diff --git a/.ncurc.yml b/.ncurc.yml index d675bc11b2..3ac07e871d 100644 --- a/.ncurc.yml +++ b/.ncurc.yml @@ -4,3 +4,5 @@ reject: - delay # Now ESM and depends on top-level await. - tempfile + # Version 7 had breaking changes not worth the effort. + - conventional-changelog diff --git a/bower.json b/bower.json index 1760d1517b..a0d5ba007e 100644 --- a/bower.json +++ b/bower.json @@ -12,29 +12,22 @@ }, "license": "MIT", "dependencies": { - "ace": "ajaxorg/ace-builds#v1.4.6", - "async": "2.1.4", - "babel-standalone": "6.19.0", - "bowser": "1.0.0", + "ace": "ajaxorg/ace-builds#v1.43.2", "chroma-js": "1.1.1", "ckeditor": "4.7.3", "colors": "3.0.0", "d3": "3.5.17", "d3-plugins": "cheminfo/d3-plugins#ea652308c616f3accde0a418f7ccc6254a932985", "eventEmitter": "^5.2.3", - "fancytree": "2.20.0", + "fancytree": "2.38.5", "farbtastic": "2.0.0-alpha.1", - "fetch": "2.0.1", "file-saver.js": "cheminfo-js/file-saver.js#6a90cb37e56fbb110f03c70c90ebceb9312650db", "flag-icon-css": "2.8.0", "jit": "2.0.2", "jqgrid_edit": "git://github.com/NPellet/jqGrid#4.5.6", - "jquery": "2.2.4", - "jquery-cookie": "1.4.1", - "jquery-mousewheel": "3.1.13", + "jquery-mousewheel": "3.2.2", "jquery-qrcode": "cheminfo/jquery-qrcode#efece6cf4e32d1151436a146a2ac0e2197e0837b", "jquery-tmpl": "BorisMoore/jquery-tmpl#vBeta1.0.0", - "jquery-ui": "1.12.1", "jquery.panzoom": "cheminfo/jquery.panzoom#626f65a0180211aafc9b5d57696ac56350be6bf1", "jquery.threedubmedia": "git://github.com/threedubmedia/jquery.threedubmedia", "jsbarcode": "3.5.7", @@ -42,7 +35,6 @@ "jsme": "bcdc8f0d475eb72c2d75d20afae0b7ca4ebde273", "jsmol": "v1.2.0", "json-chart": "1.1.0", - "jsoneditor": "5.5.11", "jszip": "3.1.3", "leaflet": "1.0.2", "leaflet-omnivore": "0.3.2", @@ -50,23 +42,22 @@ "loglevel": "1.4.1", "marked": "0.3.6", "ml": "0.2.1", - "modernizr": "2.8.3", "moment": "2.17.1", "moment-duration-format": "~1.3.0", "nmr-simulation": "0.2.1", "notifyjs": "0.4.2", "numeral": "2.0.6", - "onde": "cheminfo/onde#126c1571a3b212abbefb5351ad9b192cef35e7a1", + "onde": "cheminfo/onde#9ed3407d02ca323b8dce8d2456eb54b49a804344", "papa-parse": "4.1.2", "pouchdb": "3.3.1", "requirejs": "2.3.6", "select2": "4.0.3", "setImmediate": "YuzuJS/setImmediate#1.0.5", "slickgrid": "cheminfo/SlickGrid#6423d3d4c9e09180ad83a9166d149e3e4124320d", - "spectrum": "1.8.0", - "sprintf": "1.0.3", + "spectrum": "101b05c1d977fbc529ae4c3b6865b1f7ab70c6e0", + "sprintf": "1.1.3", "threejs": "r71", - "ui-contextmenu": "1.14.0", + "ui-contextmenu": "1.18.1", "uri.js": "1.18.4", "web-animations-js": "2.2.2", "x2js": "1.2.0", @@ -75,7 +66,6 @@ }, "resolutions": { "jsgraph": "2.2.36", - "jquery": "2.2.4", "eventEmitter": "^5.1.0" }, "private": true diff --git a/gruntfile.js b/gruntfile.js index 5274dac127..d2027cdb90 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -192,7 +192,7 @@ module.exports = function (grunt) { src: [ './d3/d3*', [ - './fancytree/dist/jquery.fancytree*.js', + './fancytree/dist/modules/jquery.fancytree*.js', './fancytree/dist/skin-lion/*', ], [ @@ -200,13 +200,6 @@ module.exports = function (grunt) { './jqgrid_edit/js/i18n/grid.locale-en.js', './jqgrid_edit/css/*.css', ], - './jquery/dist/*', - [ - './jquery-ui/ui/*.js', - './jquery-ui/ui/effects/*.js', - './jquery-ui/ui/widgets/*.js', - './jquery-ui/themes/base/**', - ], './threejs/build/three.min.js', './ace/src/**', [ @@ -228,7 +221,6 @@ module.exports = function (grunt) { './leaflet/dist/**', './leaflet-omnivore/leaflet-omnivore.min.js', ], - './jsoneditor/dist/**', './jit/Jit/**/*', './ui-contextmenu/jquery.ui-contextmenu*', './papa-parse/papaparse*', @@ -238,10 +230,7 @@ module.exports = function (grunt) { './onde/src/*', ['./spectrum/spectrum.js', './spectrum/spectrum.css'], './superagent/superagent.js', - './modernizr/modernizr.js', './lodash/dist/**', - './bowser/bowser*', - './jquery-cookie/jquery.cookie.js', './chemcalc/lib.js', './jsgraph/dist/**', './jsme/**', @@ -253,7 +242,6 @@ module.exports = function (grunt) { './jquery-tmpl/**', './setImmediate/setImmediate.js', './chroma-js/chroma*', - './async/dist/**', './loglevel/dist/**', './marked/lib/marked.js', './highlight.js/build/highlight.pack.js', @@ -274,11 +262,7 @@ module.exports = function (grunt) { './flag-icon-css/css/flag-icon.min.css', './flag-icon-css/flags/**', './jquery-qrcode/jquery.qrcode.min.js', - './mathjs/dist/**', './nmr-simulation/**', - './katex/dist/**', - './babel-standalone/**', - './fetch/fetch.js', './js-yaml/dist/**', './canvg/dist/**', './eventEmitter/*.js', @@ -289,10 +273,13 @@ module.exports = function (grunt) { expand: true, cwd: './node_modules', src: [ - './katex/dist/**', './angularplasmid/dist/**', - './mathjs/dist/math.min.js', - './mathjs/dist/math.min.map', + './jquery/dist/*', + ['./jquery-ui/dist/*.js', './jquery-ui/themes/base/**'], + './jsoneditor/dist/**', + './katex/dist/**', + './jquery-migrate/dist/*', + './mathjs/lib/browser/**', './openchemlib/dist/**', [ './quill/dist/*.js*', @@ -300,7 +287,6 @@ module.exports = function (grunt) { './quill-resize-module/dist/resize.*', './quill-table-better/dist/quill-table-better.*', ], - './d3-hierarchy/dist/d3-hierarchy.min.js', './@fortawesome/fontawesome-free/css/all.min.css', './@fortawesome/fontawesome-free/webfonts/*', ], diff --git a/package-lock.json b/package-lock.json index c81339cbdc..ae54ce16f6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,29 +1,32 @@ { "name": "visualizer", - "version": "2.171.1", + "version": "2.172.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "visualizer", - "version": "2.171.1", + "version": "2.172.1", "hasInstallScript": true, "license": "MIT", "dependencies": { - "@babel/preset-env": "^7.28.0", - "@fortawesome/fontawesome-free": "^6.7.2", + "@babel/preset-env": "^7.28.3", + "@fortawesome/fontawesome-free": "^7.0.0", "angularplasmid": "^1.0.5", "babel-preset-minify": "^0.5.2", "country-data": "0.0.31", - "d3-hierarchy": "^1.1.9", "delay": "^4.4.1", "eslint-plugin-import": "^2.32.0", - "katex": "^0.10.0", - "mathjs": "^5.10.3", - "mf-parser": "^1.5.0", + "jquery": "^3.7.1", + "jquery-migrate": "^3.5.2", + "jquery-ui": "^1.14.1", + "jsoneditor": "^10.3.0", + "katex": "^0.16.22", + "mathjs": "^14.6.0", + "mf-parser": "^3.6.0", "mime-types": "^2.1.35", "node-jsgraph": "2.4.15", - "openchemlib": "^9.6.0", + "openchemlib": "^9.7.0", "quill": "^2.0.3", "quill-resize-module": "^2.0.4", "quill-table-better": "^1.2.1", @@ -33,15 +36,15 @@ "twig": "^1.17.1" }, "devDependencies": { - "@babel/types": "^7.28.1", + "@babel/types": "^7.28.2", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "add-stream": "^1.0.0", "bower": "^1.8.14", "conventional-changelog": "^6.0.0", - "eslint": "^9.31.0", - "eslint-config-cheminfo": "^14.1.1", + "eslint": "^9.33.0", + "eslint-config-cheminfo": "^15.0.1", "extend": "^3.0.2", "globals": "^16.3.0", "grunt": "^1.6.1", @@ -54,7 +57,7 @@ "lodash": "^4.17.21", "mkpath": "^1.0.0", "prettier": "^3.6.2", - "rollup": "^4.45.1", + "rollup": "^4.46.3", "rollup-plugin-polyfill-node": "^0.13.0", "semver": "^5.7.2", "tempfile": "^3.0.0", @@ -140,13 +143,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", - "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz", + "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@babel/types": "^7.28.0", + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -193,17 +196,17 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", - "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz", + "integrity": "sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==", "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.27.1", "@babel/helper-optimise-call-expression": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.27.1", + "@babel/traverse": "^7.28.3", "semver": "^6.3.1" }, "engines": { @@ -440,12 +443,12 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", - "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", + "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.28.0" + "@babel/types": "^7.28.2" }, "bin": { "parser": "bin/babel-parser.js" @@ -518,13 +521,13 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", - "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -687,12 +690,12 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", - "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.28.3", "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { @@ -703,9 +706,9 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", - "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.3.tgz", + "integrity": "sha512-DoEWC5SuxuARF2KdKmGUq3ghfPMO6ZzR12Dnp5gubwbeWJo4dbNWXJPVlwvh4Zlq6Z7YVvL8VFxeSOJgjsx4Sg==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -713,7 +716,7 @@ "@babel/helper-globals": "^7.28.0", "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -1212,9 +1215,9 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.1.tgz", - "integrity": "sha512-P0QiV/taaa3kXpLY+sXla5zec4E+4t4Aqc9ggHlfZ7a2cp8/x/Gv08jfwEtn9gnnYIMvHx6aoOZ8XJL8eU71Dg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.3.tgz", + "integrity": "sha512-K3/M/a4+ESb5LEldjQb+XSrpY0nF+ZBFlTCbSnKaYAMfD8v33O6PMs4uYnOk19HlcsI8WMu3McdFPTiQHF/1/A==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1397,9 +1400,9 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.0.tgz", - "integrity": "sha512-VmaxeGOwuDqzLl5JUkIRM1X2Qu2uKGxHEQWh+cvvbl7JuJRgKGJSfsEF/bUaxFhJl/XAyxBe7q7qSuTbKFuCyg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.3.tgz", + "integrity": "sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.0", @@ -1410,7 +1413,7 @@ "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", "@babel/plugin-syntax-import-assertions": "^7.27.1", "@babel/plugin-syntax-import-attributes": "^7.27.1", @@ -1421,8 +1424,8 @@ "@babel/plugin-transform-block-scoped-functions": "^7.27.1", "@babel/plugin-transform-block-scoping": "^7.28.0", "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.27.1", - "@babel/plugin-transform-classes": "^7.28.0", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", "@babel/plugin-transform-computed-properties": "^7.27.1", "@babel/plugin-transform-destructuring": "^7.28.0", "@babel/plugin-transform-dotall-regex": "^7.27.1", @@ -1454,7 +1457,7 @@ "@babel/plugin-transform-private-methods": "^7.27.1", "@babel/plugin-transform-private-property-in-object": "^7.27.1", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.0", + "@babel/plugin-transform-regenerator": "^7.28.3", "@babel/plugin-transform-regexp-modifiers": "^7.27.1", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", @@ -1530,17 +1533,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", - "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz", + "integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.0", + "@babel/generator": "^7.28.3", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.0", + "@babel/parser": "^7.28.3", "@babel/template": "^7.27.2", - "@babel/types": "^7.28.0", + "@babel/types": "^7.28.2", "debug": "^4.3.1" }, "engines": { @@ -1548,9 +1551,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.1", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz", - "integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==", + "version": "7.28.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", + "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -1600,24 +1603,26 @@ } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.49.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.49.0.tgz", - "integrity": "sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==", + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.52.0.tgz", + "integrity": "sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==", "dev": true, "license": "MIT", "dependencies": { + "@types/estree": "^1.0.8", + "@typescript-eslint/types": "^8.34.1", "comment-parser": "1.4.1", "esquery": "^1.6.0", "jsdoc-type-pratt-parser": "~4.1.0" }, "engines": { - "node": ">=16" + "node": ">=20.11.0" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.6.1.tgz", - "integrity": "sha512-KTsJMmobmbrFLe3LDh0PC2FXpcSYJt/MLjlkh/9LEnmKYLSYmT/0EW9JWANjeoemiuZrmogti0tW5Ch+qNUYDw==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", + "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -1668,18 +1673,18 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz", - "integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz", + "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz", - "integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==", + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -1724,9 +1729,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz", - "integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.33.0.tgz", + "integrity": "sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1745,12 +1750,12 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.4.tgz", - "integrity": "sha512-Ul5l+lHEcw3L5+k8POx6r74mxEYKG5kOb6Xpy2gCRW6zweT6TEhAf8vhxGgjhqrd/VO/Dirhsb+1hNpD1ue9hw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.1", + "@eslint/core": "^0.15.2", "levn": "^0.4.1" }, "engines": { @@ -1758,9 +1763,9 @@ } }, "node_modules/@fortawesome/fontawesome-free": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.2.tgz", - "integrity": "sha512-JUOtgFW6k9u4Y+xeIaEiLr3+cjoUPiAuLXoyKOJSia6Duzb7pq+A76P9ZdPDoAoxHdHzq6gE9/jKBGXlZT8FbA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-7.0.0.tgz", + "integrity": "sha512-X48nISrSOa89zu2VMljC4XaRf8NmgTwQBVHfS2Nu5G00ZwM31oOVrAtGxZF3b6wDYf9lJsf/Eq4cCSFKIkOWPQ==", "license": "(CC-BY-4.0 AND OFL-1.1 AND MIT)", "engines": { "node": ">=6" @@ -1888,6 +1893,44 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "28.0.6", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.6.tgz", @@ -2049,9 +2092,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.1.tgz", - "integrity": "sha512-NEySIFvMY0ZQO+utJkgoMiCAjMrGvnbDLHvcmlA33UXJpYBCvlBEbMMtV837uCkS+plG2umfhn0T5mMAxGrlRA==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.3.tgz", + "integrity": "sha512-UmTdvXnLlqQNOCJnyksjPs1G4GqXNGW1LrzCe8+8QoaLhhDeTXYBgJ3k6x61WIhlHX2U+VzEJ55TtIjR/HTySA==", "cpu": [ "arm" ], @@ -2063,9 +2106,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.1.tgz", - "integrity": "sha512-ujQ+sMXJkg4LRJaYreaVx7Z/VMgBBd89wGS4qMrdtfUFZ+TSY5Rs9asgjitLwzeIbhwdEhyj29zhst3L1lKsRQ==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.3.tgz", + "integrity": "sha512-8NoxqLpXm7VyeI0ocidh335D6OKT0UJ6fHdnIxf3+6oOerZZc+O7r+UhvROji6OspyPm+rrIdb1gTXtVIqn+Sg==", "cpu": [ "arm64" ], @@ -2077,9 +2120,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.1.tgz", - "integrity": "sha512-FSncqHvqTm3lC6Y13xncsdOYfxGSLnP+73k815EfNmpewPs+EyM49haPS105Rh4aF5mJKywk9X0ogzLXZzN9lA==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.3.tgz", + "integrity": "sha512-csnNavqZVs1+7/hUKtgjMECsNG2cdB8F7XBHP6FfQjqhjF8rzMzb3SLyy/1BG7YSfQ+bG75Ph7DyedbUqwq1rA==", "cpu": [ "arm64" ], @@ -2091,9 +2134,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.1.tgz", - "integrity": "sha512-2/vVn/husP5XI7Fsf/RlhDaQJ7x9zjvC81anIVbr4b/f0xtSmXQTFcGIQ/B1cXIYM6h2nAhJkdMHTnD7OtQ9Og==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.3.tgz", + "integrity": "sha512-r2MXNjbuYabSIX5yQqnT8SGSQ26XQc8fmp6UhlYJd95PZJkQD1u82fWP7HqvGUf33IsOC6qsiV+vcuD4SDP6iw==", "cpu": [ "x64" ], @@ -2105,9 +2148,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.1.tgz", - "integrity": "sha512-4g1kaDxQItZsrkVTdYQ0bxu4ZIQ32cotoQbmsAnW1jAE4XCMbcBPDirX5fyUzdhVCKgPcrwWuucI8yrVRBw2+g==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.3.tgz", + "integrity": "sha512-uluObTmgPJDuJh9xqxyr7MV61Imq+0IvVsAlWyvxAaBSNzCcmZlhfYcRhCdMaCsy46ccZa7vtDDripgs9Jkqsw==", "cpu": [ "arm64" ], @@ -2119,9 +2162,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.1.tgz", - "integrity": "sha512-L/6JsfiL74i3uK1Ti2ZFSNsp5NMiM4/kbbGEcOCps99aZx3g8SJMO1/9Y0n/qKlWZfn6sScf98lEOUe2mBvW9A==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.3.tgz", + "integrity": "sha512-AVJXEq9RVHQnejdbFvh1eWEoobohUYN3nqJIPI4mNTMpsyYN01VvcAClxflyk2HIxvLpRcRggpX1m9hkXkpC/A==", "cpu": [ "x64" ], @@ -2133,9 +2176,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.1.tgz", - "integrity": "sha512-RkdOTu2jK7brlu+ZwjMIZfdV2sSYHK2qR08FUWcIoqJC2eywHbXr0L8T/pONFwkGukQqERDheaGTeedG+rra6Q==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.3.tgz", + "integrity": "sha512-byyflM+huiwHlKi7VHLAYTKr67X199+V+mt1iRgJenAI594vcmGGddWlu6eHujmcdl6TqSNnvqaXJqZdnEWRGA==", "cpu": [ "arm" ], @@ -2147,9 +2190,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.1.tgz", - "integrity": "sha512-3kJ8pgfBt6CIIr1o+HQA7OZ9mp/zDk3ctekGl9qn/pRBgrRgfwiffaUmqioUGN9hv0OHv2gxmvdKOkARCtRb8Q==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.3.tgz", + "integrity": "sha512-aLm3NMIjr4Y9LklrH5cu7yybBqoVCdr4Nvnm8WB7PKCn34fMCGypVNpGK0JQWdPAzR/FnoEoFtlRqZbBBLhVoQ==", "cpu": [ "arm" ], @@ -2161,9 +2204,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.1.tgz", - "integrity": "sha512-k3dOKCfIVixWjG7OXTCOmDfJj3vbdhN0QYEqB+OuGArOChek22hn7Uy5A/gTDNAcCy5v2YcXRJ/Qcnm4/ma1xw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.3.tgz", + "integrity": "sha512-VtilE6eznJRDIoFOzaagQodUksTEfLIsvXymS+UdJiSXrPW7Ai+WG4uapAc3F7Hgs791TwdGh4xyOzbuzIZrnw==", "cpu": [ "arm64" ], @@ -2175,9 +2218,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.1.tgz", - "integrity": "sha512-PmI1vxQetnM58ZmDFl9/Uk2lpBBby6B6rF4muJc65uZbxCs0EA7hhKCk2PKlmZKuyVSHAyIw3+/SiuMLxKxWog==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.3.tgz", + "integrity": "sha512-dG3JuS6+cRAL0GQ925Vppafi0qwZnkHdPeuZIxIPXqkCLP02l7ka+OCyBoDEv8S+nKHxfjvjW4OZ7hTdHkx8/w==", "cpu": [ "arm64" ], @@ -2189,9 +2232,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.1.tgz", - "integrity": "sha512-9UmI0VzGmNJ28ibHW2GpE2nF0PBQqsyiS4kcJ5vK+wuwGnV5RlqdczVocDSUfGX/Na7/XINRVoUgJyFIgipoRg==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.3.tgz", + "integrity": "sha512-iU8DxnxEKJptf8Vcx4XvAUdpkZfaz0KWfRrnIRrOndL0SvzEte+MTM7nDH4A2Now4FvTZ01yFAgj6TX/mZl8hQ==", "cpu": [ "loong64" ], @@ -2202,10 +2245,10 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.1.tgz", - "integrity": "sha512-7nR2KY8oEOUTD3pBAxIBBbZr0U7U+R9HDTPNy+5nVVHDXI4ikYniH1oxQz9VoB5PbBU1CZuDGHkLJkd3zLMWsg==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.3.tgz", + "integrity": "sha512-VrQZp9tkk0yozJoQvQcqlWiqaPnLM6uY1qPYXvukKePb0fqaiQtOdMJSxNFUZFsGw5oA5vvVokjHrx8a9Qsz2A==", "cpu": [ "ppc64" ], @@ -2217,9 +2260,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.1.tgz", - "integrity": "sha512-nlcl3jgUultKROfZijKjRQLUu9Ma0PeNv/VFHkZiKbXTBQXhpytS8CIj5/NfBeECZtY2FJQubm6ltIxm/ftxpw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.3.tgz", + "integrity": "sha512-uf2eucWSUb+M7b0poZ/08LsbcRgaDYL8NCGjUeFMwCWFwOuFcZ8D9ayPl25P3pl+D2FH45EbHdfyUesQ2Lt9wA==", "cpu": [ "riscv64" ], @@ -2231,9 +2274,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.1.tgz", - "integrity": "sha512-HJV65KLS51rW0VY6rvZkiieiBnurSzpzore1bMKAhunQiECPuxsROvyeaot/tcK3A3aGnI+qTHqisrpSgQrpgA==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.3.tgz", + "integrity": "sha512-7tnUcDvN8DHm/9ra+/nF7lLzYHDeODKKKrh6JmZejbh1FnCNZS8zMkZY5J4sEipy2OW1d1Ncc4gNHUd0DLqkSg==", "cpu": [ "riscv64" ], @@ -2245,9 +2288,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.1.tgz", - "integrity": "sha512-NITBOCv3Qqc6hhwFt7jLV78VEO/il4YcBzoMGGNxznLgRQf43VQDae0aAzKiBeEPIxnDrACiMgbqjuihx08OOw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.3.tgz", + "integrity": "sha512-MUpAOallJim8CsJK+4Lc9tQzlfPbHxWDrGXZm2z6biaadNpvh3a5ewcdat478W+tXDoUiHwErX/dOql7ETcLqg==", "cpu": [ "s390x" ], @@ -2259,9 +2302,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.1.tgz", - "integrity": "sha512-+E/lYl6qu1zqgPEnTrs4WysQtvc/Sh4fC2nByfFExqgYrqkKWp1tWIbe+ELhixnenSpBbLXNi6vbEEJ8M7fiHw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.3.tgz", + "integrity": "sha512-F42IgZI4JicE2vM2PWCe0N5mR5vR0gIdORPqhGQ32/u1S1v3kLtbZ0C/mi9FFk7C5T0PgdeyWEPajPjaUpyoKg==", "cpu": [ "x64" ], @@ -2273,9 +2316,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.1.tgz", - "integrity": "sha512-a6WIAp89p3kpNoYStITT9RbTbTnqarU7D8N8F2CV+4Cl9fwCOZraLVuVFvlpsW0SbIiYtEnhCZBPLoNdRkjQFw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.3.tgz", + "integrity": "sha512-oLc+JrwwvbimJUInzx56Q3ujL3Kkhxehg7O1gWAYzm8hImCd5ld1F2Gry5YDjR21MNb5WCKhC9hXgU7rRlyegQ==", "cpu": [ "x64" ], @@ -2287,9 +2330,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.1.tgz", - "integrity": "sha512-T5Bi/NS3fQiJeYdGvRpTAP5P02kqSOpqiopwhj0uaXB6nzs5JVi2XMJb18JUSKhCOX8+UE1UKQufyD6Or48dJg==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.3.tgz", + "integrity": "sha512-lOrQ+BVRstruD1fkWg9yjmumhowR0oLAAzavB7yFSaGltY8klttmZtCLvOXCmGE9mLIn8IBV/IFrQOWz5xbFPg==", "cpu": [ "arm64" ], @@ -2301,9 +2344,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.1.tgz", - "integrity": "sha512-lxV2Pako3ujjuUe9jiU3/s7KSrDfH6IgTSQOnDWr9aJ92YsFd7EurmClK0ly/t8dzMkDtd04g60WX6yl0sGfdw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.3.tgz", + "integrity": "sha512-vvrVKPRS4GduGR7VMH8EylCBqsDcw6U+/0nPDuIjXQRbHJc6xOBj+frx8ksfZAh6+Fptw5wHrN7etlMmQnPQVg==", "cpu": [ "ia32" ], @@ -2315,9 +2358,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.1.tgz", - "integrity": "sha512-M/fKi4sasCdM8i0aWJjCSFm2qEnYRR8AMLG2kxp6wD13+tMGA4Z1tVAuHkNRjud5SW2EM3naLuK35w9twvf6aA==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.3.tgz", + "integrity": "sha512-fi3cPxCnu3ZeM3EwKZPgXbWoGzm2XHgB/WShKI81uj8wG0+laobmqy5wbgEwzstlbLu4MyO8C19FyhhWseYKNQ==", "cpu": [ "x64" ], @@ -2334,6 +2377,12 @@ "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "license": "MIT" }, + "node_modules/@sphinxxxx/color-conversion": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", + "integrity": "sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==", + "license": "ISC" + }, "node_modules/@types/estree": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", @@ -2388,6 +2437,210 @@ "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.39.1.tgz", + "integrity": "sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.39.1", + "@typescript-eslint/types": "^8.39.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.39.1.tgz", + "integrity": "sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.39.1", + "@typescript-eslint/visitor-keys": "8.39.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.39.1.tgz", + "integrity": "sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.39.1.tgz", + "integrity": "sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.39.1.tgz", + "integrity": "sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.39.1", + "@typescript-eslint/tsconfig-utils": "8.39.1", + "@typescript-eslint/types": "8.39.1", + "@typescript-eslint/visitor-keys": "8.39.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.39.1.tgz", + "integrity": "sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.39.1", + "@typescript-eslint/types": "8.39.1", + "@typescript-eslint/typescript-estree": "8.39.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.39.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.39.1.tgz", + "integrity": "sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.39.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@vitest/eslint-plugin": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.3.4.tgz", + "integrity": "sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.24.1" + }, + "peerDependencies": { + "eslint": ">= 8.57.0", + "typescript": ">= 5.0.0", + "vitest": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vitest": { + "optional": true + } + } + }, "node_modules/abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -2395,6 +2648,12 @@ "dev": true, "license": "ISC" }, + "node_modules/ace-builds": { + "version": "1.43.2", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.43.2.tgz", + "integrity": "sha512-3wzJUJX0RpMc03jo0V8Q3bSb/cKPnS7Nqqw8fVHsCCHweKMiTIxT3fP46EhjmVy6MCuxwP801ere+RW245phGw==", + "license": "BSD-3-Clause" + }, "node_modules/acorn": { "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", @@ -2645,9 +2904,9 @@ "license": "MIT" }, "node_modules/atom-sorter": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/atom-sorter/-/atom-sorter-1.2.0.tgz", - "integrity": "sha512-WaEaDUy0UCnOEWSCa7dm2Ij41CiZEXveRUrv4H0PIJ42v2etWih7kwiGqzsEerm8Lp6zc7VOVUm/x4qIReBGbw==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/atom-sorter/-/atom-sorter-2.2.1.tgz", + "integrity": "sha512-+Lyyb6iXLHEb/ZYkpuvdEUgZ62+oA96p3rJG5lsttwl9vig1UqD8sAUnGQjrDFcVNUywFBhiW57Nns65M7TXEA==", "license": "MIT" }, "node_modules/available-typed-arrays": { @@ -3152,19 +3411,23 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, "node_modules/chemical-elements": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/chemical-elements/-/chemical-elements-1.3.0.tgz", - "integrity": "sha512-364wypF24rEbKviTfW5T+pCUK5zOQAY7CYfB1XWDI+eiS44oifdkR7i2RldDL8dDIV9BBQs3tLyv6Btu6hvBCg==", - "license": "MIT", - "dependencies": { - "papaparse": "^5.3.2" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/chemical-elements/-/chemical-elements-2.2.1.tgz", + "integrity": "sha512-Khr3m8RhBbNwDb2MSo9Zb9O+dcUuFourUC0hK+YxNhAtEhOwJPVTMDQeDi1vUwH44tUeNRNKriUs2QQFNQvxgg==", + "license": "MIT" }, "node_modules/chemical-groups": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/chemical-groups/-/chemical-groups-1.3.0.tgz", - "integrity": "sha512-iptPGur5faUv+zvP05VHZ9ATMteSjjiQgefjX30pM1LlKM8jIFCyUYg79XSTJiFj4bHR+hF7R3UsNDPRpd43qA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/chemical-groups/-/chemical-groups-2.2.3.tgz", + "integrity": "sha512-rIhA7dC2OJNbQeEFM6+3u81hItYWkaYbWh7awn3hy9RI1qCvhQgdTkrvt7zlLCmcp2nuMzJZUXSju6etBsf6lA==", "license": "MIT" }, "node_modules/ci-info": { @@ -3261,10 +3524,13 @@ } }, "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } }, "node_modules/comment-parser": { "version": "1.4.1", @@ -3295,12 +3561,16 @@ } }, "node_modules/complex.js": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.11.tgz", - "integrity": "sha512-6IArJLApNtdg1P1dFtn3dnyzoZBEF0MwMnrfF1exSBRpZYoy4yieMkpZhQDC0uwctw48vii0CFVyHfpgZ/DfGw==", - "license": "MIT OR GPL-2.0", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.4.2.tgz", + "integrity": "sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==", + "license": "MIT", "engines": { "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" } }, "node_modules/component-emitter": { @@ -3592,12 +3862,6 @@ "integrity": "sha512-fPZJ3jqM68+AAgqQ7UaGbgHL/39rp6l7GyqS2k1HJPu/kpS8D07x/+Uup6a9tCUKIlOFcRrDCf1qxSt8jnI5BA==", "license": "BSD-2-Clause" }, - "node_modules/d3-hierarchy": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", - "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==", - "license": "BSD-3-Clause" - }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -3677,9 +3941,9 @@ } }, "node_modules/decimal.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", - "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "license": "MIT" }, "node_modules/deep-is": { @@ -4079,19 +4343,19 @@ } }, "node_modules/eslint": { - "version": "9.31.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz", - "integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==", + "version": "9.33.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.33.0.tgz", + "integrity": "sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.0", - "@eslint/config-helpers": "^0.3.0", - "@eslint/core": "^0.15.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.31.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/js": "9.33.0", + "@eslint/plugin-kit": "^0.3.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", @@ -4139,19 +4403,20 @@ } }, "node_modules/eslint-config-cheminfo": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-cheminfo/-/eslint-config-cheminfo-14.1.1.tgz", - "integrity": "sha512-y0I6J5P+h+sU8ZycY0kH1qNHUcu18Rf97BwQBj33j5H28mu+ritgEBX15Gr+CPbQFSb23dgd7nWc+jfdhU9QLw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-cheminfo/-/eslint-config-cheminfo-15.0.1.tgz", + "integrity": "sha512-Bl4LizcVW2ybURIHz4fROj/rcyVQnsJreaUBH6aD8RvpoZxbL8wuDMp/DcwaaYR10RTt/MV8TPYkncRbTpa1Mg==", "dev": true, "license": "MIT", "dependencies": { - "eslint-plugin-import": "^2.31.0", - "eslint-plugin-jsdoc": "^50.6.11", - "eslint-plugin-unicorn": "^59.0.1", - "globals": "^16.1.0" + "@vitest/eslint-plugin": "^1.3.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsdoc": "^51.4.1", + "eslint-plugin-unicorn": "^60.0.0", + "globals": "^16.3.0" }, "peerDependencies": { - "eslint": "^9.22.0" + "eslint": "^9.30.1" } }, "node_modules/eslint-import-resolver-node": { @@ -4252,34 +4517,34 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "50.6.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-50.6.11.tgz", - "integrity": "sha512-k4+MnBCGR8cuIB5MZ++FGd4gbXxjob2rX1Nq0q3nWFF4xSGZENTgTLZSjb+u9B8SAnP6lpGV2FJrBjllV3pVSg==", + "version": "51.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-51.4.1.tgz", + "integrity": "sha512-y4CA9OkachG8v5nAtrwvcvjIbdcKgSyS6U//IfQr4FZFFyeBFwZFf/tfSsMr46mWDJgidZjBTqoCRlXywfFBMg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@es-joy/jsdoccomment": "~0.49.0", + "@es-joy/jsdoccomment": "~0.52.0", "are-docs-informative": "^0.0.2", "comment-parser": "1.4.1", - "debug": "^4.3.6", + "debug": "^4.4.1", "escape-string-regexp": "^4.0.0", - "espree": "^10.1.0", + "espree": "^10.4.0", "esquery": "^1.6.0", "parse-imports-exports": "^0.2.4", - "semver": "^7.6.3", + "semver": "^7.7.2", "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": ">=18" + "node": ">=20.11.0" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -4290,65 +4555,39 @@ } }, "node_modules/eslint-plugin-unicorn": { - "version": "59.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-59.0.1.tgz", - "integrity": "sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==", + "version": "60.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-60.0.0.tgz", + "integrity": "sha512-QUzTefvP8stfSXsqKQ+vBQSEsXIlAiCduS/V1Em+FKgL9c21U/IIm20/e3MFy1jyCf14tHAhqC1sX8OTy6VUCg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "@eslint-community/eslint-utils": "^4.5.1", - "@eslint/plugin-kit": "^0.2.7", - "ci-info": "^4.2.0", + "@babel/helper-validator-identifier": "^7.27.1", + "@eslint-community/eslint-utils": "^4.7.0", + "@eslint/plugin-kit": "^0.3.3", + "change-case": "^5.4.4", + "ci-info": "^4.3.0", "clean-regexp": "^1.0.0", - "core-js-compat": "^3.41.0", + "core-js-compat": "^3.44.0", "esquery": "^1.6.0", "find-up-simple": "^1.0.1", - "globals": "^16.0.0", + "globals": "^16.3.0", "indent-string": "^5.0.0", "is-builtin-module": "^5.0.0", "jsesc": "^3.1.0", "pluralize": "^8.0.0", "regexp-tree": "^0.1.27", "regjsparser": "^0.12.0", - "semver": "^7.7.1", + "semver": "^7.7.2", "strip-indent": "^4.0.0" }, "engines": { - "node": "^18.20.0 || ^20.10.0 || >=21.0.0" + "node": "^20.10.0 || >=21.0.0" }, "funding": { "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=9.22.0" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/@eslint/core": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.13.0.tgz", - "integrity": "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/eslint-plugin-unicorn/node_modules/@eslint/plugin-kit": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz", - "integrity": "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.13.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "eslint": ">=9.29.0" } }, "node_modules/eslint-plugin-unicorn/node_modules/semver": { @@ -4525,6 +4764,36 @@ "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", "license": "Apache-2.0" }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -4537,6 +4806,16 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -4741,12 +5020,16 @@ } }, "node_modules/fraction.js": { - "version": "4.0.12", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.12.tgz", - "integrity": "sha512-8Z1K0VTG4hzYY7kA/1sj4/r1/RWLBD3xwReT/RCrUCbzPszjNQCCsy3ktkU/eaEqX3MYa4pY37a52eiBlPMlhA==", - "license": "MIT OR GPL-2.0", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.1.tgz", + "integrity": "sha512-PhqCuhSKIGbbkJ+cojHv47eEWClU71FIOhiUsYdZYTwhIzCeIN8rXeEjserTvPat5JLJChumn8chHz64WkZgTw==", + "license": "MIT", "engines": { "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" } }, "node_modules/fs.realpath": { @@ -6195,6 +6478,39 @@ "integrity": "sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==", "license": "MIT" }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/jquery": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", + "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", + "license": "MIT" + }, + "node_modules/jquery-migrate": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-3.5.2.tgz", + "integrity": "sha512-GGvcVWK3aei2/98r7pA4UkOYvs4xVeCGvquNXADFUp9+Sr6VeOw0ktlQ9z4YlBbEFpsXBlRioAgpH/fLWinj4Q==", + "license": "MIT", + "peerDependencies": { + "jquery": ">=3 <4" + } + }, + "node_modules/jquery-ui": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.14.1.tgz", + "integrity": "sha512-DhzsYH8VeIvOaxwi+B/2BCsFFT5EGjShdzOcm5DssWjtcpGWIMsn66rJciDA6jBruzNiLf1q0KvwMoX1uGNvnQ==", + "license": "MIT", + "dependencies": { + "jquery": ">=1.12.0 <5.0.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6247,6 +6563,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "license": "MIT" }, + "node_modules/json-source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/json-source-map/-/json-source-map-0.6.1.tgz", + "integrity": "sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==", + "license": "MIT" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -6266,13 +6588,42 @@ "node": ">=6" } }, + "node_modules/jsoneditor": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/jsoneditor/-/jsoneditor-10.3.0.tgz", + "integrity": "sha512-KYuX34Tgze1SU3rIrwF0Y3fewrTYq1dSLHT2FXLPIUhFObmtSD+NML2hqXX7rtwGs2dfLUwsK8gn3WbhFT5CtQ==", + "license": "Apache-2.0", + "dependencies": { + "ace-builds": "^1.36.2", + "ajv": "^6.12.6", + "javascript-natural-sort": "^0.7.1", + "jmespath": "^0.16.0", + "json-source-map": "^0.6.1", + "jsonrepair": "^3.8.1", + "picomodal": "^3.0.0", + "vanilla-picker": "^2.12.3" + } + }, + "node_modules/jsonrepair": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/jsonrepair/-/jsonrepair-3.13.0.tgz", + "integrity": "sha512-5YRzlAQ7tuzV1nAJu3LvDlrKtBFIALHN2+a+I1MGJCt3ldRDBF/bZuvIPzae8Epot6KBXd0awRZZcuoeAsZ/mw==", + "license": "ISC", + "bin": { + "jsonrepair": "bin/cli.js" + } + }, "node_modules/katex": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.10.2.tgz", - "integrity": "sha512-cQOmyIRoMloCoSIOZ1+gEwsksdJZ1EW4SWm3QzxSza/QsnZr6D4U1V9S4q+B/OLm2OQ8TCBecQ8MaIfnScI7cw==", + "version": "0.16.22", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.22.tgz", + "integrity": "sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], "license": "MIT", "dependencies": { - "commander": "^2.19.0" + "commander": "^8.3.0" }, "bin": { "katex": "cli.js" @@ -6465,25 +6816,26 @@ } }, "node_modules/mathjs": { - "version": "5.10.3", - "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-5.10.3.tgz", - "integrity": "sha512-ySjg30BC3dYjQm73ILZtwcWzFJde0VU6otkXW/57IjjuYRa3Qaf0Kb8pydEuBZYtqW2OxreAtsricrAmOj3jIw==", + "version": "14.6.0", + "resolved": "https://registry.npmjs.org/mathjs/-/mathjs-14.6.0.tgz", + "integrity": "sha512-5vI2BLB5GKQmiSK9BH6hVkZ+GgqpdnOgEfmHl7mqVmdQObLynr63KueyYYLCQMzj66q69mV2XZZGQqqxeftQbA==", "license": "Apache-2.0", "dependencies": { - "complex.js": "2.0.11", - "decimal.js": "10.2.0", - "escape-latex": "1.2.0", - "fraction.js": "4.0.12", - "javascript-natural-sort": "0.7.1", - "seed-random": "2.2.0", - "tiny-emitter": "2.1.0", - "typed-function": "1.1.0" + "@babel/runtime": "^7.26.10", + "complex.js": "^2.2.5", + "decimal.js": "^10.4.3", + "escape-latex": "^1.2.0", + "fraction.js": "^5.2.1", + "javascript-natural-sort": "^0.7.1", + "seedrandom": "^3.0.5", + "tiny-emitter": "^2.1.0", + "typed-function": "^4.2.1" }, "bin": { "mathjs": "bin/cli.js" }, "engines": { - "node": ">= 6" + "node": ">= 18" } }, "node_modules/meow": { @@ -6499,6 +6851,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -6509,14 +6871,14 @@ } }, "node_modules/mf-parser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mf-parser/-/mf-parser-1.5.0.tgz", - "integrity": "sha512-GErJnRZX8Bkd7Jqx1Ua8jFS0LYgAb9MQvQGvsRAva2jh1RBzWoN+jvPX7NpAQhyfxzV/KG1Zn9R7ZlvMxx91mg==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/mf-parser/-/mf-parser-3.6.0.tgz", + "integrity": "sha512-vBE7hE8ZB2rtMPxJZHgfuMQIF98ebqXUDTtG/EzapRJ/CDurI/bEo8ZEyQI+ZKznGXr6HGcnBdoE2+U52v/JtA==", "license": "MIT", "dependencies": { - "atom-sorter": "^1.2.0", - "chemical-elements": "^1.3.0", - "chemical-groups": "^1.3.0" + "atom-sorter": "^2.2.1", + "chemical-elements": "^2.2.1", + "chemical-groups": "^2.2.3" } }, "node_modules/micromatch": { @@ -6834,9 +7196,9 @@ } }, "node_modules/openchemlib": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/openchemlib/-/openchemlib-9.6.0.tgz", - "integrity": "sha512-SAMLSwOQTCDNpfNu/WTQpzLMYTRj/xwetMPRoAGHeR2J162RP/OI6vHpVcC7L4V7ThMW3ZhMf7GdH04yndmHtw==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/openchemlib/-/openchemlib-9.7.0.tgz", + "integrity": "sha512-IMO5O+151rrfakuTkEpCsZvMXFqfCGWrXarlEBukiAqDYhxqSG0LtyzZdtTn0ETSY8Nz+oTLGs1iJ2tRRUK7lA==", "license": "BSD-3-Clause" }, "node_modules/optionator": { @@ -6935,12 +7297,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/papaparse": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.5.2.tgz", - "integrity": "sha512-PZXg8UuAc4PcVwLosEEDYjPyfWnTEhOrUfdv+3Bx+NuAb+5NhDmXzg5fHWmdCh1mP5p7JAZfFr3IMQfcntNAdA==", - "license": "MIT" - }, "node_modules/parchment": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/parchment/-/parchment-3.0.0.tgz", @@ -7084,6 +7440,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/picomodal": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/picomodal/-/picomodal-3.0.0.tgz", + "integrity": "sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==", + "license": "MIT" + }, "node_modules/pluralize": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", @@ -7194,6 +7556,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/quill": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/quill/-/quill-2.0.3.tgz", @@ -7524,6 +7907,17 @@ "node": ">=4" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -7539,9 +7933,9 @@ } }, "node_modules/rollup": { - "version": "4.45.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.1.tgz", - "integrity": "sha512-4iya7Jb76fVpQyLoiVpzUrsjQ12r3dM7fIVz+4NwoYvZOShknRmiv+iu9CClZml5ZLGb0XMcYLutK6w9tgxHDw==", + "version": "4.46.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.3.tgz", + "integrity": "sha512-RZn2XTjXb8t5g13f5YclGoilU/kwT696DIkY3sywjdZidNSi3+vseaQov7D7BZXVJCPv3pDWUN69C78GGbXsKw==", "dev": true, "license": "MIT", "dependencies": { @@ -7555,26 +7949,26 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.45.1", - "@rollup/rollup-android-arm64": "4.45.1", - "@rollup/rollup-darwin-arm64": "4.45.1", - "@rollup/rollup-darwin-x64": "4.45.1", - "@rollup/rollup-freebsd-arm64": "4.45.1", - "@rollup/rollup-freebsd-x64": "4.45.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.45.1", - "@rollup/rollup-linux-arm-musleabihf": "4.45.1", - "@rollup/rollup-linux-arm64-gnu": "4.45.1", - "@rollup/rollup-linux-arm64-musl": "4.45.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.45.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-gnu": "4.45.1", - "@rollup/rollup-linux-riscv64-musl": "4.45.1", - "@rollup/rollup-linux-s390x-gnu": "4.45.1", - "@rollup/rollup-linux-x64-gnu": "4.45.1", - "@rollup/rollup-linux-x64-musl": "4.45.1", - "@rollup/rollup-win32-arm64-msvc": "4.45.1", - "@rollup/rollup-win32-ia32-msvc": "4.45.1", - "@rollup/rollup-win32-x64-msvc": "4.45.1", + "@rollup/rollup-android-arm-eabi": "4.46.3", + "@rollup/rollup-android-arm64": "4.46.3", + "@rollup/rollup-darwin-arm64": "4.46.3", + "@rollup/rollup-darwin-x64": "4.46.3", + "@rollup/rollup-freebsd-arm64": "4.46.3", + "@rollup/rollup-freebsd-x64": "4.46.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.46.3", + "@rollup/rollup-linux-arm-musleabihf": "4.46.3", + "@rollup/rollup-linux-arm64-gnu": "4.46.3", + "@rollup/rollup-linux-arm64-musl": "4.46.3", + "@rollup/rollup-linux-loongarch64-gnu": "4.46.3", + "@rollup/rollup-linux-ppc64-gnu": "4.46.3", + "@rollup/rollup-linux-riscv64-gnu": "4.46.3", + "@rollup/rollup-linux-riscv64-musl": "4.46.3", + "@rollup/rollup-linux-s390x-gnu": "4.46.3", + "@rollup/rollup-linux-x64-gnu": "4.46.3", + "@rollup/rollup-linux-x64-musl": "4.46.3", + "@rollup/rollup-win32-arm64-msvc": "4.46.3", + "@rollup/rollup-win32-ia32-msvc": "4.46.3", + "@rollup/rollup-win32-x64-msvc": "4.46.3", "fsevents": "~2.3.2" } }, @@ -7591,6 +7985,30 @@ "rollup": "^1.20.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/rxn-parser": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/rxn-parser/-/rxn-parser-0.1.2.tgz", @@ -7710,10 +8128,10 @@ "postcss": "^7.0.27" } }, - "node_modules/seed-random": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", - "integrity": "sha512-34EQV6AAHQGhoc0tn/96a9Fsi6v2xdqe/dMUwljGRaFOzR3EgRmECvD0O8vi8X+/uQ50LGHfkNu/Eue5TPKZkQ==", + "node_modules/seedrandom": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz", + "integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==", "license": "MIT" }, "node_modules/semver": { @@ -8167,6 +8585,19 @@ "node": ">=8.0" } }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/tsconfig-paths": { "version": "3.15.0", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", @@ -8321,11 +8752,27 @@ } }, "node_modules/typed-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-1.1.0.tgz", - "integrity": "sha512-TuQzwiT4DDg19beHam3E66oRXhyqlyfgjHB/5fcvsRXbfmWPJfto9B4a0TBdTrQAPGlGmXh/k7iUI+WsObgORA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/typed-function/-/typed-function-4.2.1.tgz", + "integrity": "sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==", + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">= 18" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", + "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, "node_modules/uglify-js": { @@ -8540,6 +8987,15 @@ "spdx-license-ids": "^3.0.0" } }, + "node_modules/vanilla-picker": { + "version": "2.12.3", + "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz", + "integrity": "sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==", + "license": "ISC", + "dependencies": { + "@sphinxxxx/color-conversion": "^2.2.2" + } + }, "node_modules/walk": { "version": "2.3.15", "resolved": "https://registry.npmjs.org/walk/-/walk-2.3.15.tgz", diff --git a/package.json b/package.json index 2ad88d9062..86f9bef580 100644 --- a/package.json +++ b/package.json @@ -40,15 +40,15 @@ "url": "https://github.com/NPellet/visualizer.git" }, "devDependencies": { - "@babel/types": "^7.28.1", + "@babel/types": "^7.28.2", "@rollup/plugin-commonjs": "^28.0.6", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^16.0.1", "add-stream": "^1.0.0", "bower": "^1.8.14", "conventional-changelog": "^6.0.0", - "eslint": "^9.31.0", - "eslint-config-cheminfo": "^14.1.1", + "eslint": "^9.33.0", + "eslint-config-cheminfo": "^15.0.1", "extend": "^3.0.2", "globals": "^16.3.0", "grunt": "^1.6.1", @@ -61,7 +61,7 @@ "lodash": "^4.17.21", "mkpath": "^1.0.0", "prettier": "^3.6.2", - "rollup": "^4.45.1", + "rollup": "^4.46.3", "rollup-plugin-polyfill-node": "^0.13.0", "semver": "^5.7.2", "tempfile": "^3.0.0", @@ -69,20 +69,23 @@ }, "private": true, "dependencies": { - "@babel/preset-env": "^7.28.0", - "@fortawesome/fontawesome-free": "^6.7.2", + "@babel/preset-env": "^7.28.3", + "@fortawesome/fontawesome-free": "^7.0.0", "angularplasmid": "^1.0.5", "babel-preset-minify": "^0.5.2", "country-data": "0.0.31", - "d3-hierarchy": "^1.1.9", "delay": "^4.4.1", "eslint-plugin-import": "^2.32.0", - "katex": "^0.10.0", - "mathjs": "^5.10.3", - "mf-parser": "^1.5.0", + "jquery": "^3.7.1", + "jquery-migrate": "^3.5.2", + "jquery-ui": "^1.14.1", + "jsoneditor": "^10.3.0", + "katex": "^0.16.22", + "mathjs": "^14.6.0", + "mf-parser": "^3.6.0", "mime-types": "^2.1.35", "node-jsgraph": "2.4.15", - "openchemlib": "^9.6.0", + "openchemlib": "^9.7.0", "quill": "^2.0.3", "quill-resize-module": "^2.0.4", "quill-table-better": "^1.2.1", @@ -92,6 +95,6 @@ "twig": "^1.17.1" }, "volta": { - "node": "20.19.1" + "node": "20.19.4" } } diff --git a/rollup.config.mjs b/rollup.config.mjs index 8f175a6641..84bf4de86c 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -25,7 +25,7 @@ export default [ plugins, }, { - input: 'node_modules/mf-parser/src/index.js', + input: 'node_modules/mf-parser/lib/src/index.js', output: { file: 'src/browserified/MFParser/index.js', format: 'umd', diff --git a/src/css/main.css b/src/css/main.css index e681cdf6f9..746575e008 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -288,7 +288,7 @@ div.ci-module-header-toolbar ul { } div.ci-module-header-toolbar ul li { - margin: 0 0 0 10px; + margin: 0 0 0 5px; list-style-type: none; cursor: pointer; color: #666666; diff --git a/src/init.js b/src/init.js index 07902ebc92..a47c0f81f4 100644 --- a/src/init.js +++ b/src/init.js @@ -6,31 +6,24 @@ require.config({ ace: 'components/ace/src', angularplasmid: 'node_modules/angularplasmid/dist/angularplasmid.complete.min', - async: 'components/async/dist/async', - babel: 'components/babel-standalone/babel.min', - bowser: 'components/bowser/bowser', canvg: 'components/canvg/dist/canvg.bundle', chroma: 'components/chroma-js/chroma.min', ckeditor: 'components/ckeditor/ckeditor', countryData: 'browserified/country-data/index', delay: 'browserified/delay/index', d3: 'components/d3/d3.min', - 'd3-hierarchy': 'node_modules/d3-hierarchy/dist/d3-hierarchy.min', eventEmitter: 'components/eventEmitter/EventEmitter.min', - fancytree: 'components/fancytree/dist/jquery.fancytree-all', - fetch: 'components/fetch/fetch', 'file-saver': 'components/file-saver.js/FileSaver', forms: 'lib/forms', highlightjs: 'lib/highlight.js/highlight.pack', jcampconverter: 'lib/jcampconverter/jcampconverter.7.3.1.min', jqgrid: 'components/jqgrid_edit/js/jquery.jqGrid', jsbarcode: 'components/jsbarcode/dist/JsBarcode.all.min', - jquery: 'components/jquery/dist/jquery', - 'jquery-cookie': 'components/jquery-cookie/jquery.cookie', + jquery: 'node_modules/jquery/dist/jquery', + 'jquery-migrate': 'node_modules/jquery-migrate/dist/jquery-migrate', 'jquery-tmpl': 'components/jquery-tmpl/jquery.tmpl.min', - 'jquery-ui': 'components/jquery-ui', + 'jquery-ui': 'node_modules/jquery-ui/dist/jquery-ui', jsgraph: 'components/jsgraph/dist/jsgraph-es6', - jsoneditor: 'components/jsoneditor/dist/jsoneditor-minimalist.min', 'json-chart': 'components/json-chart/dist/json-chart.min', jszip: 'components/jszip/dist/jszip.min', 'js-yaml': 'components/js-yaml/dist/js-yaml.min', @@ -40,13 +33,12 @@ require.config({ 'markdown-js': 'components/markdown-js/lib/markdown', marked: 'components/marked/lib/marked', // mathjax: 'components/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML&delayStartupUntil=configured', - mathjs: 'node_modules/mathjs/dist/math.min', + mathjs: 'node_modules/mathjs/lib/browser/math', 'mime-types': 'browserified/mime-types/index', moment: 'components/moment/moment', 'moment-duration-format': 'components/moment-duration-format/lib/moment-duration-format', notifyjs: 'components/notifyjs/dist/notify', - modernizr: 'components/modernizr/modernizr', msa: 'lib/msa/msa.min', 'nmr-simulation': 'components/nmr-simulation/dist/nmr-simulation', numeral: 'components/numeral/numeral', @@ -72,14 +64,6 @@ require.config({ uri: 'components/uri.js/src', 'web-animations': 'components/web-animations-js/web-animations.min', x2js: 'components/x2js/xml2json.min', - BiojsSequence: 'lib/biojs-1.0/src/main/javascript/Biojs.Sequence', - BiojsTooltip: 'lib/biojs-1.0/src/main/javascript/Biojs.Tooltip', - BiojsFeatureViewer: 'lib/biojs-1.0/src/main/javascript/Biojs.FeatureViewer', - BiojsCore: 'lib/biojs-1.0/src/main/javascript/Biojs', - BiojsMyFeatureViewer: - 'modules/types/bio/feature_viewer/Biojs.MyFeatureViewer', - BiojsDasProteinFeatureViewer: - 'lib/biojs-1.0/src/main/javascript/Biojs.DasProteinFeatureViewer', }, shim: { canvg: { @@ -88,9 +72,6 @@ require.config({ katex: { exports: 'katex', }, - fetch: { - exports: 'fetch', - }, // mathjax: { // exports: 'MathJax', // init: function () { @@ -118,21 +99,19 @@ require.config({ ckeditor: { exports: 'CKEDITOR', }, - modernizr: { - exports: 'Modernizr', - }, 'lib/parser/Parser': { exports: 'Parser', }, quillResizeModule: ['quillPrivate', 'quill'], quillTableBetterModule: ['quillPrivate', 'quill'], - 'jquery-cookie': 'jquery', select2: ['jquery'], jsbarcode: ['jquery'], 'lib/threejs/TrackballControls': ['threejs'], + 'jquery-migrate': ['jquery'], + 'jquery-ui': ['jquery'], jqgrid: ['jquery', 'components/jqgrid_edit/js/i18n/grid.locale-en'], 'lib/couchdb/jquery.couch': ['jquery'], - slickgrid_core: ['jquery', 'jquery-ui/ui/widgets/sortable', 'jquery-tmpl'], + slickgrid_core: ['jquery', 'jquery-ui', 'jquery-tmpl'], slickgrid: { deps: [ 'slickgrid_core', @@ -162,31 +141,13 @@ require.config({ deps: ['lib/pixastic/pixastic/pixastic.core'], exports: 'Pixastic', }, - fancytree: [ - 'jquery-ui/ui/effects/effect-blind', - 'jquery-ui/ui/widgets/droppable', - 'jquery-ui/ui/widgets/draggable', - ], 'moment-duration-format': ['moment'], - BiojsCore: { - exports: 'Biojs', - }, - BiojsSequence: ['BiojsCore'], - BiojsTooltip: ['BiojsCore'], - BiojsMyFeatureViewer: ['BiojsFeatureViewer'], - BiojsFeatureViewer: [ - 'BiojsCore', - 'lib/biojs-1.0/src/main/resources/dependencies/jquery/jquery.tooltip', - 'lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael-2.1.2', - 'lib/biojs-1.0/src/main/resources/dependencies/graphics/canvg', - 'lib/biojs-1.0/src/main/resources/dependencies/graphics/rgbcolor', - ], - BiojsDasProteinFeatureViewer: ['BiojsMyFeatureViewer'], }, map: { '*': { quill: 'quillPrivate', Quill: 'quillPrivate', + 'components/fancytree/dist/modules/jquery.fancytree.ui-deps': 'jquery-ui', }, quillPrivate: { quill: 'quill', @@ -219,8 +180,10 @@ require([ 'uri/URI.fragmentQuery', 'components/setImmediate/setImmediate', 'lib/regenerator/regenerator-runtime', + 'jquery-ui', + // Uncomment to enable jquery-migrate deprecations warnings. + // 'jquery-migrate', ], function (Version, $, Datas, EntryPoint, URI) { - $.browser = { msie: false }; // Property used by old libraries and not present in jQuery anymore $(document).ready(() => { const url = new URI(window.location.href); const type = diff --git a/src/lib/biojs-1.0/README.md b/src/lib/biojs-1.0/README.md deleted file mode 100755 index 739cb63937..0000000000 --- a/src/lib/biojs-1.0/README.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview -The aim of this project is to create a library of graphical components easy to reuse to represent biological information. A library easy to maintain and develop by identifying minimal functional units that could be used as building blocks for more complex applications. A browser independent JavaScript library easy to integrate in web applications regardless the programming language used to develop the server side. - -* [Registry of components](http://www.ebi.ac.uk/Tools/biojs/registry) -* [Documentation for developers](https://github.com/biojs/biojs/wiki/Documentation) - -# Objectives -* Represent consistently biological information across different projects -* Ease discovery, test and integration of graphical components -* Standardize and facilitate components development - -# Use a BioJS component -* Search and select a component in a BioJS registry. i.e. [EBI BioJS registry](http://www.ebi.ac.uk/Tools/biojs/registry/components.html) -* Look at the "overview" section to see an example of how a component works -* Check the "options", "methods" and "events" sections to see more information about the functionality provided by a component -* Find inside the "installation" section the code and dependencies you will need to make a component working in a web page - -# Develop a component -BioJS components are framework agnostic, only requiring the code to be written in JavaScript. The developer of a new component is thus free to use any framework (e.g. [JQuery](http://jquery.com/), [YUI](http://yuilibrary.com/)) and to include any other library (e.g. [Raphael](http://raphaeljs.com/), [D3](http://d3js.org/)). - -Any component by definition extends the BioJS reference implementation incorporating the rules provided by the [BioJS specification](https://docs.google.com/document/d/1gG036Bvwl4i-KX5BTHddGzeE_5eospL-864BrnsAS_s/edit). The BioJS specification defines: - -* the component architecture -* a protocol to handle events that allows communication between components -* the component extension through Object Oriented Inheritance -* the code documentation format -* documentation on how to include examples to test the component functionality - -# Create a new component from scratch - -We would recommend you to follow our [tutorials](https://github.com/biojs/biojs/wiki/Documentation#tutorials) and read the [BioJS documentation](https://github.com/biojs/biojs/wiki/Documentation). - -Visualization components can be as complex as you want. However we encourage you to identify the minimal parts that make sense to isolate building components that can be reused independently or as a part of another more complex components. - -Before coding we suggest to collect [requirements](https://github.com/biojs/biojs/wiki/Documentation#requirements) that will help you to think about how to implement a component. You could use our [template](https://docs.google.com/document/d/1LLyUK0jEc8KXAtlmUc7vX68wvR3k8AoSdkLVSKcK1M0/edit) to collect requirements or you could follow your own. If would like to share your requirements document we will be happy to include it in the list of component requirements. - -# Wrap JavaScript functionality as BioJS - -If you already have some JavaScript functionality you could make it BioJS creating a wrapper on top of it. A wrapper is simply a new BioJS components using your JavaScript functionality as a dependency. We do not have a specific tutorial for this, but you could use the tutorials we have to create a component. - -# Feedback -Please feel free to send us feature requests and/or ideas of what it should be considered in the development of BioJS through the [issue tracker](https://github.com/biojs/biojs/issues) or the [BioJS mailing list](https://groups.google.com/forum/#!forum/biojs). - -Join the BioJS mailing list if you would like to send us an email to participate or provide feedback about the project. - -# Code license -[Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0) - diff --git a/src/lib/biojs-1.0/pom.xml b/src/lib/biojs-1.0/pom.xml deleted file mode 100755 index 7522585f1d..0000000000 --- a/src/lib/biojs-1.0/pom.xml +++ /dev/null @@ -1,182 +0,0 @@ - - 4.0.0 - uk.ac.ebi - biojs - - 1.0-SNAPSHOT - BioJS - - - ${basedir}/target/biojs - - - nl.windgazer - jsdoctk-plugin - 2.3.2 - - - ${project.build.directory} - 1 - js - ${basedir}/src/main/javascript - - - - - - - - - - - net.alchim31.maven - 1.3.0 - yuicompressor-maven-plugin - - - compile - - compress - - - - - false - true - true - ${project.basedir}/src/main/javascript - ${project.build.directory}/biojs/ - - **/css/**/* - **/dependencies/**/* - - - - - - - maven-resources-plugin - 2.5 - - - copy-resources - - compile - - copy-resources - - - ${basedir}/target/test - - - src/test/javascript - true - - - - - - - - - - maven-resources-plugin - 2.5 - - - copy-resources - - compile - - copy-resources - - - ${basedir}/target/test/data - - - src/test/data - true - - - - - - - - - - - - - - - jsdoctk1 - http://jsdoctk-plugin.googlecode.com/svn/repo - - - - - - - jsdoctk2 - http://jsdoctk-plugin.googlecode.com/svn/repo - - - diff --git a/src/lib/biojs-1.0/registry.txt b/src/lib/biojs-1.0/registry.txt deleted file mode 100755 index 9894064d5f..0000000000 --- a/src/lib/biojs-1.0/registry.txt +++ /dev/null @@ -1,8 +0,0 @@ -To quickly build the registry web application from this code, execute the command below. The web application will be available in "target/registry". Remember to make the BioJS files accessible through a web server like "Apache HTTP Server". - - mvn clean compile jsdoctk:jsdoc - -For more information: - https://github.com/biojs/biojs - https://github.com/biojs/biojs/wiki/Documentation - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.AreaSelector.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.AreaSelector.js deleted file mode 100755 index fd27054b92..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.AreaSelector.js +++ /dev/null @@ -1,275 +0,0 @@ -/** - * This component visualize a div in a upper layer that can be used to select an area of other component. - * Although is not biological related component, it is generic enough to be used in other components, that - * require to select a region, see chromosome example. Just one selector can be used for a HTML component. - *

WARNING: The CSS value for the position will be changed to relative.

- * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires jquery.watcher.js - * @dependency - * - * @requires Selector CSS - * @dependency - * - * @param {Object} options An object with the options for the Chromosome component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {boolean} resize_left - * to indicate if the selector can be resizable from the left side. default value: true - * - * @option {boolean} resize_right - * to indicate if the selector can be resizable from the right side. default value: true - * - * @option {boolean} resize_top - * to indicate if the selector can be resizable from the top side. default value: true - * - * @option {boolean} resize_bottom - * to indicate if the selector can be resizable from the bottom side. default value: true - * - * @option {array} area - * an array with 4 elements(integers) to indicate the start position of the area selector. - * The first two elements indicate the X and Y position of the top-left corner, - * the last 2 elements indicate the bottom-right position. - * The position are relative to the target element. - * - * @example - * var instance = new Biojs.AreaSelector({ - * target: "YourOwnDivId", - * area: [10,10,40,40] - * }); - - * - */ - -Biojs.AreaSelector = Biojs.extend ( -/** @lends Biojs.AreaSelector# */ -{ - constructor: function (options) { - var self=this; - $("#"+self.opt.target).css("position","relative"); - var innerCode="
"; - if (self.opt.resize_left) innerCode += "
"; - if (self.opt.resize_right) innerCode += "
"; - if (self.opt.resize_top) innerCode += "
"; - if (self.opt.resize_bottom) innerCode += "
"; - innerCode += "
"; - $("#"+self.opt.target).append(innerCode); - - - $("#"+self.opt.target+" .selector .right").draggable({ - axis: "x", - start :function(event) { - self.updateScalers(); - $(this).parent().css('border-right-width',"0px"); - }, - stop :function(event) { - $("#"+self.opt.target+" .selector").width(self._removePx($(this).css('left'))+5); - $(this).parent().css('border-right-width',"1px"); - self.updateScalers(); - self.raiseEvent('onRegionChanged', { - region : self.getCoveredArea() - }); - } - }); - $("#"+self.opt.target+" .selector .left").draggable({ - axis: "x", - start :function(event) { - self.updateScalers(); - $(this).parent().css('border-left-width',"0px"); - }, - stop :function(event) { - var delta=$(this).position().left+5; - $("#"+self.opt.target+" .selector").width($("#"+self.opt.target+" .selector").width()-delta); - $("#"+self.opt.target+" .selector").css('left',($(this).parent().position().left+delta)+"px"); - $(this).parent().css('border-left-width',"1px"); - self.updateScalers(); - self.raiseEvent('onRegionChanged', { - region : self.getCoveredArea() - }); - } - }); - $("#"+self.opt.target+" .selector .bottom").draggable({ - axis: "y", - start :function(event) { - self.updateScalers(); - $(this).parent().css('border-bottom-width',"0px"); - }, - stop :function(event) { - $("#"+self.opt.target+" .selector").height(self._removePx($(this).css('top'))+5); - $(this).parent().css('border-bottom-width',"1px"); - self.updateScalers(); - self.raiseEvent('onRegionChanged', { - region : self.getCoveredArea() - }); - } - }); - $("#"+self.opt.target+" .selector .top").draggable({ - axis: "y", - start :function(event) { - self.updateScalers(); - $(this).parent().css('border-top-width',"0px"); - }, - stop :function(event) { - var delta=$(this).position().top+5; - $("#"+self.opt.target+" .selector").height($("#"+self.opt.target+" .selector").height()-delta); - $("#"+self.opt.target+" .selector").css('top',($(this).parent().position().top+delta)+"px"); - $(this).parent().css('border-top-width',"1px"); - self.updateScalers(); - self.raiseEvent('onRegionChanged', { - region : self.getCoveredArea() - }); - } - }); - - - $("#"+self.opt.target).watch("left,top,width,height,display", function() { - self.updateScalers(); - }, 100, "_containerMove"); - - self.updateScalers(); - self.setCoveredArea(self.opt.area); - }, - - /** - * Default values for the options - * @name Biojs.AreaSelector-opt - */ - opt: { - target: "YourOwnDivId", - resize_left: true, - resize_right: true, - resize_top: true, - resize_bottom: true, - area: [0,0,50,50] - }, - - /** - * Array containing the supported event names - * @name Biojs.AreaSelector-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.AreaSelector#onRegionChanged - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * It gets activated when the covered area has changed - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {array} region A 4-element array indicating the current position of the selector. - * The first two elements indicate the X and Y position of the top-left corner, - * the last 2 elements indicate the bottom-right position. - * The position are relative to the target element. - * - * @example - * instance.onRegionChanged(function( objEvent ) { - * alert("The current area is from the point [" + objEvent.region[0] + "," + objEvent.region[1] + "] to the point [" + objEvent.region[2] + "," + objEvent.region[3] + "] "); - * }); - */ - "onRegionChanged" - ], - - /** - * get the current value of the area - * - * @example - * var area = instance.getCoveredArea(); - * alert("The current area is from the point [" + area.region[0] + "," + area.region[1] + "] to the point [" + area.region[2] + "," + area.region[3] + "] "); - * - */ - getCoveredArea: function(){ - var self=this; - return [ - $("#"+self.opt.target+" .selector").position().left, - $("#"+self.opt.target+" .selector").position().top, - $("#"+self.opt.target+" .selector").position().left + $("#"+self.opt.target+" .selector").width(), - $("#"+self.opt.target+" .selector").position().top + $("#"+self.opt.target+" .selector").height() - ]; - }, - /** - * set the value of the area - * - * @param {string} area A 4-element array indicating the position to locate the selector. - * The first two elements indicate the X and Y position of the top-left corner, - * the last 2 elements indicate the bottom-right position. - * The position are relative to the target element. - * - * @example - * instance.setCoveredArea([ 20,20,50,50]); - * - */ - setCoveredArea: function(area){ - var self=this; - $("#"+self.opt.target+" .selector").css('left',area[0]+"px"); - $("#"+self.opt.target+" .selector").css('top',area[1]+"px"); - $("#"+self.opt.target+" .selector").width(area[2]-area[0]); - $("#"+self.opt.target+" .selector").height(area[3]-area[1]); - self.updateScalers(); - self.raiseEvent('onRegionChanged', { - region : self.getCoveredArea() - }); - }, - - /** - * @private - * Private: update the positions and the limits of the scalers - */ - updateScalers: function(){ - var self=this; - $("#"+self.opt.target+" .selector .left").css("left","-5px"); - $("#"+self.opt.target+" .selector .left").css("top",($("#"+self.opt.target+" .selector").height()/2)-5); - $("#"+self.opt.target+" .selector .right").css("left",$("#"+self.opt.target+" .selector").width()-5); - $("#"+self.opt.target+" .selector .right").css("top",($("#"+self.opt.target+" .selector").height()/2)-5); - $("#"+self.opt.target+" .selector .top").css("left",($("#"+self.opt.target+" .selector").width()/2)-5); - $("#"+self.opt.target+" .selector .top").css("top","-5px"); - $("#"+self.opt.target+" .selector .bottom").css("left",($("#"+self.opt.target+" .selector").width()/2)-5); - $("#"+self.opt.target+" .selector .bottom").css("top",$("#"+self.opt.target+" .selector").height()-5); - $("#"+self.opt.target+" .selector .right").draggable("option","containment",[ - $("#"+self.opt.target+" .selector").offset().left-3, - $("#"+self.opt.target).offset().top, - $("#"+self.opt.target).offset().left+$("#"+self.opt.target).width()-4, - $("#"+self.opt.target).offset().top+$("#"+self.opt.target).height() - ]); - $("#"+self.opt.target+" .selector .left").draggable("option","containment",[ - $("#"+self.opt.target).offset().left-4, - $("#"+self.opt.target).offset().top, - $("#"+self.opt.target+" .selector").offset().left+$("#"+self.opt.target+" .selector").width()-5, - $("#"+self.opt.target).offset().top+$("#"+self.opt.target).height() - ]); - $("#"+self.opt.target+" .selector .bottom").draggable("option","containment",[ - $("#"+self.opt.target).offset().left, - $("#"+self.opt.target+" .selector").offset().top-3, - $("#"+self.opt.target).offset().left+$("#"+self.opt.target).width(), - $("#"+self.opt.target).offset().top+$("#"+self.opt.target).height()-4 - ]); - $("#"+self.opt.target+" .selector .top").draggable("option","containment",[ - $("#"+self.opt.target).offset().left, - $("#"+self.opt.target).offset().top-4, - $("#"+self.opt.target).offset().left+$("#"+self.opt.target).width()-4, - $("#"+self.opt.target+" .selector").offset().top+$("#"+self.opt.target+" .selector").height()-5 - ]); - }, - /** - * @private - * Private: remove the last two characters of a string and return its integer value - */ - _removePx: function(str){ - return 1*str.substr(0,str.length-2); - } -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.AutocompleteOLS.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.AutocompleteOLS.js deleted file mode 100755 index 84c82769f5..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.AutocompleteOLS.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * This is a component that provides autocomplete functionality for querying the Ontology Lookup Service (OLS) for any ontology or set of ontologies in this service. - * It is based on the jquery Autocomplete widget developed for ArrayExpress and was developed with support from the BioMedBridges project. - * - * - * @class - * @extends Biojs - * - * @author Dani Welter, Simon Jupp, Nikolay Kolesnikov - * @version 0.5.0_beta - * @category 1 - * - * @requires jQuery Core 1.8.2 - * @dependency - * - * @requires jQuery Caret-Range 1.0 - * @dependency - * - * @requires jQuery Autocomplete for OLS - * @dependency - * - * @requires AE Common CSS - * @dependency - * - * - * - * @param {Object} options An object with the options for the Autocomplete component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [ontology="EFO"] - * The ontology to be queried via the component. - * - * @example - * var instance = new Biojs.AutocompleteOLS({ - * target: "YourOwnDivId", - * ontology: "EFO" - * }); - * - */ -Biojs.AutocompleteOLS = Biojs.extend ( - /** @lends Biojs.AutocompleteOLS# */ - { - constructor: function (options) { - var self = this; - - this._container = jQuery("#" + self.opt.target); - this._container.append(jQuery("")); - - if ($ == undefined) { - throw "jQuery not loaded"; - } - $(function() { - - var autoCompleteFixSet = function() { - $(this).attr('autocomplete', 'off'); - }; - var autoCompleteFixUnset = function() { - $(this).removeAttr('autocomplete'); - }; - - $("#local-searchbox").autocomplete( - "http://www.ebi.ac.uk/ontology-lookup/term.view" - , { matchContains: false - , selectFirst: false - , scroll: true - , max: 50 - , requestTreeUrl: "http://www.ebi.ac.uk/ontology-lookup/json/termchildren" - , ontologyId: self.opt.ontology -// change this to "all" to search all ontologies - dont do this for now! - } - ).focus(autoCompleteFixSet).blur(autoCompleteFixUnset).removeAttr('autocomplete'); - - - }); - - }, - - - /** - * Default values for the options - * @name Biojs.AutocompleteOLS-opt - */ - opt: { - target: "", - ontology: "EFO" - }, - - /** - * Array containing the supported event names - * @name Biojs.AutocompleteOLS-opt - */ - eventTypes: [] - - } - -); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEBICompound.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEBICompound.js deleted file mode 100755 index 1e5cfe49e9..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEBICompound.js +++ /dev/null @@ -1,374 +0,0 @@ -/** - * - * - * @class - * @extends Biojs - * - * @author John Gomez-Carvajal - * @version 1.0.0 - * @category 2 - * - * @requires Server side proxy - * - * @requires ChEBICompound.css - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options An object with the options for the component. - * - * @option {string} [imageUrl="http://www.ebi.ac.uk/chebi/displayImage.do"] - * Url of the web service in order to require the compound image. - * To get a compound image, 'imageUrl + id' will be used as URI. - * - * @option {string} id - * ChEBI identifier of the compound to be displayed (i.e. '4991'). - * - * @option {int} [height=undefined] - * The height in pixels of how big this component should be displayed. If it's not specified, the CSS value will be used instead. - * - * @option {int} [width=undefined] - * The width in pixels of how big this image should be displayed. If it's not specified, the CSS value will be used instead. - * - * @example - * var instance = new Biojs.ChEBICompound({ - * target: 'YourOwnDivId', - * id: 'CHEBI:2922', - * width: 700, - * height: 400 - * }); - * - */ -Biojs.ChEBICompound = Biojs.extend( -/** @lends Biojs.ChEBICompound# */ -{ - constructor: function(options){ - - var self = this; - var width = this.opt.width; - var height = this.opt.height; - var imageWidth, imageHeight; - - if ( "string" == (typeof this.opt.target) ) { - this._container = jQuery( "#" + this.opt.target ); - - } else { - - this.opt.target = "biojs_ChEBICompound_" + this.getId(); - this._container = jQuery('
'); - } - - this._container.html('').addClass("ChEBICompound"); - - if ( width == undefined ) { - width = this._container.css('width'); - - } else { - this._container.width( width ); - } - - if ( height == undefined ) { - height = this._container.css('height'); - - } else { - this._container.height( height ); - } - - this._container.html(''); - this._imageContainer = jQuery('
').appendTo(this._container); - this._tabContainer = jQuery('
').appendTo(this._container); - - // Build the summary left panel - this._summaryContainer = this._buildTabPanel( - this._tabContainer, - function ( tabVisible, visibleWidth ) { - // Do nothing on tab visibility change - } - ); - - // Size of the image for the URL request - imageWidth = this._imageContainer.width(); - imageHeight = this._imageContainer.height(); - this.opt.imageDimension = (imageWidth < imageHeight)? imageWidth: imageHeight; - - if (this.opt.id !== undefined) { - this.setId(this.opt.id); - } - }, - - opt: { - target: 'YourOwnDivId', - id: undefined, - imageUrl: 'http://www.ebi.ac.uk/chebi/displayImage.do', - chebiDetailsUrl: 'http://www.ebi.ac.uk/webservices/chebi/2.0/test/getCompleteEntity?chebiId=', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - - height: undefined, - width: undefined, - scale: false, - imageIndex: 0 - }, - - eventTypes : [ - /** - * @name Biojs.ChEBICompound#onRequestError - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onRequestError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - * */ - "onRequestError", - /** - * @name Biojs.ChEBICompound#onImageLoaded - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} id The identifier of the loaded file. - * - * @example - * instance.onImageLoaded( - * function( e ) { - * alert( e.id + " loaded." ); - * } - * ); - * - * */ - "onImageLoaded" - ], - - /** - * Set the identifier of the chemical component. - * Shows both information and image for the new identifier. - * - * @param {string} chebiId Chemical EBI's identifier for the compound to be displayed. - * - * @example - * instance.setId('CHEBI:4991'); - * - * @example - * // No image available - * instance.setId('CHEBI:60004'); - * - */ - setId: function( chebiId ) { - - var self = this; - var url; - var image; - - this._imageContainer.html(''); - this.opt.id = chebiId.replace('CHEBI:',''); - this._requestDetails( this.opt ); - - var params = { - defaultImage: true, - imageIndex: this.opt.imageIndex, - chebiId: chebiId, - dimensions: this.opt.imageDimension, - scaleMolecule: this.opt.scale - }; - - url = this.opt.imageUrl + '?' + jQuery.param(params); - image = jQuery('') - .load(function() { - self._imageContainer.removeClass("noImage"); - self._imageContainer.append(image).css({ - 'width': self.opt.imageDimension, - 'height': self.opt.imageDimension, - 'margin': 'auto' - }); - - self.raiseEvent( Biojs.ChEBICompound.EVT_ON_IMAGE_LOADED, { - id: chebiId, - url: url - }); - }) - .error(function() { - self._imageContainer.addClass("noImage"); - self.raiseEvent( Biojs.ChEBICompound.EVT_ON_REQUEST_ERROR, { - id: chebiId, - url: url, - message: "No image available" - }); - }) - .attr('src', url); - }, - - _requestDetails: function( opt ){ - var self = this; - - var urlSummary = opt.chebiDetailsUrl + opt.id; - - Biojs.console.log( "Requesting summary from: " + urlSummary ); - - var httpRequest = { - url: urlSummary, - method: "GET", - /** - * @ignore - */ - success: function(xml){ - self._dataReceived(xml); - }, - /** - * @ignore - */ - error: function(qXHR, textStatus, errorThrown) { - Biojs.console.log("ERROR requesting summary. Response: " + textStatus); - self.raiseEvent( Biojs.ChEBICompound.EVT_ON_REQUEST_ERROR, { - message: textStatus - }); - } - }; - - // Using proxy? - // Redirect using the proxy and encode all params as url data - if ( opt.proxyUrl != undefined ) { - - // Redirect to proxy url - httpRequest.url = opt.proxyUrl; - - // Encode both url and parameters under the param url - httpRequest.data = [{ name: "url", value: urlSummary }]; - - - } - // Data type - httpRequest.dataType = "text"; - jQuery.ajax(httpRequest); - - }, - - - // parses the xml file from the request and stores the information in an easy to access way - _dataReceived: function(xml){ - var data = {}; - var i = 0; - var self = this; - - Biojs.console.log("Data received"); - - if ( xml.length > 0 ) { - xmlDoc = jQuery.parseXML( xml ); - xmlResult = jQuery(xmlDoc).find('return'); - - data.chebiAsciiName = { name: "Name", value: xmlResult.find(' > chebiAsciiName').text() }; - data.chebiId = { name: "Identifier", value: xmlResult.find('> chebiId').text() }; - data.definition = { name: "Definition", value: xmlResult.find('> definition').text() }; - data.SecondaryChEBIIds = { name: "Other Identifiers", value: xmlResult.find(' > SecondaryChEBIIds').text() }; - data.entityStar = { name: "Stars", value: xmlResult.find(' > entityStar').text() }; - - } - - this._setSummary( data ); - - return data; - }, - - - _setSummary : function ( data ) { - Biojs.console.log("_setSummary()"); - - var container = this._summaryContainer; - - // Remove all elements in container - container.children().remove(); - - if ( Biojs.Utils.isEmpty(data) ) { - container.append('Not information available'); - - } else { - // Add the summary data - for (key in data) { - if ( data[key].value.length > 0 ) { - if ( key == 'entityStar' ) { - jQuery('

' + data[key].name + '

').appendTo( container ); - jQuery('
') - .appendTo( container ) - .css({ - 'width': parseInt(data[key].value) * 16, - 'padding': 0 - }); - } else { - container.append( '

' + data[key].name + '

' + data[key].value + '

' ); - } - } - } - - this.raiseEvent( Biojs.ChEBICompound.EVT_ON_SUMMARY_LOADED,{ - id: data.Identifier - }); - } - - Biojs.console.log("_setSummary done"); - }, - - _buildTabPanel: function( container, onVisibilityChangeCb ) { - - container.html(''); - - var content = jQuery('
').appendTo(container); - var expand = jQuery('').appendTo(container); - var collapse = jQuery('
').appendTo(container); - - var buttonsWidth = parseInt( jQuery('.toggle').css('width'), 10 ); - var contentWidth = container.width() - buttonsWidth; - - container.css( 'left', 0 ) - .find('.toggle') - .click( function(){ - // Animate show/hide this tab - container.animate({ - left: ( parseInt( container.css('left'), 10 ) == 0 ? buttonsWidth - container.outerWidth() : 0 ) + "px" - }, - // to call once the animation is complete - function() { - - var visibleWidth = parseInt( container.css('left'), 10 ) == 0 ? container.width() : buttonsWidth; - - container.find('.toggle').toggle(); - - if ( "function" == typeof onVisibilityChangeCb ) { - onVisibilityChangeCb.call( this, collapse.is(':visible'), visibleWidth ); - } - } - ); - }) - .css({ - 'float':'right', - 'position':'relative' - }); - - Biojs.console.log('content width '+ contentWidth); - - content.css({ - 'width': contentWidth + "px", - 'height': container.height() + "px", - 'word-wrap': 'break-word' - }); - - return content; - }, - - getHTML: function () { - return this._container; - } - -},{ - //Events - EVT_ON_IMAGE_LOADED: "onImageLoaded", - EVT_ON_SUMMARY_LOADED: "onSummaryLoaded", - EVT_ON_REQUEST_ERROR: "onRequestError" - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEMBLCompound.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEMBLCompound.js deleted file mode 100755 index 6b20f71b2d..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.ChEMBLCompound.js +++ /dev/null @@ -1,297 +0,0 @@ -/** - * - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 2 - * - * @requires Server side proxy - * - * @param {Object} options An object with the options for the component. - * - * @option {string} [imageUrl="http://www.ebi.ac.uk/chebi/displayImage.do"] - * Url of the web service in order to require the compound image. - * To get a compound image, 'imageUrl + id' will be used as URI. - * - * @option {string} id - * ChEBI identifier of the compound to be displayed (i.e. '4991'). - * - * @option {int} [height=400] - * The height in pixels of how big this image should be displayed. - * - * @option {int} [width=400] - * The width in pixels of how big this image should be displayed. - * - * @example - * var instance = new Biojs.ChEMBLCompound({ - * target: 'YourOwnDivId', - * id: 'CHEMBL67' - * }); - * - * - */ -Biojs.ChEMBLCompound = Biojs.extend( -/** @lends Biojs.ChEMBLCompound# */ -{ - constructor: function(options){ - Biojs.console.enable(); - //constructor of Biojs.ChEMBLCompound - - jQuery("#"+this.opt.target).css("padding","0px") - .css("width",this.opt.width) - .css("height",this.opt.height) - .css("overflow","hidden"); - - if (this.opt.id !== undefined) { - this.setId(this.opt.id); - } - }, - - opt: { - target: 'YourOwnDivId', - id: undefined, - imageUrl: 'https://www.ebi.ac.uk/chembldb/index.php/compound/displayimage/', - detailsUrl: 'https://www.ebi.ac.uk/chemblws/compounds/', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - - height: 400, - width: 597, - scale: false, - imageIndex: 0 - }, - - eventTypes : [ - /** - * @name Biojs.ChEMBLCompound#onRequestError - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onRequestError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - * */ - "onRequestError", - /** - * @name Biojs.ChEMBLCompound#onLoadedImage - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} id The identifier of the loaded file. - * - * @example - * instance.onLoadedImage( - * function( e ) { - * alert( e.id + " loaded." ); - * } - * ); - * - * */ - "onLoadedImage" - ], - - /** - * - * - * @example - * instance.setId('4991'); - * - */ - setId: function(chEMBLId) { - self = this; - self.opt.id = chEMBLId; - - var dimension = Math.round(self.opt.width * 0.7); - var url = self.opt.imageUrl + chEMBLId; - var image = ''; - - jQuery("div#"+this.opt.target).html( - '
'+ image +'
'+ - '
' - ); - - jQuery('#image_' + chEMBLId ).load(function() { - self.raiseEvent('onLoadedImage', {id: chEMBLId}); - }) - .css('height',self.opt.height) - .css('width',dimension); - - this._requestDetails(chEMBLId); - }, - - _requestDetails: function(chEMBLId){ - var self = this; - - Biojs.console.log('url=' + self.opt.detailsUrl + chEMBLId + '.json' ); - - jQuery.ajax({ - url: self.opt.proxyUrl, - dataType: 'json', - data: 'url=' + self.opt.detailsUrl + chEMBLId + '.json', - success: function(json){ - Biojs.console.log("SUCCESS: data received from "+this.data); - self._buildPanel(json.compounds); - }, - async: false, - error: function(qXHR, textStatus, errorThrown){ - Biojs.console.log(textStatus); - self.raiseEvent('onRequestError', {message: textStatus}); - } - }); - }, - - -// // parses the xml file from the request and stores the information in an easy to access way -// _parseResponse: function(xml){ -// var data = {}; -// var i = 0; -// var self = this; -// -// xmlDoc = jQuery.parseXML( xml ); -// xmlResult = jQuery(xmlDoc).find('return'); -// -// data.Identifier = xmlResult.find('> chEMBLId').text(); -// data.Definition = xmlResult.find('> definition').text(); -// data.Name = xmlResult.find(' > chebiAsciiName').text(); -// data.Stars = xmlResult.find(' > entityStar').text(); -// data.SecondaryIds = xmlResult.find(' > SecondaryChEBIIds').text(); -//// data.Synonyms = xmlResult.find(' > Synonyms > data').map(function(){ -//// return jQuery(this).text(); -//// }).get().join(", "); -// -// Biojs.console.log("Details decoded:"); -// Biojs.console.log(data); -// return data; -// }, - - - _buildPanel : function (details) { - - this._controlsVisible = false; - - Biojs.console.log(details); - - var self = this; - var width = Math.round(self.opt.width * 0.3); - var height = self.opt.height; - - var controlSectionDiv = jQuery("#"+self.opt.target+" > div#controlSection"+self.opt.id); - - controlSectionDiv.append('
'+ - '
'+ - '<<'+ - '>>

') - .css("border", 0) - .css("margin", 0) - .css("width", "auto") - .css("height", "auto") - .css('float', 'left') - .css('font-family','"Heveltica Neue", Arial, "sans serif"') - .css('font-size','12px'); - - // Measurements - // - var padding = 5; - var tabWidth = 20, tabHeight = height; - var controlsWidth = width - (2*padding+tabWidth), controlsHeight = height - (padding*2); - - // - // Panel - // - var controlDiv = controlSectionDiv.find("div#controls"); - - var detailsHTML = ''; - for (key in details) { - if ( details[key].length > 0 ) { - detailsHTML += '' + key + ':
' + details[key] + '

'; - } - } - - controlDiv.css("position","relative") - .css("border", 0) - .css("margin", 0) - .css('background-color', "#000") - .css('color', "#fff" ) - .css('float', 'left') - .css("width", controlsWidth ) - .css("height", controlsHeight) - .css("padding", padding) - .append( detailsHTML ); - - // - // Tab - // - var showHideTab = controlSectionDiv.find('#controlTab'); - - showHideTab.css("border", 0) - .css("margin", 0) - .css("padding", 0) - .css("float", "left") - .css("width", tabWidth) - .css("height", tabHeight) - .css('background-color', "#000"); - - /** - * @private - * @function - */ - // This function will hide/show the control panel - var toggleControls = function (){ - - showHideTab.find("span").toggle(); - - if (self._controlsVisible) { - controlDiv.hide(); - //showHideTab.css('background-color', self.opt.backgroundColor); - self._controlsVisible = false; - } else { - controlDiv.show(); - //showHideTab.css('background-color', "#000"); - self._controlsVisible = true; - } - } - - self._toggleControls = toggleControls; - - showHideTab.find('#hideButton') - .click( self._toggleControls ) - .mouseover(function(){ - jQuery(this).css("color","#27C0FF"); - }) - .mouseout(function(){ - jQuery(this).css("color","#fff"); - }) - .css("color","#fff") - .css("display","none") - .css("cursor","pointer"); - - showHideTab.find('#showButton') - .click( self._toggleControls ) - .mouseover(function(){ - jQuery(this).css("color","#27C0FF"); - }) - .mouseout(function(){ - jQuery(this).css("color","#000"); - }) - .css("color","#000") - .css("cursor","pointer"); - - this._controlsReady = true; - - Biojs.console.log("_buildPanel done"); - } - - - - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Chromosome.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Chromosome.js deleted file mode 100755 index eef4eb55e7..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Chromosome.js +++ /dev/null @@ -1,413 +0,0 @@ -/** - * This component allow to visualize a chromosome and its bands. - * The bands can be recovered from a DAS source or directly from a javascript model. - * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 1.0.1 - * @category 2 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jsdas 0.1.6 - * @dependency - * - * @requires Chromosome CSS - * @dependency - * - * - * @requires Biojs AreaSelector - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires jquery.watcher.js - * @dependency - * - * @requires Selector CSS - * @dependency - * - * - * - * - * @param {Object} options An object with the options for the Chromosome component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} dasSource - * URL of the DAS source to obtain the band's information. - * For example Ensembl provides the human chromosome information as a DAS source in the - * URL http://www.ensembl.org/das/Homo_sapiens.NCBI36.karyotype/ - * - * @option {string} dasSegment - * DAS segment to query, in case of chromosomes is the chromosome id (eg. 8). - * Optionally DAS sources can be queried for a spwcific region of the chromosome(eg. 8:43100000,49100001) - * - * @option {Object} model - * Alternatively to DAS, This component can receive directly a javascript object containing the relevant information. - * Here is an example of the object structure using JSON notation: - * { - * "id": "8", - * "start": 1, - * "stop": 199999, - * "bands": [ - * { - * "label": "p11", - * "type": "acen", - * "start": 1, - * "stop": "100000" - * }, - * { - * "label": "q11", - * "type": "gpos75", - * "start": 100001, - * "stop": "199999" - * } - * ] - * } - * - * @option {boolean} [includeSelector] - * Include an area selector that interacts with the coordinate position of the chromosome. default true. - * - * @example - * var instance= new Biojs.Chromosome({ - * target: "YourOwnDivId", - * dasSource: "http://www.ensembl.org/das/Homo_sapiens.NCBI36.karyotype/", - * dasSegment: "8" - * }); - * - */ -Biojs.Chromosome = Biojs.extend ( -/** @lends Biojs.Chromosome# */ -{ - constructor: function (options) { - var self = this; - $("#"+self.opt.target).html('
'); - $("#"+self.opt.target+'_chr').css('position','relative'); - if (self.opt.dasSource!=null){ - var client = JSDAS.Simple.getClient(self.opt.dasSource); - client.features({segment: self.opt.dasSegment}, function(res){ - self._modelFromDAS(res,self); - }, self._error_response); - }else if (self.opt.model!=null){ - this._process_model(self.opt.model,self); - } - }, - - /** - * Default values for the options - * @name Biojs.Chromosome-opt - */ - opt: { - target: "chromosome", - model: null, - dasSource: null, - dasSegment: null, - includeSelector: true - }, - - /** - * Array containing the supported event names - * @name Biojs.Chromosome-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.Chromosome#onBandSelection - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} chromosome_id Id of the chromosome that the selected band belongs. - * @eventData {string} band_id Id of the band that has been selected. - * @eventData {integer} band_start Coordinate of the first nucleotide of the selected band - * @eventData {integer} band_stop Coordinate of the last nucleotide of the selected band - * @eventData {string} band_type type of the band selected (eg. acen, gpos50, gneg). - * @example - * instance.onBandSelection(function( objEvent ) { - * alert("The band " + objEvent.band_id + " of the chromosome " + objEvent.chromosome_id + " has been selected\n[" + objEvent.band_start + "," + objEvent.band_stop + "]"); - * }); - */ - "onBandSelection", - /** - * @name Biojs.Chromosome#onSelectorChanged - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. Is triggered when the the coordinates of the selector have been changed. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} chromosome_id Id of the chromosome that the selected band belongs. - * @eventData {integer} selector_start Coordinate of the left side of the selector - * @eventData {integer} selector_stop Coordinate of the right side of the selector - * @example - * instance.onSelectorChanged(function( objEvent ) { - * alert("The selector has move to the region \n[" + objEvent.selector_start + "," + objEvent.selector_stop + "]"); - * }); - */ - "onSelectorChanged", - /** - * @name Biojs.Chromosome#onModelLoaded - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. Triggered when he model has been loaded - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} model The model after been displayed - * @example - * instance.onModelLoaded(function( objEvent ) { - * alert("The model for the chromosome "+objEvent.model.id+" has been loaded"); - * }); - */ - "onModelLoaded", - /** - * @name Biojs.Chromosome#onDASLoadFail - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. Triggered when the model couldn't be loaded - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} dasSource URL of the DAS source queried - * @eventData {string} dasSegment URL of the DAS source queried - * @example - * instance.onDASLoadFail(function( objEvent ) { - * alert("The DAS source "+objEvent.dasSource+" with information of the segment "+objEvent.dasSegment+" couldn't be loaded"); - * }); - */ - "onDASLoadFail" - ], - - /** - * @private - * Private: Callback function in case of an error in the DAS query. - */ - _error_response: function(){ - var self=this; - $("#"+self.opt.target).append("ERROR querying the DAS source."); - self.raiseEvent('onDASLoadFail', { - dasSource: self.opt.dasSource, - dasSegment: self.opt.dasSegment - }); - }, - - /** - * @private - * Private: Callback function when the DAS response is captured. - * It maps the response into the internal model for bands. - */ - _modelFromDAS: function(res,parent){ - if(typeof parent != "undefined") - var self=parent; - var annotations = res.GFF.SEGMENT[0].FEATURE, chr_start=res.GFF.SEGMENT[0].start, chr_stop=res.GFF.SEGMENT[0].stop; - var model = { - id: res.GFF.SEGMENT[0].id, - start: res.GFF.SEGMENT[0].start*1, - stop: res.GFF.SEGMENT[0].stop, - bands:null - }; - var bands=[]; - var first="first",last=""; - for (var i in annotations){ - var ann = annotations[i],type=ann.TYPE.id.substr(5); - if (type=="acen"){ - if (ann.id[0]=="p") type="p_acen"; - else if (ann.id[0]=="q") type="q_acen"; - } - bands.push({start:ann.START.textContent*1,stop:ann.END.textContent*1,label:ann.id,type:type}); - } - model.bands=bands; - self.opt.model=model; - self._process_model(model,self); - }, - - /** - * @private - * Private: Creates a div element for each band in the model; the width of the band is calculated as a percentage - * of the relationship between the number of nucleotides in the band and the number of nucleotides of the chromosome. - */ - _process_model: function(model,self){ - //Sorting the bands by the start coordinate - model.bands.sort( - /** - * @ignore - **/ - function sortfunc(a,b){ - return a.start-b.start; - }); - var first="first",last="",firstid=null,firstW=null; - for (var i in model.bands){ - var band = model.bands[i]; - if (i*1+1==model.bands.length) - last="last"; - var percentage=94*(band.stop-band.start)/model.stop;// no using the 100% of the width, so there is an extra space for the borders - var band_id=model.id+"_"+band.label; - $("#"+self.opt.target+'_chr').append("
"); - band_id=band_id.replace(/\./gi, "\\."); - $("#"+band_id).click(function (){ - //Finding the band in the model - var band={} - for (var j in model.bands){ - if ($(this).attr("title")==model.bands[j].label) - band=model.bands[j]; - } - //arising an event with the ban info - self.raiseEvent('onBandSelection', { - chromosome_id : model.id, - band_id: band.label, - band_start: band.start, - band_stop: band.stop, - band_type: band.type - }); - //If the selector is included then its position gets updated to the selected band - if (self.opt.includeSelector){ - self.opt.selector.from=band.start; - self.opt.selector.to=band.stop; - self.raiseEvent('onSelectorChanged', { - chromosome_id : model.id, - selector_start: band.stop, - selector_stop: band.type - }); - self._moveSelectorToDivCoordinates($(this).position().left,$(this).position().left+$(this).width()); - } - }); - if(first!="") { - firstid=band_id; //id of the first band - firstW=band.stop; - } - first=""; - } - //Setting up the selector in case is included - if (self.opt.includeSelector){ - //The selector just allows horizontal interaction and is preseted in the first band - self.opt.selector = new Biojs.AreaSelector({ - target: self.opt.target+'_chr', - resize_top: false, - resize_bottom: false, - area:[0,-5,$('#'+firstid).width(),20] - }); - //Creating two more attributes in the object to save chromosome coordinates where is visible, starting in the first band - self.opt.selector.from = 0; - self.opt.selector.to = firstW; - self.opt.selector.fromWatcher=false; - //When the selector change its position the chromosome coordinates have to be updated - self.opt.selector.onRegionChanged(function( objEvent ) { - if (!self.opt.selector.fromWatcher){ - self.opt.selector.from = self._getCoordinateFromLeft(objEvent.region[0]); - self.opt.selector.to = self._getCoordinateFromLeft(objEvent.region[2]); - self.raiseEvent('onSelectorChanged', { - chromosome_id : self.opt.model.id, - selector_start: self.opt.selector.from, - selector_stop: self.opt.selector.to - }); - } - }); - //if the div containing the chromosome is resized or moved the selector is modified with - $("#"+self.opt.target).watch("left,top,width,height,display", function() { - self.opt.selector.fromWatcher=true; - if (self.opt.selector.from!=null && self.opt.selector.to!=null ) - self.moveSelectorToCoordinates(self.opt.selector.from,self.opt.selector.to); - self.opt.selector.fromWatcher=false; - }, 100, "_containerMove"); - } - self.raiseEvent('onModelLoaded', { - model: model - }); - - }, - /** - * AreaSelector component that allows to interact with the chromosome. - * Optional feature, that can be disable in the options object by setting the feature includeSelector to false - * @private - * @name Biojs.Chromosome-selector - */ - selector:null, - /** - * Move the Selector to a specific place in the chromosome - * - * @param {integer} from initial chromosome coordinate to locate the selector - * @param {integer} to final chromosome coordinate to locate the selector - * - * @example - * instance.moveSelectorToCoordinates(10000000,20000000); - * - */ - moveSelectorToCoordinates: function(from, to){ - var self=this; - if(self.opt.selector!=null){ - self.opt.selector.from=from; - self.opt.selector.to=to; - self._moveSelectorToDivCoordinates(self._getLeftFromCoordinate(from),self._getLeftFromCoordinate(to)); - }else - return false; - }, - - /** - * Gives the corresponding value for left in respect of the parent component from a chromosome coordinate - * @private - * @name Biojs.Chromosome-_getLeftFromCoordinate - */ - _getLeftFromCoordinate: function(coordinate){ - var self=this; - var band=null - for (var j in self.opt.model.bands){ - var b=self.opt.model.bands[j]; - if (coordinate>=b.start && coordinate<=b.stop){ - band=b; - break; - } - } - if (band!=null){ - var band_id=self.opt.model.id+"_"+band.label; - band_id=band_id.replace(/\./gi, "\\."); - var leftDiv = $("#"+band_id).position().left, - widthDiv= $("#"+band_id).width(), - leftBand=band.start, - widthBand=band.stop-band.start; - return leftDiv+ (((coordinate-leftBand)*widthDiv)/widthBand); - }else - return false; - - }, - /** - * Gives the corresponding value for a chromosome coordinate from the left value in respect of the parent component - * @private - * @name Biojs.Chromosome-_getCoordinateFromLeft - */ - _getCoordinateFromLeft: function(left){ - var self=this; - var band=null - for (var j in self.opt.model.bands){ - var b=self.opt.model.bands[j]; - var band_id=self.opt.model.id+"_"+b.label; - band_id=band_id.replace(/\./gi, "\\."); - - if (left>=$("#"+band_id).position().left && left<=$("#"+band_id).position().left + $("#"+band_id).width()){ - var leftDiv = $("#"+band_id).position().left, - widthDiv= $("#"+band_id).width(), - leftBand=b.start, - widthBand=b.stop-b.start; - return leftBand+ (((left-leftDiv)*widthBand)/widthDiv); - } - } - return false; - - }, - - /** - * moves the selector to a position in the div using the div relative coordinates - * @private - * @name Biojs.Chromosome-_moveSelectorToDivCoordinates - */ - _moveSelectorToDivCoordinates: function(from, to){ - var self=this; - if (self.opt.includeSelector && self.opt.selector!=null) - self.opt.selector.setCoveredArea([from,-5,to,20]); - } -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Cytoscape.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Cytoscape.js deleted file mode 100755 index dd2b2340ba..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Cytoscape.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * The Cytoscape.js component is a wrapper that allows you to use Cytoscape.js in BioJS. - * - * @class - * @extends Biojs - * - * @author Max Franz - * @version 1.0.0 - * @category 1 - * - * @requires Cytoscape.js (latest version strongly recommended) - * @dependency - * - * @param {Object} options An object with the options for Cytoscape.js. - * - * @option {string} container - * The ID of the HTML DOM element in which Cytoscape.js will be placed. - * - * - * @example - * var cy; - * var instance = new Biojs.Cytoscape({ - * container: window.document.getElementById('some-div-id'), - * ready: function(){ - * cy = this; // now you can use cytoscape.js as normal - * } - * }); - * - * - */ -Biojs.Cytoscape = Biojs.extend( -/** @lends Biojs.Cytoscape# */ -{ - constructor: function(options){ - cytoscape( options ); - }, - - /** - * Default values for the options - * @name Biojs.Cytoscape-opt - */ - opt: { - container: undefined - }, - - /** - * Array containing the supported event names - * @name Biojs.Cytoscape-eventTypes - */ - eventTypes: [ - ] - -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.DNAContentViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.DNAContentViewer.js deleted file mode 100755 index 7c159a5bbd..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.DNAContentViewer.js +++ /dev/null @@ -1,1024 +0,0 @@ -/** - * This component uses the D3 library to visualise contents of a DNA sequence, with panning and zooming functionality. - * - * @class - * @extends Biojs - * - * @author Anil Thanki, Shabhonam Caim - * @version 1.0.0 - * @category 2 - * - * - * @requires D3 - * @dependency - * - * - * @requires jQuery UI 1.8.2+ - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires biojs.DNAContentViewer.css - * @dependency - * - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * - * @param {Object} options An object with the options for DNAContentViewer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [fontFamily='"Andale mono", courier, monospace'] - * Font list to be applied to the component content. - * - * @option {string} [fontColor="white"] - * HTML color code for the font. - * - * @option {string} [backgroundColor="#7BBFE9"] - * Background color for the entire div content. - * - * @option {Object} [selectionFontColor="white"] - * This color will be used to change the font color of selected text. - * - * @option {Object} [selectionBackgroundColor="yellow"] - * This color will be used to change the background of selected text. - * - * @option {string} dataSet - * File in text format including input sequence data in raw format. Example of text file ...
- *
ACGACTAGCATCAGCATCGACACGACTAGCACTGGACTGAATCGACATCGACATGC
- *  ...
- * - * @example - * var instance = new Biojs.DNAContentViewer({ - * target: "YourOwnDivId", - * selectionBackgroundColor: '#99FF00', - * dataSet: "../biojs/data/DNAContentViewerData.txt" - * }); - * - */ - - -Biojs.DNAContentViewer = Biojs.extend( - /** @lends Biojs.DNAContentViewer# */ - - - { - zoomSlider: '', - slider_stop: 0, - slider_start: 0, - track: [], - track_bins: [], - width: 1, - height: 1, - data_last_start: 1, - data_first_start: 1, - max: 0, - data: [], - main_data: [], - - - constructor: function (options) { - - var self = this; - self.vis = null; - self.color = null; - self.foci = []; - - - this.track; // data - this.track_bins; // data - - - this._container = $("#DNAContentFeaturePainter-holder"); - $(this._container).addClass("graph"); - - - // Apply options values - this._container.css({ - 'font-family': self.opt.fontFamily, // this is one example of the use of self instead of this - 'background-color': self.opt.backgroundColor, - 'color': self.opt.fontColor, - 'font-size': '36px', - 'text-align': 'center', - 'vertical-align': 'middle', -// 'left':'10px', - 'width': '600px', - 'height': '100px', - 'bottom': '0px' - - }); - - // Disable text selection and - // Change the selection mouse pointer - // from text to hand. - this._container.css({ - '-moz-user-select': 'none', - '-webkit-user-select': 'none', - 'user-select': 'none' - }); - - this.paintDNAContentContent(self.opt.dataSet); - - }, - - /** - * Default values for the options - * @name Biojs.DNAContentViewer-opt - */ - opt: { - target: "YourOwnDivId", - dataSet: "", - fontFamily: '"Andale mono", courier, monospace', - fontColor: "white", - backgroundColor: "#7BBFE9", - selectionFontColor: "black", - selectionBackgroundColor: "yellow", - width: "100%", - height: "130", - radius: 10 - }, - - /** - * Array containing the supported event names - * @name Biojs.DNAContentViewer-eventTypes - */ - eventTypes: [ - /** - * No events added for now but can be added in future - */ - ], - - - /** - * Repaints everything: ruler, shapes, and legend. - * @param {boolean} [withoutZoom=false] When false, it zooms according to the slider values. - * @param {int} [newStart] Zoom from this sequence start value. - * @param {int} [newStop] Zoom to this sequence end value. - * - * @example - * instance._updateDraw(); - * - */ - _updateDraw: function (withoutZoom, newStart, newStop) { - //recalculate start and stop - - if (newStart && newStop) { - - this.slider_start += newStart; - this.slider_stop += newStop; - this._calculateContent(this.slider_start, this.slider_stop); - } - else { - this._calculateContent(); - - } - - if (this.slider_start < this.data_first_start) { - if (newStart == newStop) { - this.slider_stop += this.data_first_start - this.slider_start; - } - this.slider_start = this.data_first_start; - - } - - if (this.slider_stop > this.data_last_start) { - if (newStart == newStop) { - this.slider_start += this.data_last_start - this.slider_stop; - } - this.slider_stop = this.data_last_start; - } - - this._paintDNAContentGraph(undefined, this.slider_start, this.slider_stop); - }, - - /** - * Paint the features according to the values specified in the json object defined when creating the object. - * This method initializes the holder, paints the slider and print button depending on the options, and - * paints the features and legend. - * - * @example - * instance.paintDNAContentContent("../biojs/data/DNAContentViewerData.txt"); - * - * @param {string} dataSet Location of the file with the input text file in raw sequence format. - *
ACGACTACGACTAGCATCAGCATCAGCACTAGCATCAGCACTAGCACTAGCACTAGCATCAGCACTAGCACTAGCACTGACACT...
- */ - paintDNAContentContent: function (dataSet) { - if (dataSet != undefined) { - this._setDataSource(dataSet); - this._init(); - } else { - this.$errorMsg = jQuery('
') - .html('There was an unexpected failure, the image cannot be displayed. data is undefined.') - .dialog({ - autoOpen: true, - title: 'Error', - modal: true - }); - throw "Error"; - } - - }, - - /** - * Private: Initializes the component. - */ - _init: function () { - Biojs.DNAContentViewer.myself = this; - //First create the slider, button, and holder - var painter_div = jQuery("#" + this.opt.target); - painter_div.text(''); - painter_div.append(this._withSliderOnly(100)); - - painter_div.append('
'); - - var holder = document.getElementById("DNAContentPainter-holder"); - if (!holder) { - this.$errorMsg = jQuery('
') - .html('There was an unexpected failure, the image cannot be displayed.') - .dialog({ - autoOpen: true, - title: 'Error', - modal: true - }); - throw "Error"; - } - holder.innerHTML = ""; - holder.style.height = "200px"; - holder.style.width = "700px"; - var self = this; - this.width = $("#DNAContentPainter-holder").width(), - this.height = $("#DNAContentPainter-holder").height(), - this.r = self.opt.radius; - - self.opt.width = self.opt.width.toString(); - if (self.opt.width.indexOf("%") != -1) - this.width = this.width * (self.opt.width.substring(0, self.opt.width.length - 1) * 1) / 100.0; - else - this.width = self.opt.width * 1; - self.opt.width = parseInt(this.width); - - self.opt.height = self.opt.height.toString(); - if (self.opt.height.indexOf("%") != -1) - this.height = this.height * (self.opt.height.substring(0, self.opt.height.length - 1) * 1) / 100.0; - else - this.height = self.opt.height * 1; - self.opt.height = parseInt(this.height); - - - self.color = function () { - return d3.scale.ordinal().range(self.colors); - }(); - - d3.text(self.opt.dataSet, function (data, error) { - self.track = data; - var length = data.length - 1; - self._paintLegend(); - self._updateLegend(self._Statsforchunk(self.track)); - self.slider_start = 0; - self.slider_stop = length; - self.data_last_start = length; - self.data_first_start = 0; - - self._paintSlider(); - self._paintMarkersGraph(); - self._updateDraw(); - }); - - }, - - /** - * Private: Function to create slider only. - * @param {int} sizeX Width. - * @ignore - */ - _withSliderOnly: function (sizeX) { - var text = - '' + - '' + - '' + - '' + - '' + - '' + - '
' + - '' + - '' + - '
' + - '
'; - return text; - }, - - - /** - * Private: Function to calculate AT/GC content for given positions. - * @param {string} newStart start position. - * @param {string} newStop stop position. - * @ignore - */ - _calculateContent: function (newStart, newStop) { - var sequence = this.track; - if (newStart && newStop) { - if (newStart < 0) { - newStart = 0; - } - if (newStop > this.slider_stop) { - newStop = this.slider_stop; - } - - sequence = sequence.substring(newStart, newStop) - - } else { - newStart = 0; - } - - var DNAContent_content = [] - var seq_len = sequence.length; - var i = 0; - if (seq_len > 100) { - while (i <= seq_len) { - var chunk = sequence.substr(i, Math.floor(seq_len / 100)); - DNAContent_content.push({start: parseInt(newStart) + parseInt(i), gc_value: this._GCforchunk(chunk), at_value: this._ATforchunk(chunk)}); - i += Math.floor(seq_len / 100); - } - if (i < seq_len) { - var chunk = sequence.substr(i); - DNAContent_content.push({start: parseInt(newStart) + parseInt(i), gc_value: this._GCforchunk(chunk), at_value: this._ATforchunk(chunk)}); - } - } else { - while (i <= seq_len) { - var chunk = sequence.substr(i, 10); - DNAContent_content.push({start: parseInt(newStart) + parseInt(i), gc_value: this._GCforchunk(chunk), at_value: this._ATforchunk(chunk)}); - i += 1; - } - } - - this.max = 100; - this.track_bins = DNAContent_content; - }, - - - - /** - * Private: Function to calculate AT/GC stats for chunk.. - * @param {string} chunk sequence. - * Returns: (int) gc - * @ignore - */ - _Statsforchunk: function (chunk) { - var chunk_array = chunk.split(""); - var gc = 0; - var at = 0; - var ot = 0; - var total = 0; - for (var a = 0; a < chunk_array.length; a++) { - if (chunk_array[a].toLocaleLowerCase() == "g" || chunk_array[a].toLocaleLowerCase() == "c") { - gc++; - } - else if (chunk_array[a].toLocaleLowerCase() == "a" || chunk_array[a].toLocaleLowerCase() == "t") { - at++; - } - else { - ot++; - } - total++; - } - return ({total: total, gc: gc, at: at, ot: ot}); - }, - - - /** - * Private: Function to calculate AT % for chunk. - * @param {string} chunk sequence. - * Returns: (int) gc - * @ignore - */ - _GCforchunk: function (chunk) { - var chunk_array = chunk.split(""); - var gc = 0; - var total = 0; - for (var a = 0; a < chunk_array.length; a++) { - if (chunk_array[a].toLocaleLowerCase() == "g" || chunk_array[a].toLocaleLowerCase() == "c") { - gc++; - } - total++; - } - return gc * 100 / total; - }, - - /** - * Private: Function to calculate AT % for chunk. - * @param {string} chunk sequence. - * Returns: (int) at - * @ignore - */ - _ATforchunk: function (chunk) { - var chunk_array = chunk.split(""); - var at = 0; - var total = 0; - - for (var a = 0; a < chunk_array.length; a++) { - if (chunk_array[a].toLocaleLowerCase() == "a" || chunk_array[a].toLocaleLowerCase() == "t") { - at++; - } - total++; - } - return at * 100 / total; - }, - - - /** - * Private: Paints the slider - * Purpose: set up slider buttons - * Returns: - - * @ignore - */ - _paintSlider: function () {//holder size, left and right margins of the holder, and number of amino acids - var sequenceLength = 100;//config.sequenceLength; - if (!document.getElementById("DNAContentPainter-slider")) { - return; - } - - var slider_div = jQuery("#DNAContentPainter-slider"); - slider_div.text(''); - slider_div.append(''); - slider_div.append('
'); - var self = this; - var diff = parseInt(self.track.length / 100); - this.zoomSlider = jQuery('
').appendTo(slider_div); - - - slider_div.html('Controls:
' + - '
' + - '
' + - '
') - }, - - /** - * Private: Paints the AT/GC Legengd and MArker radio buttons - * Returns: - - * @ignore - */ - _paintLegend: function () {//holder size, left and right margins of the holder, and number of amino acids - var self = this; - - if (!document.getElementById("DNAContentPainter-slider")) { - return; - } - - var slider_div_legend = jQuery("#DNAContentPainter-Legend"); - - slider_div_legend.html('
GC Content
' + - '
AT Content
') - - $("#at_checkbox").change(function () { - self._toggleAT(); - }); - - - $("#gc_checkbox").change(function () { - self._toggleGC(); - }); - - - var marker_legend = jQuery("#Marker-Legend"); - - marker_legend.html('
Marker Position:
Left Centre Right
') - - $(".marker-pos").change(function () { - self._toggleMarker(this); - }); - }, - - /** - * Private: Updates percentage values in AT/GC legends - * Returns: - - * @ignore - */ - _updateLegend: function (stats) {//holder size, left and right margins of the holder, and number of amino acids - - if (!document.getElementById("DNAContentPainter-slider")) { - return; - } - - var at_perc = parseFloat(stats.at * 100 / stats.total).toFixed(2); - var gc_perc = parseFloat(stats.gc * 100 / stats.total).toFixed(2); - - - var gc_perc_div = jQuery("#gc_perc"); - var at_perc_div = jQuery("#at_perc"); - - - gc_perc_div.html(gc_perc + '%') - at_perc_div.html(at_perc + '%') - }, - - - /** - * Private: Draws area chart from DNA string using D3.js - * @param {boolean} [withoutZoom=false] When true, this method recalculates the total for each feature type. - * @param {int} [start=0] When true, this method recalculates the total for each feature type. - * @param {int} [end=max] When true, this method recalculates the total for each feature type. - * @ignore - */ - _paintDNAContentGraph: function (withoutZoom, start, end) { - var self = this; - var left = "50px"; - var top = "0px"; - var filtered_track = this.track_bins; - - // filter data if start and end positions are defined - if (start && end) { - filtered_track = jQuery.grep(self.track_bins, function (element) { - return element.start >= start && element.start <= end; // retain appropriate elements - }); - } - - - var height = this.height; - var width = this.width; - var max = Math.ceil(this.max / 100) * 100 - var length = filtered_track.length - 1; - - var space = parseInt(width) / (filtered_track[length].start - filtered_track[0].start); - - if (length > 0) { - - this._clear(); - - var svg = d3.select("#DNAContentPainter-holder").select("svg") - .append("g") - .attr("width", this.width) - .attr("height", this.height + 30) - .attr("class", "redrawn-path") - .attr("transform", "translate(" + left + "," + top + ")"); - - this._container = jQuery("#DNAContentPainter-holder"); - - var d3line2 = d3.svg.line() - .x(function (d) { - return d.x; - }) - .y(function (d) { - return d.y; - }) - .interpolate("linear"); - - - var gc_pathinfo = []; - var at_pathinfo = []; - - var last_start = 0; - // check for average difference between each positions - var diff = parseInt(filtered_track[1].start - filtered_track[0].start); - - - // loop through each element and calculate x and y axis for chart - for (var i = 0; i < filtered_track.length - 1;) { - - - var gc_tempx, at_tempx; - - if (start) { - gc_tempx = (filtered_track[i].start - start) * space; - at_tempx = (filtered_track[i].start - start) * space; - } else { - gc_tempx = (filtered_track[i].start) * space; - at_tempx = (filtered_track[i].start) * space; - - } - var gc_tempy = height - (filtered_track[i].gc_value * height / max); - var at_tempy = height - (filtered_track[i].at_value * height / max); - gc_pathinfo.push({ x: gc_tempx, y: gc_tempy}); - at_pathinfo.push({ x: at_tempx, y: at_tempy}); - - i++; - - last_start = filtered_track[i].start; - - } - - if (start) { - gc_tempx = (filtered_track[filtered_track.length - 1].start - start) * space; - at_tempx = (filtered_track[filtered_track.length - 1].start - start) * space; - } - - var gc_tempy = height - (filtered_track[filtered_track.length - 1].gc_value * height / max); - var at_tempy = height - (filtered_track[filtered_track.length - 1].at_value * height / max); - - gc_pathinfo.push({ x: gc_tempx, y: gc_tempy}); - at_pathinfo.push({ x: at_tempx, y: at_tempy}); - - var path = svg.selectAll("path") - .data([1]); - - //select 10 positions to be displayed on x axis - var filter_track_legend = []; - for (i = 0; i < filtered_track.length;) { - filter_track_legend.push(filtered_track[i]); - i += parseInt(length / 10); - } - - //draw selected 10 positions as legend - var legendtext = svg.selectAll('text.day') - .data(filter_track_legend); - - legendtext.enter().append('svg:text') - .attr('x', function (d) { - if (start) { - return (d.start - start) * space; - - } else { - return (d.start ) * space; - } - }) - .attr('y', 160) - .attr('text-anchor', 'middle') - .style("font-size", "10px") - .text(function (d) { - if (d.start > 1000000) { - return parseInt(d.start / 1000000) + "M"; - } else if (d.start > 1000) { - return parseInt(d.start / 1000) + "K"; - } else { - return d.start; - } - }); - - //select 10 positions to be displayed on x axis - var marker_legend = []; - - for (i = 1; i <= 10; i++) { - marker_legend.push((max / 10) * i); - - } - - // lines at bottom of diagram to show the positions - var line = svg.selectAll("line.bottom") - .data(filtered_track); - line.enter().insert("svg:line") - .attr("class", "line") - .attr("x1", function (d) { - if (start) { - return (d.start - start) * space; - - } else { - return (d.start ) * space; - } - }) - .attr("y1", 130) - .attr("x2",function (d) { - if (start) { - return (d.start - start) * space; - - } else { - return (d.start ) * space; - } - }).attr("y2", function (d, i) { - return 140; - }) - .attr('stroke', function () { - return "black"; - }); - - var line = svg.selectAll("line.bottom") - .data(filter_track_legend); - line.enter().insert("svg:line") - .attr("class", "line") - .attr("x1", function (d) { - if (start) { - return (d.start - start) * space; - - } else { - return (d.start ) * space; - } - }) - .attr("y1", 130) - .attr("x2",function (d) { - if (start) { - return (d.start - start) * space; - - } else { - return (d.start ) * space; - } - }).attr("y2", function (d, i) { - return 150; - }) - .attr('stroke', function () { - return "black"; - }); - - - var line_base = svg.selectAll("line.bottom") - .data([1]); - line_base.enter().insert("svg:line") - .attr("class", "line base") - .attr("x1", function (d) { - - return 0; - }) - .attr("y1", function (d) { - return height; - }) - .attr("x2",function (d) { - return width; - }).attr("y2", function (d) { - return height; - }) - .attr('stroke', function () { - return "black"; - }); - - - //draw path from calculated chart axis - path.enter().append("svg:path") - .attr("width", 200) - .attr("height", 200) - .attr("class", "path gc-path") - - .attr('stroke', function () { - return "blue"; - }) - .attr('stroke-width', function () { - return "2px"; - }) - .attr("fill", function () { - return "transparent"; - }) - .attr("d", d3line2(gc_pathinfo)); - - - //draw path from calculated chart axis - path.enter().append("svg:path") - .attr("width", 200) - .attr("height", 200) - .attr("class", "path at-path") - - .attr('stroke', function () { - return "red"; - }) - .attr('stroke-width', function () { - return "2px"; - }) - .attr("fill", function () { - return "transparent"; - }) - .attr("d", d3line2(at_pathinfo)); - } - }, - - /** - * Private: Draws percentage markers using D3.js - * @ignore - */ - _paintMarkersGraph: function () { - var left = "50px"; - var top = "0px"; - var height = this.height; - var width = this.width; - var max = 100 - - - this._clear(); - - var svg = d3.select("#DNAContentPainter-holder").append("svg") - .style("overflow", "visible") - .append("g") - .attr("class", "marker-base") - .attr("width", this.width) - .attr("height", this.height + 30) - .attr("transform", "translate(" + left + "," + top + ")"); - - this._container = jQuery("#DNAContentPainter-holder"); - - - //select 10 positions to be displayed on x axis - var marker_legend = []; - - for (var i = 1; i <= 10; i++) { - marker_legend.push((max / 10) * i); - - } - - - var markertext = svg.selectAll('text.marker') - .data(marker_legend); - - markertext.enter().append('svg:text') - .attr("class", "text marker") - .attr('x', function (d) { - return 10; - }) - .attr('y', function (d) { - return height - (d * height / max) + parseInt(5); - }) - .attr('text-anchor', 'begin') - .style("font-size", "10px") - .text(function (d, i) { - return ((i + 1) * 10) + "%"; - }); - - // lines at bottom of diagram to show the positions - var marker = svg.selectAll("tick.marker") - .data(marker_legend); - marker.enter().insert("svg:line") - .attr("class", "tick tickmarker") - .attr("x1", function (d) { - return 0; - }) - .attr("y1", function (d) { - return height - (d * height / max); - }) - .attr("x2",function (d) { - return 5; - }).attr("y2", function (d) { - return height - (d * height / max); - }) - .attr('stroke', function () { - return "black"; - }); - - var marker_base = svg.selectAll("line.bottom") - .data([1]); - marker_base.enter().insert("svg:line") - .attr("class", "line marker base") - .attr("x1", function (d) { - return 1; - }) - .attr("y1", function (d) { - return 0; - }) - .attr("x2",function (d) { - return 1; - }).attr("y2", function (d) { - return height; - }) - .attr('stroke', function () { - return "black"; - }); - }, - - /** - * Private: Paints the slider - * Purpose: set up slider buttons - * Returns: - - * @ignore - */ - _toggleAT: function () {//holder size, left and right margins of the holder, and number of amino acids - if (jQuery(".at-path").css('display') == 'none') { - jQuery(".at-path").show(); - } else { - jQuery(".at-path").hide(); - } - }, - - /** - * Private: Paints the slider - * Purpose: set up slider buttons - * Returns: - - * @ignore - */ - _toggleGC: function () {//holder size, left and right margins of the holder, and number of amino acids - - if (jQuery(".gc-path").css('display') == 'none') { - jQuery(".gc-path").show(); - } else { - jQuery(".gc-path").hide(); - } - }, - - /** - * Private: Paints the slider - * Purpose: set up slider buttons - * Returns: - - * @ignore - */ - _toggleMarker: function (self) {//holder size, left and right margins of the holder, and number of amino acids - console.log(self) - var svg = d3.select("#DNAContentPainter-holder") - var width = this.width; - var marker = svg.selectAll("line.marker"); - var marker_text = svg.selectAll("text.marker"); - var marker_tick = svg.selectAll("line.tick"); - - if (self.value == "left") { - marker.transition() - .duration(500) - .attr("x1", function (d) { - return 1; - }) - .attr("x2", function (d) { - return 1; - }); - - marker_text.transition() - .duration(500) - .attr('text-anchor', 'begin') - .attr('x', function (d) { - return 10; - }); - - marker_tick.transition() - .duration(500) - .attr("x1", function (d) { - return 0; - }) - .attr("x2", function (d) { - return 5; - }) - } else if (self.value == "centre") { - marker.transition() - .duration(500) - .attr("x1", function (d) { - return width / 2; - }) - .attr("x2", function (d) { - return width / 2; - }); - - marker_text.transition() - .duration(500) - .attr('text-anchor', 'begin') - .attr('x', function (d) { - return parseInt(width / 2) + parseInt(10); - }); - - marker_tick.transition() - .duration(500) - .attr("x1", function (d) { - return width / 2; - }) - .attr("x2", function (d) { - return parseInt(width / 2) + parseInt(5); - }) - } else { - marker.transition() - .duration(500) - .attr("x1", function (d) { - return width; - }) - .attr("x2", function (d) { - return width; - }); - - marker_text.transition() - .duration(500) - .attr('text-anchor', 'end') - .attr('x', function (d) { - return parseInt(width) - parseInt(10); - }); - - marker_tick.transition() - .duration(500) - .attr("x1", function (d) { - return (width - 5); - }) - .attr("x2", function (d) { - return width; - }) - } - }, - - /** - * Private: Clears all divs content. - * @ignore - */ - _clear: function () { - d3.select("#DNAContentPainter-holder").select("svg").select("g.redrawn-path").remove(); - }, - - /** - * Private: sets data source. - * @param {string} [dataset], it sets file path to this.opt.dataset. - * @ignore - */ - _setDataSource: function (dataSet) { - this.opt.dataSet = dataSet; - }, - - _addSimpleClickTrigger: function () { - - var self = this; - - // Add the click event to each character in the content - this._container.find('span') - .click(function (e) { - // A letter was clicked! - // Let's discover which one was it - // TIP: e.target contains the clicked DOM node - var selected = jQuery(e.target).text(); - - // Create an event object - var evtObject = { "selected": selected }; - - // We're ready to raise the event onClick of our component - self.raiseEvent('onClick', evtObject); - }); - } - - - }, { - myself: undefined - }); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.DasProteinFeatureViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.DasProteinFeatureViewer.js deleted file mode 100755 index 4923bdbc91..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.DasProteinFeatureViewer.js +++ /dev/null @@ -1,341 +0,0 @@ -/** - * This component uses a DASProtein web service that builds the JSON data object used by FatureViewer component. - * - * @class - * @extends Biojs.FeatureViewer - * - * @author Leyla Jael Garcia Castro - * @version 1.0.0 - * @category 2 - * - * - * @param {Object} options An object with the options for DASProteinFeatureViewer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {boolean} [showSlider=true] - * Should the slider for zooming be displayed? - * - * @option {boolean} [showPrintButton=true] - * Should the button for printing/exporting to image be displayed? - * - * @option {boolean} [showFeatureTooltipOnMouseOver=true] - * Should the tooltip for features be displayed? - * - * @option {boolean} [highlightFeatureOnMouseOver=true] - * Should the features be highlighted when mouse over? - * - * @option {boolean} [selectFeatureOnMouseClick=true] - * Should the features remain highlighted, i.e. being selected, after a mouse click, - * and deselected after a second click or whenever other feature is selected? - * - * @option {boolean} [dragSites=true] - * Should the sites be draggable? - * - * @option {string} segment - * Protein identifier or protein accession - * - * @option {string} [dasSources="http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot"] - * DAS protein sources used to retrieved the features, if another one is needed, just add something like ",URL" - * - * @option {string} featureTypes - * In case of more than one source, it is possible to specify only one of them to retrieve a particular feature type. - * For instance "feature.DOMAIN=http://www.ebi.ac.uk/das-srv/interpro/das/InterPro-matches-overview", for more - * types just add something like "&feature.XXX=URL" - * Feature type should be capitalized and can be any of these: DOMAIN, CA_BIND, DNA_BIND, NP_BIND, INTRAMEM, TOPO_DOM, TRANSMEM, ZN_FING, PEPTIDE, - * PROPEP, SIGNAL, TRANSIT, ACT_SITE, METAL, CARBOHYD, LIPID, MOD_RES, COILED, COMPBIAS, CONSERVED_MOTIF, REGION, - * REPEAT, CHAIN, INIT_MET, BINDING, SITE, NON_STD, DISULFID, CROSSLINK, VAR_SEQ, VARIANT, MUTAGEN, UNSURE, - * CONFLICT, NON_CONS, NON_TER, HELIX, TURN, STRAND - * - * @option {string} featureNames - * Feature names are displayed as part of the legend. In case you want to modify the text associated to a feature - * type, you can use this option. For instance name.DOMAIN=Family domains, for more names just add something like - * "&name.XXX=any text" - * Feature type should be capitalized and can be any of these: DOMAIN, CA_BIND, DNA_BIND, NP_BIND, INTRAMEM, TOPO_DOM, TRANSMEM, ZN_FING, PEPTIDE, - * PROPEP, SIGNAL, TRANSIT, ACT_SITE, METAL, CARBOHYD, LIPID, MOD_RES, COILED, COMPBIAS, CONSERVED_MOTIF, REGION, - * REPEAT, CHAIN, INIT_MET, BINDING, SITE, NON_STD, DISULFID, CROSSLINK, VAR_SEQ, VARIANT, MUTAGEN, UNSURE, - * CONFLICT, NON_CONS, NON_TER, HELIX, TURN, STRAND - * - * @option {int} [imageWidth=700] - * Image width - * - * @option {string} [imageStyle="nonOverlapping"] - * Image style, a value from {nonOverlapping, centered, rows} - * - * @option {boolean} [hgrid=false] - * Should horizontal lines be shown? - * - * @option {boolean} [vgrid=false] - * Should vertical lines be shown? - * - * @option {boolean} [allFeatures=true] - * Should all feature types be displayed? or only those defined by default? - * Default feature types: DOMAIN, CA_BIND, DNA_BIND, NP_BIND, INTRAMEM, TOPO_DOM, TRANSMEM, ZN_FING, PEPTIDE, - * PROPEP, SIGNAL, TRANSIT, ACT_SITE, METAL, CARBOHYD, LIPID, MOD_RES - * Other features that will be displayed if allFeatures is true: COILED, COMPBIAS, CONSERVED_MOTIF, REGION, - * REPEAT, CHAIN, INIT_MET, BINDING, SITE, NON_STD, DISULFID, CROSSLINK, - * VAR_SEQ, VARIANT, MUTAGEN, UNSURE, CONFLICT, NON_CONS, NON_TER, HELIX, TURN, STRAND - * - * @option {boolean} [allRectangles=false] - * Should all features, including those involving just one amino acid be displayed as rectangles? - * If not, some predefined features will be use for ACT_SITE, METAL, CARBOHYD, LIPID, MOD_RES - * - * @option {boolean} [allSameSize=false] - * If "centered" is the image style option, should all rectangles have the same size? - * - * @option {string} [proxyUrl="../biojs/dependencies/proxy/proxy.php"] - * Server side proxy server. - * - * @example - * var myPainter = new Biojs.DasProteinFeatureViewer({ - * target: "YourOwnDivId", - * segment: "a4_human" - * }); - * - */ -Biojs.DasProteinFeatureViewer = Biojs.FeatureViewer.extend( - /** @lends Biojs.DasProteinFeatureViewer */ - { - /* - * Private variables - */ - _webservice:"http://wwwdev.ebi.ac.uk/uniprot/featureViewer/image", - _dasReference:"http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/", - /** - * Default values for the options - * @name Biojs.DasProteinFeatureViewer-constructor - */ - constructor:function (options) { - this.base(options); - var self = this; - //Biojs.console.enable(); - //create params from options - var params = "?"; - params = params + "&option=raphael"; - if (!Biojs.Utils.isEmpty(options.segment)) { - params = params + "&segment=" + options.segment; - } else { - throw "A UniProt accession or identifier is mandatory"; - } - if (!Biojs.Utils.isEmpty(options.dasSources)) { - params = params + "&dasSources=" + options.dasSources; - } - if (!Biojs.Utils.isEmpty(options.featureTypes)) { - params = params + "&" + options.featureTypes; - } - if (!Biojs.Utils.isEmpty(options.featureNames)) { - params = params + "&" + options.featureNames; - } - if ((options.imageWidth != undefined) && (!isNaN(options.imageWidth))) { - params = params + "&width=" + options.imageWidth; - } - if (!Biojs.Utils.isEmpty(options.imageStyle)) { - params = params + "&style=" + options.imageStyle; - } - if ((options.hgrid != undefined) && (options.hgrid == true)) { - params = params + "&hgrid"; - } - if ((options.vgrid != undefined) && (options.vgrid == true)) { - params = params + "&vgrid"; - } - if ((options.allFeatures != undefined) && (options.allFeatures == true)) { - params = params + "&allFeatures"; - } - if ((options.allRectangles != undefined) && (options.allRectangles == true)) { - params = params + "&allRectangles"; - } - if ((options.allSameSize != undefined) && (options.allSameSize == true)) { - params = params + "&allSameSize"; - } - //complete parent options with defaults defined by the children - this.opt.json = ""; - //Biojs.console.log("params: " + params); - //get the json from the web service - jQuery.ajax({ - //url:this._webservice + params, - url: self.opt.proxyUrl, - data: "url=" + this._webservice + params, - success:function (response, callOptions) { - json = jQuery.parseJSON(response); - //Biojs.console.log(response); - //Biojs.console.log(json); - try { - self.opt.json = json; - //jQuery.noConflict(); - //self.initRaphael(); - if (!Biojs.Utils.isEmpty(self.opt.json)) { - self.paintFeatures(self.opt.json) - } - } catch (err) { - Biojs.console.log(err); - document.getElementById(self.opt.target).innerHTML = ''; - document.getElementById(self.opt.target).innerHTML = 'No image available. Did you provide a valid UniProt accession or identifier, and valid limits?'; - } - }, - error:function (response, callOptions) { - Biojs.console.log(error); - document.getElementById(self.opt.target).innerHTML = ''; - document.getElementById(self.opt.target).innerHTML = 'No image available. Did you provide a valid UniProt accession or identifier, and valid limits?'; - } - }); - }, - - /** - * Default values for the options: - * target: "", - * segment: "", - * showSlider: true, - * showPrintButton: true, - * showFeatureTooltipOnMouseOver: true, - * highlightFeatureOnMouseOver: true, - * selectFeatureOnMouseClick: true, - * dragSites: true //beware that dragging implies a click on so the click event will be raised! - * selectionColor: "#ff8c00" - * dasSources: "http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot", - * featureTypes: "", - * featureNames: "", - * imageWidth: 700, - * imageStyle: "nonOverlapping", - * optionResponse: "raphael", - * hgrid: false, - * vgrid: false, - * allFeatures: true, - * allRectangles:false, - * allSameSize: false, - * proxyUrl: "../biojs/dependencies/proxy/proxy.php" - * @name Biojs.DasProteinFeatureViewer-opt - */ - opt:{ - //Parent - /* target:"YourOwnDivId", - //json: {}, //is not an option here, it is fixed to _webservice response - showSlider:true, - showPrintButton:true, - showFeatureTooltipOnMouseOver:true, - highlightFeatureOnMouseOver:true, - selectFeatureOnMouseClick:true, - dragSites:true, - selectionColor:"#ff8c00", //make sure it does not exist at http://wwwdev.ebi.ac.uk/das-srv/uniprot/das/uniprot/stylesheet - */ - dasSources:"http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot", - featureTypes:"", - featureNames:"", - imageWidth:700, - imageStyle:"nonOverlapping", - optionResponse:"raphael", - hgrid:false, - vgrid:false, - allFeatures:true, - allRectangles:false, - allSameSize:false, - proxyUrl: "../biojs/dependencies/proxy/proxy.php" - }, - - /** - * Array containing the supported event names - * @name Biojs.DasProteinFeatureViewer-eventTypes - */ - eventTypes : [], - - /** - * Opens a new window/tab in the browser with the graphical representation for all feature types. - * - * @example - * myPainter.showGeneralLegend(); - * - */ - showGeneralLegend: function() { - var config = this.opt.json.configuration; - var dataURL = this._webservice + "?"; - window.open(dataURL); //open generated image in new tab/window - }, - - /** - * Opens a new window/tab in the browser with the graphical representation as a plain image. - * Note: For IE it does not reflect the drags/drops on sites - * - * @example - * myPainter.exportFeaturesToImage(); - * - */ - exportFeaturesToImage: function() { -// if (typeof FlashCanvas != "undefined") { -// FlashCanvas.initElement(canvas); -// } - var config = this.opt.json.configuration; - var dataURL = ""; - if (jQuery.browser.msie) { //canvas does not work (not even with IE 9) - var arguments = "segment=" + this.opt.json.segment; - if ((config.requestedStart != 0) && (config.requestedStop != 0)) { - arguments = arguments + ":" + config.requestedStart + "," + config.requestedStop; - } - arguments = arguments + - "&dasReference=" + config.dasReference + - "&dasSources=" + config.dasSources + - "&width=" + config.sizeX + - "&option=image" + - "&hgrid=" + config.horizontalGrid + - "&vgrid=" + config.verticalGrid + - "&style=" + config.style; - dataURL = this._webservice + "?" + arguments; - window.open(dataURL); //open generated image in new tab/window - } else { - svg = document.getElementById('uniprotFeaturePainter-holder').innerHTML; - var canvas = document.createElement("canvas"); - canvg(canvas, svg); - dataURL = canvas.toDataURL(); - this.$imageExported = jQuery('
') - .html('exported image') - .dialog({ - autoOpen: true, - title: 'Exported image', - modal: true, - width: config.sizeX+20 - }); - } - }, - - /** - * Applies a style, either "centered", "nonOverlapping", or "rows". - * @param show - * - * @example - * myPainter.applyStyle("centered"); - */ - applyStyle: function(style) { - if ((style != undefined) && ((style == "centered") || (style == "nonOverlapping") || (style = "rows"))) { - var config = this.opt.json.configuration; - this.customize(style, config.horizontalGrid, config.verticalGrid); - } - }, - - /** - * Shows/hide the horizontal guide lines. - * @param show - * - * @example - * myPainter.showHideHorizontalGrid(true); - */ - showHideHorizontalGrid: function(show) { - if ((show != undefined) && ((show == true) || (show == false))) { - var config = this.opt.json.configuration; - this.customize(config.style, show, config.verticalGrid); - } - }, - - /** - * Shows/hide the horizontal guide lines. - * @param show - * - * @example - * myPainter.showHideVerticalGrid(true); - */ - showHideVerticalGrid: function(show) { - if ((show != undefined) && ((show == true) || (show == false))) { - var config = this.opt.json.configuration; - this.customize(config.style, config.horizontalGrid, show); - } - } - } -); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.DetailsFrame.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.DetailsFrame.js deleted file mode 100755 index f65109707c..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.DetailsFrame.js +++ /dev/null @@ -1,171 +0,0 @@ -/** - * This component creates a floating div as a pop-up window to visualize a list of annotations on an entity. - * Eg. Protein, Interaction, Gene, etc - * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires Details frame CSS - * @dependency - * - * @param {Object} options An object with the options for the Details Frame component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {object} features - * Object with the features to display, every attribute is displayed as an item in the list. - * The attribute id, is used for the title of the frame. - * The attribute description has a different style at the beggining of the list - * - * @option {boolean} [minizable=true] - * to indicate if the window is minizable. default value: true - * - * @option {boolean} [draggable=true] - * to indicate if the window can be draggable. default value: true - * - * @example - * var instance = new Biojs.DetailsFrame({ - * target: "YourOwnDivId", - * features: { - * "id":"P64747", - * "description":"Uncharacterized protein Rv0893c/MT0917","Gene-Name":"Rv0893c", - * "%GC":" 60.63", - * "Location":" Unknown", - * "Chrom-Location":" 946", - * "Strand-Direction":" -1", - * "Cordon-Bias":" 0.07692", - * "Funct-Class":" unknown", - * "Degree":" 15", - * "Betweenness":" 784.68", - * "Closeness":" 0.24790", - * "Eigen":" 0.00003", - * "Hub":" N", - * "Sass-Infect":" 0", - * "Sass-Growth":" 0", - * "GO-Growth":" 0", - * "TDR":" 0", - * "UniProt":" 0", - * "DDTRP":" 0", - * "Gas-Nic":" 0", - * "#-Paralogs":" 11", - * "Mtb-cplx":" 11", - * "Mtb":" 7", - * "Corynebacterineae":" 0", - * "Actinomycetales":" 0", - * "Actinobacteridae":" 0", - * "Bacteria":"0", - * "Non-bacteria":"0", - * "H.sapiens":"0", - * "in_leprae":"0", - * "DN/DS":"0.48", - * "Codon-Volatility":"0.1" - * } - * }); - * - */ -Biojs.DetailsFrame = Biojs.extend ( -/** @lends Biojs.DetailsFrame# */ -{ - constructor: function (options) { - var self=this; - var target =self.opt.target; - var html = ''; - if (self.opt.minizable) - html += '
'; - if (self.opt.draggable) - html += '
'; - html += '
'; - html += '
    '; - $("#"+target).addClass("protein"); - $("#"+target).append(html); - self.updateFeatures(); - if (self.opt.minizable) - $("#"+target+" .minimize").click(function(){ - if ($("#"+target+" ul").css('display') == "none"){ - $("#"+target+" ul").show(); - $(this).removeClass("minimized"); - $(this).addClass("to_minimize"); - }else{ - $("#"+target+" ul").hide(); - $(this).removeClass("to_minimize"); - $(this).addClass("minimized"); - } - }); - if (self.opt.draggable){ - $("#"+target).draggable({cursor:"move",cancel: "ul"}); - } - }, - - /** - * Default values for the options - * @name Biojs.DetailsFrame-opt - */ - opt: { - target: "YourOwnDivId", - features: { "id":"Not loaded" }, - minizable:true, - draggable:true - }, - - /** - * Array containing the supported event names - * @name Biojs.DetailsFrame-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.DetailsFrame#onFeaturesUpdated - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * It gets activated when the features of the frame have been updated - * - * @example - * instance.onFeaturesUpdated(function( objEvent ) { - * alert("Features have been updated!"); - * }); - */ - "onFeaturesUpdated" - ], - - /** - * The content of the frame can be changed by using this method. - * - * @param {Object} details An object with the features to display in the Details Frame component. - * @example - * instance.updateFeatures({id:"newId",description:"new description",newFeature:"its value",otherFeature:"another value"}); - * - */ - updateFeatures: function(features,order){ - var self=this; - if (typeof features != "undefined") - self.opt.features = features; - $("#"+self.opt.target+" header").html(self.opt.features.id); - var html = ''; - if (typeof self.opt.features["description"] != "undefined") - html += '
  • '+self.opt.features["description"]+'

  • '; - if (typeof order == "undefined") - for (var i in self.opt.features){ - if ((i!="description") && (i!='id')) - html += '
  • '+i+':'+self.opt.features[i]+'
  • '; - } - else - for (var i=0; i'+self.opt.features[order[i]]+''; - } - $("#"+self.opt.target+" ul").html(html); - self.raiseEvent('onFeaturesUpdated', {}); - } -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.EbiGlobalSearch.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.EbiGlobalSearch.js deleted file mode 100755 index ac7a29e79d..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.EbiGlobalSearch.js +++ /dev/null @@ -1,399 +0,0 @@ -/** - * EBI Global Search - * - * @class - * @extends Biojs - * - * @author Rafael C Jimenez - * @version 1.0.0 - * @category 2 - * - * @requires jQuery Core 1.8.0 - * @dependency - * - * @requires ebi-visual.css - * @dependency - * - * @requires EbiGlobalSearch.css - * @dependency - * - * @param {Object} options Component options - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed - * - * @option {string} query [query='keratin'] - * Query to retrieve EBI search results - * - * @option {string} [searchBaseURL='www.ebi.ac.uk/ebisearch/'] - * Base URL of the REST service which provides the data - * - * @option {string} [style='basic'] - * Options to display this component: basic, collapsible or expanded - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * Proxy to bypass the same origin policy ({@link http://en.wikipedia.org/wiki/Same_origin_policy}) - * - * @example - * var instance = new Biojs.EbiGlobalSearch({ - * target: 'YourOwnDivId', - * query: 'p53', - * searchBaseURL: 'http://www.ebi.ac.uk/ebisearch/', - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * style: 'expanded' // basic | collapsible | expanded - * }); - * - */ -Biojs.EbiGlobalSearch = Biojs.extend( -/** @lends Biojs.EbiGlobalSearch# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - this.setQuery(this.opt.query); - }, - - /** - * Default values for the options - * @name Biojs.EbiGlobalSearch-opt - */ - opt: { - target: "YourOwnDivId", - query: undefined, - searchBaseURL: 'http://www.ebi.ac.uk/ebisearch/', - style: 'collapsible', - proxyUrl: '' - }, - - /** - * Set query for the service. - * @param {string} query Query. - * @param {string} style Style: 'basic', 'collapsible' or 'expanded'. - * - * @example - * instance.setQuery("ENSG00000100867"); - * - * @example - * instance.setQuery("Q61171"); - * - * @example - * instance.setQuery("actin"); - * - * @example - * instance.setQuery("keratinnn"); - * - */ - setQuery: function(query, style){ - this._completedRequest = false; - if(typeof style != 'undefined'){ - this.opt.style = style; - } - if (typeof query != 'undefined') { - this.opt.query = query; - this._drawTemplate(); - if(this.opt.style != Biojs.EbiGlobalSearch.VIEW_COLLAPSIBLE){ - this._updateSummary(); - } - } else { - var message = "ERROR: Query error: " + Biojs.EbiGlobalSearch.QUERY_ERROR_UNDEFINED; - Biojs.console.log(message); - this.raiseEvent( Biojs.EbiGlobalSearch.EVT_ON_ERROR, { message: message} ); - } - }, - - /** - * Test styles for the service. - * @param {string} style Style: 'basic', 'collapsible' or 'expanded'. - * - * @example - * instance.setStyle('basic'); - * - * @example - * instance.setStyle('collapsible'); - * - * @example - * instance.setStyle('expanded'); - */ - setStyle: function(style){ - this.setQuery(this.opt.query, style); - }, - - - /* - * Function: Biojs.EbiGlobalSearch._updateSummary - * Purpose: It handles the request - * Returns: - - * Inputs: - - */ - _updateSummary: function() { - var self = this; - var url = this.opt.searchBaseURL+"globalsearchsummary.ebi?query="+this.opt.query; - if(self.opt.proxyUrl != ""){ - url = self.opt.proxyUrl + "?url=" + url; - } - jQuery.ajax({ - url: url, - context: this, - dataType: "json" - //crossDomain: true //Does not work in IE - }).done(function( response ) { - Biojs.console.log("SUCCESS: data received"); - self._completedRequest = true; - self._drawResults(response) - }).fail(function(jqXHR, textStatus) { - var errorMessage = "ERROR: Request failed: " + textStatus; - if(this.opt.query == ""){ - errorMessage = errorMessage + ": Empty query"; - } - Biojs.console.log(errorMessage); - self.raiseEvent( - Biojs.EbiGlobalSearch.EVT_ON_ERROR,{ "message": errorMessage} - ); - self._drawResults(errorMessage); - }); - }, - - - /* - * Function: Biojs.EbiGlobalSearch._updateSummary - * Purpose: It handles the request - * Returns: - - * Inputs: ul -> {object} ul jquery element. - * end -> {object} One item result. - */ - _renderItem: function(ul, item) { - jQuery( "
  • " ) - .append( jQuery( "" ).attr("href", this.opt.searchBaseURL+item.url) - .text( item.name + " ("+item.numberOfResults+")" ) - ).appendTo( ul ); - }, - - /* - * Function: Biojs.EbiGlobalSearch._updateSummary - * Purpose: It handles the request - * Returns: - - * Inputs: response -> {object} Results from the service. - * ul -> {object} ul jquery element. - */ - _renderItems: function(response, ul) { - var self = this; - var totalNumberOfResults = 0; - var totalNumberOfServices = 0; - var totalNumberOfServicesWithResults = 0; - jQuery.each(response, function(index, item) { - totalNumberOfServices++; - if(item.numberOfResults != 0){ - self._renderItem(ul, item); - totalNumberOfResults += parseInt(item.numberOfResults); - totalNumberOfServicesWithResults++; - } - }); - /* display "No results" */ - if(totalNumberOfResults == 0){ - var noResultsMessage = "No results for \""+this.opt.query+"\""; - var search_extras = jQuery("#" + Biojs.EbiGlobalSearch.SEARCH_EXTRAS); - search_extras.find("ul").css("display", "none"); - search_extras.find("p").text(noResultsMessage); - } - /* raise event with number of results */ - this.raiseEvent( - Biojs.EbiGlobalSearch.EVT_ON_RESULTS, - { "resutls" : totalNumberOfResults, "services" : totalNumberOfServices, "servicesWithResults" : totalNumberOfServicesWithResults, "items" : response } - ); - - - }, - - - /* - * Function: Biojs.EbiGlobalSearch._drawTemplate - * Purpose: Draw template - * Returns: - - * Inputs: - - */ - _drawTemplate: function(){ - /* BASIC style */ - if(this.opt.style.toLowerCase() == Biojs.EbiGlobalSearch.VIEW_BASIC){ - var thisElem = jQuery("#" + this.opt.target); - thisElem.html(""); - var search_extras = jQuery(""); - search_extras.appendTo(thisElem); - search_extras.removeClass("shortcuts"); - search_extras.text("Loading other results"); - search_extras.addClass("loading"); - - /* COLLAPSIBLE style */ - } else if (this.opt.style.toLowerCase() == Biojs.EbiGlobalSearch.VIEW_COLLAPSIBLE) { - var self = this; - var thisElem = jQuery("#" + this.opt.target); - thisElem.html(""); - var search_extras = jQuery(""); - search_extras.appendTo(thisElem); - search_extras.addClass("shortcuts expander"); - var ebi_search_results = jQuery("
    "); - ebi_search_results.appendTo(search_extras); - var h3 = jQuery("

    Show more data from EMBL-EBI

    "); - h3.addClass("slideToggle icon icon-functional"); - h3.appendTo(ebi_search_results); - - jQuery('#ebi_search_results .slideToggle[data-icon="u"]').next().hide(); - jQuery("#ebi_search_results .slideToggle").click(function() { - jQuery(this).attr("data-icon") === 'u' ? jQuery(this).attr("data-icon", "w") : jQuery(this).attr("data-icon", "u"); - if (jQuery(this).attr("data-icon") === 'w') { - if(self._completedRequest != true){ - h3.addClass("loading"); - self._updateSummary(); - } - } - jQuery(this).parent().find("p").slideToggle(300); - jQuery(this).parent().find("ul").slideToggle(300); - }); - - /* EXPANDED style or any other style selected */ - } else { - var thisElem = jQuery("#" + this.opt.target); - thisElem.html(""); - var search_extras = jQuery(""); - search_extras.appendTo(thisElem); - search_extras.addClass("shortcuts"); - var ebi_search_results = jQuery("
    "); - ebi_search_results.appendTo(search_extras); - var h3 = jQuery("

    More data from EMBL-EBI

    "); - h3.addClass("loading"); - h3.appendTo(ebi_search_results); - } - }, - - - /* - * Function: Biojs.EbiGlobalSearch._drawResults - * Purpose: Draw results - * Returns: - - * Inputs: response -> {object} Results from the service. - */ - _drawResults: function(response){ - var self = this; - - /* BASIC style */ - if(this.opt.style.toLowerCase() == Biojs.EbiGlobalSearch.VIEW_BASIC){ - var search_extras = jQuery("#" + Biojs.EbiGlobalSearch.SEARCH_EXTRAS); - search_extras.html(""); - search_extras.removeClass("loading"); - search_extras.append("

    EBI global search results

    "); - //container.blink({delay: 500}); - if(typeof response != "string"){ - /* Print results */ - var ul = jQuery("
      ").appendTo(search_extras); - self._renderItems(response, ul); - } else { - /* Print error response */ - jQuery("

      "+response+"

      ").appendTo(search_extras); - } - - - - /* COLLAPSIBLE style */ - } else if (this.opt.style.toLowerCase() == Biojs.EbiGlobalSearch.VIEW_COLLAPSIBLE) { - var self = this; - var ebi_search_results = jQuery("#" + Biojs.EbiGlobalSearch.EBI_SEARCH_RESULTS); - jQuery(ebi_search_results).find("h3").removeClass("loading"); - jQuery(ebi_search_results).find("ul").remove(); - jQuery(ebi_search_results).find("p").remove(); - if(typeof response != "string"){ - /* Print results */ - var p = jQuery("

      Other results for \"" + this.opt.query + "\"

      "); - p.appendTo(ebi_search_results); - var ul = jQuery("
        "); - ul.attr("id", "global-search-results"); - ul.appendTo(ebi_search_results); - self._renderItems(response, ul); - } else { - /* Print error response */ - jQuery("

        "+response+"

        ").appendTo(ebi_search_results); - } - - /* EXPANDED style or any other style selected */ - } else { - var ebi_search_results = jQuery("#" + Biojs.EbiGlobalSearch.EBI_SEARCH_RESULTS); - jQuery(ebi_search_results).find("h3").removeClass("loading"); - if(typeof response != "string"){ - /* Print results */ - var p = jQuery("

        Other results for \"" + this.opt.query + "\"

        "); - p.appendTo(ebi_search_results); - var ul = jQuery("
          "); - ul.attr("id", "global-search-results"); - ul.appendTo(ebi_search_results); - self._renderItems(response, ul); - } else { - /* Print error response */ - jQuery("

          "+response+"

          ").appendTo(ebi_search_results); - } - } - - - - }, - - /** - * Array containing the supported event names - * @name Biojs.EbiGlobalSearch-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.EbiGlobalSearch#onError - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - **/ - "onError", - - - /** - * @name Biojs.EbiGlobalSearch#onResults - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {int} resutls Number of total results. - * @eventData {int} items Number of items. - * @example - * instance.onResults( - * function( objEvent ) { - * alert( objEvent.resutls + " results for " + objEvent.servicesWithResults + " services of " + objEvent.services + " services queried" ); - * } - * ); - * - **/ - "onResults" - ] - - - -},{ - // Some static values - - // Query errors - QUERY_ERROR_UNDEFINED: "Query undefined", - QUERY_ERROR_USER_MESSAGE: "Sorry, we could not process your request", - - // Events - EVT_ON_ERROR: "onError", - EVT_ON_RESULTS: "onResults", - - // IDs - EBI_SEARCH_RESULTS: 'ebi_search_results', - SEARCH_EXTRAS: 'search-extras', - - //views - VIEW_BASIC: 'basic', - VIEW_COLLAPSIBLE: 'collapsible', - VIEW_EXPANDED: 'expanded' - - - -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionAtlasBaselineSummary.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionAtlasBaselineSummary.js deleted file mode 100755 index 07958fb2c9..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionAtlasBaselineSummary.js +++ /dev/null @@ -1,231 +0,0 @@ -/** - * This is the ExpressionAtlas component for displaying baseline expression of genes - * based on RNA-seq experiments in the ExpressionAtlas database. - * - * @class - * @extends Biojs - * - * @author
          ExpressionAtlas Team - * @version 1.0.3 - * @category 3 - * - * @requires jQuery Core 1.9.1 - * @dependency - * - * @param {Object} options An object with the options for ExpressionAtlasBaselineSummary component. - * - * @option {string} [featuresUrl='http://www.ebi.ac.uk/gxa/widgets/heatmap/protein'] - * The query URL pointing to the ExpressionAtlas for retrieving gene page results - * displayed as part of this widget. It is usually composed to include the identifier - * of the gene you are interested in, see example. - * - * @option {string} geneQuery - * ENSEMBL gene ids or UniProt ids. If more than one identifier follow this format "P00846+P99999" - * - * @option {string} [propertyType=''] - * To narrow to search scope of a query term, please provide a type. - * - * @option {string} [geneSetMatch=false] - * If true collapse multiple returned gene profiles into one single line of average expression. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [rootContext='../biojs/dependencies/proxy/proxy.php?url%3dhttp://www.ebi.ac.uk/gxa'] - * Specifies the root context path to be used by the widget content, - * i.e. this is the location of the content proxy pointing to ExpressionAtlas - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * This component needs to request data from a web service. To bypass the same origin policy - * (http://en.wikipedia.org/wiki/Same_origin_policy) this component needs a proxy. - * You could use your own proxy by modifying this value or one of the BioJS proxies: - * '../biojs/dependencies/proxy/proxy.php' or '../biojs/dependencies/proxy/proxy.jsp' - * - * @example - * var instance = new Biojs.ExpressionAtlasBaselineSummary({ - * geneQuery:"ENSG00000187003+ENSG00000185264", - * propertyType:"bioentity_identifier", - * geneSetMatch:false, - * target : "YourOwnDivId" - * }); - * - */ - - -Biojs.ExpressionAtlasBaselineSummary = Biojs.extend( - /** @lends Biojs.ExpressionAtlasBaselineSummary# */ - { - - /** - * Constructor to initialize the component - * @name Biojs.ExpressionAtlasBaselineSummary-constructor - */ - constructor:function (options) { - //Biojs.console.enable(); - this._containerDiv = jQuery("#" + this.opt.target); - this.setQuery(this.opt.geneQuery, this.opt.propertyType, this.opt.geneSetMatch); - }, - - /** - * Set ENSEMBL gene ids or UniProt ids. - * @param {string} geneQuery ENSEMBL gene ids or UniProt ids. If more than one identifier follow this format "P00846+P99999". - * @param {string} propertyType Property to narrow to search scope of a query term, please provide a type. - * @param {boolean} geneSetMatch If true collapse multiple returned gene profiles into one single line of average expression. - * - * @example - * instance.setQuery("ENSG00000187003+ENSG00000185264","bioentity_identifier",false); - * - * @example - * instance.setQuery("Q61171","",false); - * - * @example - * instance.setQuery("P37173+Q9UER7+P10600+P35243+Q93074+P16234","",false); - * - * @example - * instance.setQuery("ENSG000000000000","bioentity_identifier",false); - * - */ - setQuery: function(geneQuery, propertyType, geneSetMatch){ - this.opt.geneQuery = geneQuery; - this.opt.propertyType = propertyType; - this.opt.geneSetMatch = geneSetMatch; - this._containerDiv.empty(); - - /* Check if it is Uniprot or Ensembl ID. Correct propertyType if necessary */ - var listOfIds = geneQuery.split("+"); - this._identifierDb = this._checkIdentifier(listOfIds[0]); - if(this._identifierDb == Biojs.ExpressionAtlasBaselineSummary.ID_UNIPROT){ - this.opt.propertyType = ""; - } else if (this._identifierDb == Biojs.ExpressionAtlasBaselineSummary.ID_ENSEMBL){ - this.opt.propertyType = "bioentity_identifier"; - } - - /* Set url */ - var url = this.opt.featuresUrl + "?geneQuery=" + this.opt.geneQuery; - if(this.opt.propertyType != ""){ - url = url + "&propertyType=" + this.opt.propertyType; - } - if(this.opt.geneSetMatch == true){ - url = url + "&geneSetMatch=true"; - } - if (this.opt.proxyUrl != "") { - url = this.opt.proxyUrl + "?url=" + url; - } - - /* Set url and start the request */ - var self = this; - var httpRequest = { - url:url, - data:{rootContext:this.opt.rootContext}, - method:"GET", - /** @ignore No need to document this object */ - beforeSend:function () { - self._containerDiv.html(""); - }, - /** @ignore No need to document this object */ - success:function (htmlResponse) { - Biojs.console.log("SUCCESS: data received"); - Biojs.console.log(htmlResponse); - self._containerDiv.html(htmlResponse); - }, - /** @ignore No need to document this object */ - error:function (xhr, ajaxOptions, thrownError) { - Biojs.console.log("ERROR: " + xhr.status); - self._containerDiv.html("An error occurred while retrieving the data: " + xhr.status + " - " + xhr.statusText); - self.raiseEvent( - "onError", - { "message": "AJAX request failed", "jqXHR":xhr, "textStatus":ajaxOptions, "errorThrown":thrownError } - ); - } - }; - - jQuery.ajax(httpRequest); - }, - - /* - * Function: Biojs.ExpressionAtlasBaselineSummary._checkIdentifier - * Purpose: Check if the indetifier provided by the user is ENSEMBL or UniProt - * Returns: Database name (uniprot or ensembl) - * Inputs: id -> {String} Identifier. - */ - _checkIdentifier: function(id){ - var self = this; - self._re = /^([A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])$/; - if (id.search(self._re) != -1){ - return Biojs.ExpressionAtlasBaselineSummary.ID_UNIPROT; - } else if(id.substring(0,4) == "ENSG"){ - return Biojs.ExpressionAtlasBaselineSummary.ID_ENSEMBL; - } - }, - - /** - * Default values for the options - * @name Biojs.ExpressionAtlasBaselineSummary-opt - */ - opt:{ - /* Features URL - This consists of service url used to query for a particular - gene or genes by given their properties. For a single gene query, - please use a unique accession (e.g. ENSEMBL gene id or UniProt id). - For example search with UniProt id P00846 returns the gene mt-atp6, - a search for REACT_6900 returns genes belonging to this pathway. - To narrow to search scope of a query term, please provide a type: - &propertyType=bioentity_identifier (here only the identifier property is searched) - An additional parameter (&geneSetMatch=true) can be appended after - the query term to collapse multiple returned gene profiles into one - single line of average expression (this feature is still experimental). - For multiple identifiers of the same species please use: - geneQuery=ENSG00000187003+ENSG00000185264&propertyType=bioentity_identifier - */ - featuresUrl:'http://www.ebi.ac.uk/gxa/widgets/heatmap/protein', - geneQuery:"", - propertyType:"", - geneSetMatch:"", - /* Target DIV - This mandatory parameter is the identifier of the DIV tag where the - component should be displayed. Use this value to draw your - component into. */ - target:"YourOwnDivId", - /* Root context - This is an optional parameter to specify the root context path to - be used by the widget content, i.e. this is pointing to the - content proxy where required. - */ - rootContext:'../biojs/dependencies/proxy/proxy.php?url=http://www.ebi.ac.uk/gxa', - /* Proxy URL - To bypass the same origin policy this component needs a proxy, which - can be set here. - */ - proxyUrl:"../biojs/dependencies/proxy/proxy.php" - }, - - - /** - * Array containing the supported event names - * @name Biojs.ExpressionAtlasBaselineSummary-eventTypes - */ - eventTypes:[ - /** - * @name Biojs.ExpressionAtlasBaselineSummary#onError - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {string} message Error message in case of result be 'failure'. - * @eventData {Object} jqXHR XMLHttpRequest object - * @eventData {string} textStatus It describes the type of error that occurred and an optional exception object, if one occurred - * @eventData {string} errorThrown When an HTTP error occurs, errorThrown receives the textual portion of the HTTP status, such as "Not Found" or "Internal Server Error." - * - * @example - * instance.onError( - * function( error ) { - * alert( error.message ); - * } - * ); - * - **/ - "onError" - ] - - },{ - ID_UNIPROT: "uniprot", - ID_ENSEMBL: "ensembl" -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionLoader.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionLoader.js deleted file mode 100755 index f10050d544..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.ExpressionLoader.js +++ /dev/null @@ -1,429 +0,0 @@ -/** - * This component allows to load a tab-delimited file on the client. it uses HTML5 to load the file into the browser, - * it does not require a server side. - * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires Expression Loader CSS - * @dependency - * - * @requires Color Selector CSS - * @dependency - * - * @requires Color Selector - * @dependency - * - * @param {Object} options An object with the options for the Expression Loader component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {String} label - * Text for the link that opens the file chooser dialog. - * - * @example - * var instance = new Biojs.ExpressionLoader({ - * target: "YourOwnDivId" - * }); - * - */ -Biojs.ExpressionLoader = Biojs.extend ( - /** @lends Biojs.ExpressionLoader# */ - { - expressions:null, - min:99999, - max:-99999, - column:-1, - colorData:null, - - constructor: function (options) { - var self = this; - if (window.File && window.FileReader && window.FileList && window.Blob) { - $("#"+self.opt.target).html('
          '+self.opt.label+'

          '); - $("#"+self.opt.target+' .fake-file').click(function(){ - $("#"+self.opt.target+" .button-link").click(); - }); - $("#"+self.opt.target+" .button-link").change(function(evt){ - self._handleFileSelect(evt); - }); - } else { - self.raiseEvent('onError', { - error: 'Expression data can\'t be loaded in your browser.' - }); - } - }, - /** - * Default values for the options - * @name Biojs.ExpressionLoader-opt - */ - opt: { - target: "YourOwnDivId", - label: "Color by Expression File..." - }, - - /** - * Array containing the supported event names - * @name Biojs.ExpressionLoader-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.ExpressionLoader#onFileLoaded - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {Object} expressions a hash array containing the values loaded with the protein id(first column in the file) as the key and an array of numbers(expression data) as the value. - * @example - * instance.onFileLoaded(function( objEvent ) { - alert("File loaded"); - var expression =objEvent.expressions, - color=objEvent.colorData; - var i=0; - $('output').append("

          "); - for (var p in expression){ - if (i++==40) break; - var value=1*expression[p][objEvent.column*1]; - $('output').append("
          "+p+" ("+value+")"); - } - }); - * - * */ - "onFileLoaded", - /** - * @name Biojs.ExpressionLoader#onFileRemoved - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @example - instance.onFileRemoved(function( objEvent ) { - alert("File removed"); - $('output').html(""); - }); - * - * */ - "onFileRemoved", - /** - * @name Biojs.ExpressionLoader#onError - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {String} error a string describing the type of error. - * @example - * instance.onError( - * function( objEvent ) { - * alert("ERROR: "+ objEvent.error); - * } - * ); - * - * */ - "onError", - - ], - _handleFileSelect: function(evt){ - var self = this; - var files = evt.target.files; // FileList object - - // files is a FileList of File objects. List some properties. - var column = 1; - for (var i = 0, f; f = files[i]; i++) { - if (!f.type.match('text.*')) { - $('#'+self.opt.target+' output').html("The selected file is not text, its type is "+f.type); - self.raiseEvent('onError', { - error: "The selected file is not text, its type is "+f.type - }); - continue; - } - var reader = new FileReader(); - reader.onload = (function(theFile) { - return function(e) { - var exp = self.parseTabDelimitedString(e.target.result); - if (exp!=null){ - self.startWizzard(); - } - }; - })(f); - reader.readAsText(f); - } - - }, - /** - * Parse a String with tab delimited format into a hash, where the first column is treated as the key, - * and the value are all the other columns grouped as an array - * - * @param {string} text the tab delimited string - * - * @example - * instance.parseTabDelimitedString('p1\t0.5\t0.3\t0.2\np2\t0.4\t0.2\t0.9'); - */ - parseTabDelimitedString: function(text){ - var self = this; - self.expressions ={}; - self.min =99999; - self.max = -99999; - self.column=-1; - self.colorData=null; - - var lines = text.split("\n"); - var columns =-1; - for (var i=0; i< lines.length; i++){ - if (lines[i].indexOf("#")==0) - continue; - var line = lines[i].split("\t"); - if (columns==-1){ - columns = line.length; - if (columns<2){ - self.raiseEvent('onError', { - error: "The file at requires at least 2 columns (Id and Expression)" - }); - $('#'+self.opt.target+' output').html("The file at requires at least 2 columns (Id and Expression)"); - self.expressions =null; - break; - } - }else if (columns!=line.length){ - self.raiseEvent('onError', { - error: "The number of columns is different between lines "+i+" and "+(i+1) - }); - $('#'+self.opt.target+' output').html("The number of columns is different between lines "+i+" and "+(i+1)); - self.expressions =null; - columns=-1; - break; - } - var exps =line.splice(1); - self.expressions[line[0]] = exps; - for (var j=0;j(exps[j]*1)) self.min = exps[j]*1; - if (self.max<(exps[j]*1)) self.max = exps[j]*1; - } - } - return self.expressions; - }, - /** - * Build a HTML string that displays a given number of rows as a table, including a last row of radio buttons - * to select a column - * - * @param {int} rows the number of rows to be included in the table. - * - * @example - * instance.getFormatedTable(3); - */ - getFormatedTable: function(rows){ - var self=this; - var i=0; - var loadedText="" - var columns =0; - for (var p in self.expressions){ - if (rows==i++) break; - loadedText += ""; - columns = self.expressions[p].length; - } - loadedText += ""; - var col = (self.column!=-1)?self.column:0; - for (var i=0; i< columns; i++){ - var selected=(i==col)?"checked":""; - loadedText += ''; - selected=""; - } - loadedText += "
          "+p+""+self.expressions[p].join("")+"
          Column to Use:
          "; - return loadedText; - }, - /** - * Open the first parameter dialog to choose which column of the file should be loaded. It requires that a file(or a string) have - * been parsed previously because it uses the value in the attribute expressions. - * - * @example - * instance.startWizzard(); - */ - startWizzard: function(){ - var self =this; - $('#'+self.opt.target+' output').html('

          '+self.getFormatedTable(5)+'

          '); - $('#'+self.opt.target+" .dialog-modal" ).dialog({ - height: 400, - width: 600, - modal: true, - buttons: { - Next: function() { - self.column = 1*$('.dialog-modal input[name="column"]:checked').val(); - $( this ).dialog( "destroy" ); - self.wizzardStep2(); - } - } - }); - }, - /** - * Open the second parameter dialog to choose the range of expression values and their correspondent colors. It requires that a file(or a string) have - * been parsed previously because it uses the value in the attribute expressions. - * - * @example - * instance.startWizzard(); - */ - wizzardStep2: function(){ - var self =this; - var min = (self.colorData!=null)?self.colorData.min:self.min, - max = (self.colorData!=null)?self.colorData.max:self.max, - center = (self.colorData!=null)?self.colorData.center:0, - colorMin = (self.colorData!=null)?self.colorData.colorMin:"#FF0000", - colorMax = (self.colorData!=null)?self.colorData.colorMax:"#00FF00", - colorCenter = (self.colorData!=null)?self.colorData.colorCenter:"#000000"; - var loadedText = "
          Min:"; - loadedText +=''; - loadedText +="
          Center:"; - loadedText +=''; - loadedText +="
          Max:"; - loadedText +=''; - loadedText +="
          "; - - $('#'+self.opt.target+' output').html('

          '+loadedText+'

          '); - - $("#colorMax").miniColors({ - letterCase: 'uppercase' - }).miniColors('value',colorMax); - $("#colorCenter").miniColors({ - letterCase: 'uppercase' - }).miniColors('value',colorCenter); - $("#colorMin").miniColors({ - letterCase: 'uppercase' - }).miniColors('value',colorMin); - - $('#'+self.opt.target+" .dialog-modal" ).dialog({ - height: 400, - width: 600, - modal: true, - buttons: { - Apply: function() { - self.colorData = { - min: $("#min").val(), - center: $("#center").val(), - max: $("#max").val(), - colorMin: $("#colorMin").val(), - colorCenter:$("#colorCenter").val(), - colorMax: $("#colorMax").val() - }; - self.calculateExtrapolingData(self.colorData); - $("#colorCenter").miniColors('destroy'); - $("#colorMin").miniColors('destroy'); - $("#colorMax").miniColors('destroy'); - $( this ).dialog( "destroy" ); - $(" .dialog-modal" ).remove(); - $("#"+self.opt.target+" .fake-file").html("Change File..."); - $("#"+self.opt.target+" .exp-edit").remove(); - $("#"+self.opt.target+" .exp-remove").remove(); - $("#"+self.opt.target+" .fake-file").after("
          "); - $("#"+self.opt.target+" .exp-remove").click(function() { - self.expressions =null; - self.min =99999; - self.max = -99999; - self.column=-1; - self.colorData=null; - - $("#"+self.opt.target+" .exp-edit").remove(); - $("#"+self.opt.target+" .exp-remove").remove(); - $("#"+self.opt.target+" .fake-file").html(self.opt.label); - $("#"+self.opt.target+" .button-link").val(''); - self.raiseEvent('onFileRemoved', {}); - }); - $("#"+self.opt.target+" .fake-file").after("
          "); - $("#"+self.opt.target+" .exp-edit").click(function() { - self.startWizzard(); - }); - - self.raiseEvent('onFileLoaded', { - expressions: self.expressions, - column: self.column, - colorData: self.colorData - }); - } - } - }); - }, - _hexToR: function (h) { - var self=this; - return parseInt((self._cutHex(h)).substring(0,2),16) - }, - _hexToG: function (h) { - var self=this; - return parseInt((self._cutHex(h)).substring(2,4),16) - }, - _hexToB: function (h) { - var self=this; - return parseInt((self._cutHex(h)).substring(4,6),16) - }, - _cutHex: function (h) {return (h.charAt(0)=="#") ? h.substring(1,7):h}, - _getM: function (x1,y1,x2,y2) { - return (y1-y2)/(x1-x2); - }, - _getB: function (m,x,y){ - return y - m*x; - }, - _getY: function (m,b,x){ - return parseInt(m*x + b); - }, - - calculateExtrapolingData: function(colorData){ - var self=this; - var minRed = self._hexToR(colorData.colorMin), - centerRed = self._hexToR(colorData.colorCenter), - maxRed = self._hexToR(colorData.colorMax), - minGreen = self._hexToG(colorData.colorMin), - centerGreen = self._hexToG(colorData.colorCenter), - maxGreen = self._hexToG(colorData.colorMax), - minBlue = self._hexToB(colorData.colorMin), - centerBlue = self._hexToB(colorData.colorCenter), - maxBlue = self._hexToB(colorData.colorMax); - - var mRedN = self._getM(colorData.min,minRed,colorData.center,centerRed), - mGreenN = self._getM(colorData.min,minGreen,colorData.center,centerGreen), - mBlueN = self._getM(colorData.min,minBlue,colorData.center,centerBlue); - var mRedP = self._getM(colorData.center,centerRed,colorData.max,maxRed), - mGreenP = self._getM(colorData.center,centerGreen,colorData.max,maxGreen), - mBlueP = self._getM(colorData.center,centerBlue,colorData.max,maxBlue); - var bRedN = self._getB(mRedN,colorData.min,minRed), - bGreenN = self._getB(mGreenN,colorData.min,minGreen), - bBlueN = self._getB(mBlueN,colorData.min,minBlue); - var bRedP = self._getB(mRedP,colorData.max,maxRed), - bGreenP = self._getB(mGreenP,colorData.max,maxGreen), - bBlueP = self._getB(mBlueP,colorData.max,maxBlue); - - colorData.mRedN=mRedN; - colorData.mGreenN=mGreenN; - colorData.mBlueN=mBlueN; - colorData.mRedP=mRedP; - colorData.mGreenP=mGreenP; - colorData.mBlueP=mBlueP; - colorData.bRedN=bRedN; - colorData.bGreenN=bGreenN; - colorData.bBlueN=bBlueN; - colorData.bRedP=bRedP; - colorData.bGreenP=bGreenP; - colorData.bBlueP=bBlueP; - return colorData; - }, - /** - * Extrapolates a value using the minimum and maximum values and colors given as parameters. - * It returns a string in the format: "rgb([valRed],[valGreen],[valBlue])" - * - * @example - * instance.getRGBString(0.6); - * instance.getRGBString(0.8); - * instance.getRGBString(0.1); - */ - getRGBString:function(value){ - var self=this; - if (value>self.colorData.center) - return "rgb("+self._getY(self.colorData.mRedP,self.colorData.bRedP,value)+","+self._getY(self.colorData.mGreenP,self.colorData.bGreenP,value)+","+self._getY(self.colorData.mBlueP,self.colorData.bBlueP,value)+")"; - else - return "rgb("+self._getY(self.colorData.mRedN,self.colorData.bRedN,value)+","+self._getY(self.colorData.mGreenN,self.colorData.bGreenN,value)+","+self._getY(self.colorData.mBlueN,self.colorData.bBlueN,value)+")"; - } - }); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.FeatureViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.FeatureViewer.js deleted file mode 100755 index a372403218..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.FeatureViewer.js +++ /dev/null @@ -1,1774 +0,0 @@ -/** - * - * This component takes a JSON data object and paints it as a Raphael object. - * The expected JSON format is specified under the option 'json' of the FeatureViewer options. - * - * Please remember to use jQuery in compatibility mode, particularly a good idea if you use other libraries. - * - * If you are using JQuery 1.9.x please make sure you also include the jQuery Migrate plugin - * as tooltips are not compatible with 1.9.x versions, see http://jquery.com/upgrade-guide/1.9/ - * - * @class - * @extends Biojs - * - * @author Leyla Jael Garcia Castro, Guy Yachdav, Pablo Moreno - * @version 1.1.0 - * @category 0 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires jQuery.tooltip - * @dependency - * - * @requires jQuery.tooltip CSS - * @dependency - * - * @requires Raphael 2.1.2 - * @dependency - * - * @requires canvg - * @dependency - * - * @requires rgbcolor - * @dependency - * - * @requires Image ui-bg_flat_0_aaaaaa_40x100.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires Image ui-bg_flat_75_ffffff_40x100.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires Image ui-bg_glass_65_ffffff_1x400.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires Image ui-bg_glass_75_dadada_1x400.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires ui-bg_glass_75_e6e6e6_1x400.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires ui-bg_highlight-soft_75_cccccc_1x100.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires ui-icons_222222_256x240.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @requires ui-icons_454545_256x240.png (base theme images for jquery-ui-1.8.2) - * @dependency - * - * @param {Object} options An object with the options for FeatureViewer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} json - * The JSON object describing the configuration, features, and legend to be displayed. - * It must have the following members: - *
            - *
          • segment | {string} - *

            Segment, accession or identification.

            - *

          • - *
          • configuration | {object} - *

            - * General configuration used mainly to paint the ruler, grid lines, and slider. - * Elements such as XXXNonOverlapping, XXXCentered, and XXXRows are necessary only it you want to enable changing styles without retrieving the data - * from the server again. - *

            - *
            - *                 aboveRuler: <int>, //pixels above the ruler
            - *                 belowRuler: <int>, //pixels below the ruler
            - *                 dasReference: <String>, //das reference URL
            - *                 dasSources: <String>, //das annotations URLs separated by commas
            - *                 gridLineHeight: <int>, //row height (used for rows and nonOverlapping styles)
            - *                 horizontalGrid: <boolean>, //should horizontal grid lines be displayed?
            - *                 horizontalGridNumLines: <int>, //number of horizontal grid lines
            - *                 leftMargin: <int>, //pixels for the holder's left margin
            - *                 nonOverlapping: <boolean>, //is nonOverlapping style requested?
            - *                 pixelsDivision: <int>, //number of pixels between every main division in the ruler
            - *                 requestedStart: <int>, //requested start position
            - *                 requestedStop: <int>, //requested stop position
            - *                 rightMargin: <int>, //pixels for the holder's right margin
            - *                 rulerLength: <int>, //ruler length in pixels
            - *                 rulerY: <int>, //ruler y position in pixels
            - *                 sequenceLength: <int>, //sequence length (number of amino acids)
            - *                 sequenceLineY: <int>, //sequence line y position (blue line representing the sequence)
            - *                 sizeX: <int>, //holder's width in pixels
            - *                 sizeY: <int>, //holder's height in pixels
            - *                 sizeYKey: <int>, //key holder's height in pixels
            - *                 start: <int>, //first amino acid to show
            - *                 stop: <int>, //last amino acid to show
            - *                 style: <String>, // style in use from centered, rows, or nonOverlapping
            - *                 unitSize: <int>, //number of pixels used to represent one amino acid
            - *                 verticalGrid: <boolean> //are vertical grid lines displayed?
            - *                 verticalGridLineLength: <int> //vertical grid lines' length
            - *                 horizontalGridNumLinesCentered: <int>, //number of horizontal grid line for the centered style
            - *                 horizontalGridNumLinesNonOverlapping: <int>, //number of horizontal grid line for the nonOverlapping style
            - *                 horizontalGridNumLinesRows: <int>, //number of horizontal grid line for the rows style
            - *                 sequenceLineYCentered: <int>, //sequence line y position for centered style (blue line representing the sequence)
            - *                 sequenceLineYNonOverlapping: <int>, //sequence line y position for nonOverlapping style (blue line representing the sequence)
            - *                 sequenceLineYRows: <int>, //sequence line y position for rows style (blue line representing the sequence)
            - *                 sizeYCentered: <int>, //holder's height in pixels for the centered style
            - *                 sizeYNonOverlapping: <int>, //holder's height in pixels for the nonOverlapping style
            - *                 sizeYRows: <int>, //holder's height in pixels for the rows style
            - *                 verticalGridLineLengthCentered: <int> //vertical grid lines' length for the centered style
            - *                 verticalGridLineLengthNonOverlapping: <int> //vertical grid lines' length for the nonOverlapping style
            - *                 verticalGridLineLengthRows: <int> //vertical grid lines' length for the rows style
            - *          	
            - *
          • - *
          • featuresArray | {Array} - *

            Each element corresponds to an annotation, it includes elements representing the annotation itself as well as elements representing - * the SVG properties, i.e. those related to the shape. Elements such as XXXNonOverlapping, XXXCentered, and XXXRows are necessary - * only it you want to enable changing styles without retrieving the data from the server again - *

            - *
            - *                 cx: <int> //shape x position (for all shapes but rectangles)
            - *                 cy: <int> //shape y position (for all shapes but rectangles)
            - *                 evidenceCode: <String>, //annotation evidence code, e.g. "ECO:0000001"
            - *                 evidenceText: <String>, //annotation evidence text, e.g. "inferred by curator"
            - *                 featureEnd: <int> //annotation stop
            - *                 featureId: <String> //annotation id, e.g. "UNIPROTKB_P05067_SIGNAL_1_17"
            - *                 featureLabel: <String> //annotation label, e.g. "Signal"
            - *                 featureStart: <int> //annotation start
            - *                 featureTypeLabel: <String> //annotation type label, e.g. "signal_peptide"
            - *                 fill: <hexa color> //e.g. "#AA8CF0"
            - *                 fillOpacity: <float> //transparency, e.g. 0.5
            - *                 height: <int> //shape's height in pixels (for rectangles)
            - *                 path: <String> //shape path (empty if it is not a path)
            - *                 r: <radius> //shape's radius in pixels (all but rectangles)
            - *                 stroke: <hexa color> //e.g. #AA8CF0"
            - *                 strokeWidth: <int> //stroke width
            - *                 text: <String> //for shapes corresponding to text
            - *                 type: <String> //shape type (one of: rect, triangle, circle, diamond, wave, hexagon)
            - *                 typeCategory: <String>, //type category, e.g. domain
            - *                 typeCode: <String> //annotation controlled vocabulary id, e.g. "SO:0000418"
            - *                 typeLabel: <String> //annotation label to be displayed in the tool tip
            - *                 width: <int> //shape's width in pixels
            - *                 x: <int> //shape x position in pixels
            - *                 y: <int> //shape y position in pixels
            - *                 centeredStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the centered style
            - *                 nonOverlappingStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the nonOverlapping style
            - *                 rowsStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the rows style
            - *             
            - *
          • - *
          • legend | {object} - *

            Information to be displayed in the keyElements such as XXXNonOverlapping, XXXCentered, and XXXRows are necessary only it you want to enable changing - * styles without retrieving the data from the server again. - *

            - *
            - *                 key: <Array{label object, shape object}> //annotation types with the number of features showed in the segment
            - *                 segment: <Object> //requested segment without the limits, just the identifier or accession
            - *              
            - *

            Detail for elements in the key array

            - *
            - *                 label: <Object>, //
            - *                 text: <String> //annotation type name
            - *                 total: <int> //total annotations displayed for that type
            - *                 xPos: <int> //x position in pixels
            - *                 yPos: <int> //y position in pixels
            - *                 yPosCentered: <int> //y position in pixels for the centered style
            - *                 yPosNonOverlapping: <int> //y position in pixels for the nonOverlapping style
            - *                 yPosRows: <int> //y position in pixels for the rows style
            - *                 shape: <Object> //corresponding shape
            - *                 cx:  <int> //shape x position (for all shapes but rectangles)
            - *                 cy: <int> //shape y position (for all shapes but rectangles)
            - *                 fill: <hexa color> //e.g. "#AA8CF0"
            - *                 fillOpacity: <float> //transparency, e.g. 0.5
            - *                 height: <int> //shape's height in pixels (for rectangles)
            - *                 path: <String> //shape path (empty if it is not a path)
            - *                 r: <radius> //shape's radius height in pixels (all but rectangles)
            - *                 stroke: <hexa color> //e.g. #AA8CF0"
            - *                 strokeWidth: <int> //stroke width
            - *                 text: <String> //for shapes corresponding to text
            - *                 type: <String> //shape type (one of: rect, triangle, circle, diamond, wave, hexagon)
            - *                 typeLabel: <String> //annotation type name
            - *                 width: <int> //shape's width in pixels
            - *                 x: <int> //shape x position in pixels (it is probably a good idea to keep both cx and x, even for non-rectangles)
            - *                 y: <int> //shape y position in pixels (it is probably a good idea to keep both cy and y, even for non-rectangles)
            - *                 centeredStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the centered style
            - *                 nonOverlappingStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the nonOverlapping style
            - *                 rowsStyle: <Object>, //{"heightOrRadius":<int>,"y":<int>} height and y position for the rows style
            - *              
            - *

            Detail for the segment element

            - *
            - *                 text: <String>, //Accession or identifier, e.g. A4_HUMAN
            - *                 xPos: <int>, //x position in pixels
            - *                 yPos: <int>, //y position in pixels
            - *                 yPosCentered:<int>, //y position in pixels for the centered style
            - *                 yPosNonOverlapping:<int>, //y position in pixels for the nonOverlapping style
            - *                 yPosRows:<int>, //y position in pixels for the rows style
            - *             
            - *
          • - *
          - * - * @option {boolean} [showSlider=true] - * Should the slider for zooming be displayed? - * - * @option {boolean} [showPrintButton=true] - * Should the button for printing/exporting to image be displayed? - * - * @option {boolean} [showFeatureTooltipOnMouseOver=true] - * Should the tooltip for features be displayed? - * - * @option {boolean} [highlightFeatureOnMouseOver=true] - * Should the features be highlighted when mouse over? - * - * @option {boolean} [selectFeatureOnMouseClick=true] - * Should the features remain highlighted, i.e. being selected, after a mouse click, - * and deselected after a second click or whenever other feature is selected? - * - * @option {boolean} [dragSites=true] - * Should the sites be draggable? - * - * @option {String} [selectionColor=#ff8c00] - * Color in hexa format so the features on mouse-over and click will change to it. - * Make sure it does not exist at http://wwwdev.ebi.ac.uk/das-srv/uniprot/das/uniprot/stylesheet as those are the reference colours for protein features. - * - * @example - * var json = { - * "featuresArray":[ - * { - * "nonOverlappingStyle":{"heightOrRadius":10,"y":56},"type":"rect","featureEnd":73,"fillOpacity":0.5 - * ,"evidenceText":"UniProt","stroke":"#9B7057","height":10,"path":"","typeLabel":"Propeptide" - * ,"featureLabel":"Propeptide","featureStart":1,"strokeWidth":1,"text":"" - * ,"centeredStyle":{"heightOrRadius":44,"y":73},"fill":"#9B7057","width":495 - * ,"typeCategory":"Molecule processing","typeCode":"SO:0001062","cy":56,"cx":27,"evidenceCode":"" - * ,"r":10,"featureId":"UNIPROTKB_Q8LAX3_PROPEP_1_73","rowsStyle":{"heightOrRadius":10,"y":169} - * ,"featureTypeLabel":"propeptide","y":56,"x":27 - * } - * ,{ - * "nonOverlappingStyle":{"heightOrRadius":10,"y":56},"type":"rect","featureEnd":96,"fillOpacity":0.5 - * ,"evidenceText":"UniProt","stroke":"#7DBAA4","height":10,"path":"","typeLabel":"Peptide" - * ,"featureLabel":"Elicitor peptide 3","featureStart":74,"strokeWidth":1,"text":"" - * ,"centeredStyle":{"heightOrRadius":40,"y":75},"fill":"#7DBAA4","width":151 - * ,"typeCategory":"Molecule processing","typeCode":"SO:0001064","cy":56,"cx":529,"evidenceCode":"" - * ,"r":10,"featureId":"UNIPROTKB_Q8LAX3_PEPTIDE_74_96","rowsStyle":{"heightOrRadius":10,"y":157} - * ,"featureTypeLabel":"active_peptide","y":56,"x":529 - * } - * ] - * ,"segment":"Q8LAx3" - * ,"legend":{ - * "segment":{"yPosCentered":190,"text":"Q8LAX3","yPos":106,"xPos":15,"yPosNonOverlapping":106,"yPosRows":290} - * ,"key":[ - * { - * "label":{ - * "total":"1","yPosCentered":210,"text":"Peptide","yPos":126,"xPos":50 - * ,"yPosNonOverlapping":126,"yPosRows":310 - * } - * ,"shape":{ - * "centeredStyle":{"heightOrRadius":5,"y":208},"text":"" - * ,"nonOverlappingStyle":{"heightOrRadius":5,"y":121},"width":30,"fill":"#7DBAA4" - * ,"cy":121,"cx":15,"type":"rect","fillOpacity":0.5,"stroke":"#7DBAA4","height":5,"r":10 - * ,"path":"","rowsStyle":{"heightOrRadius":5,"y":305},"typeLabel":"Peptide","y":121 - * ,"strokeWidth":1,"x":15 - * } - * } - * ,{ - * "label":{ - * "total":"1","yPosCentered":210,"text":"Propeptide","yPos":126,"xPos":205 - * ,"yPosNonOverlapping":126,"yPosRows":310 - * } - * ,"shape":{ - * "centeredStyle":{"heightOrRadius":5,"y":208},"text":"" - * ,"nonOverlappingStyle":{"heightOrRadius":5,"y":121},"width":30,"fill":"#9B7057" - * ,"cy":121,"cx":170,"type":"rect","fillOpacity":0.5,"stroke":"#9B7057","height":5,"r":10 - * ,"path":"","rowsStyle":{"heightOrRadius":5,"y":305},"typeLabel":"Propeptide","y":121 - * ,"strokeWidth":1,"x":170 - * } - * } - * ] - * } - * ,"configuration":{ - * "requestedStop":96,"horizontalGridNumLines":2,"sequenceLineYCentered":95,"requestedStart":1 - * ,"gridLineHeight":12,"rightMargin":20,"belowRuler":30,"sequenceLength":96 - * ,"horizontalGridNumLinesNonOverlapping":2,"horizontalGridNumLinesCentered":6 - * ,"verticalGridLineLengthRows":284,"unitSize":6.875,"sizeYNonOverlapping":76,"style":"nonOverlapping" - * ,"sequenceLineYRows":155,"sequenceLineY":54,"verticalGrid":false,"rulerY":20 - * ,"dasSources":"http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot","horizontalGrid":false - * ,"pixelsDivision":50,"sizeY":76,"sizeX":700 - * ,"dasReference":"http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot","sizeYRows":260,"aboveRuler":10 - * ,"rulerLength":660,"verticalGridLineLengthNonOverlapping":66,"sizeYKey":210,"sizeYCentered":160 - * ,"sequenceLineYNonOverlapping":54,"verticalGridLineLength":66,"horizontalGridNumLinesRows":8 - * ,"leftMargin":20,"nonOverlapping":true,"verticalGridLineLengthCentered":172 - * } - * }; - * - * var myPainter = new Biojs.FeatureViewer({ - * target: "YourOwnDivId", - * json: json - * }); - * - */ -Biojs.FeatureViewer = Biojs.extend( - /** @lends Biojs.FeatureViewer */ - { - /* - * Public variables - */ - raphael: '', - connections: [], - zoomSlider: '', - slider_stop: 0, - slider_start: 0, - context: '', - instance: undefined, - /* - * Private variables - */ - _UP: "up", - _DOWN: "down", - _MIDDLE: "middle", - _CENTERED: "centered", - _ROWS: "rows", - _NON_OVERLAPPING: "nonOverlapping", - _GRID_OPACITY: 0.3, - _LIME: "#00ff00", - _DARK_ORANGE: "#ff8c00", - _originalColor: "", - _previousClickedColor: "", - _previousClickedFillColor: "", - _previousClickedShape: "", - _previousClickedFeature: "", - _clickCounter: 0, - - /** - * Default values for the options - * @name Biojs.FeatureViewer-constructor - */ - constructor: function(options) { - //Biojs.console.enable(); - //jQuery.noConflict(); - Biojs_FeatureViewer_array.push(this); - this.instance = Biojs_FeatureViewer_array.length-1; - Biojs_FeatureViewer_array[this.instance].opt.json = jQuery.extend(true, {}, this.opt.json); - - Biojs_FeatureViewer_array[this.instance].initRaphael(); - - if (!Biojs.Utils.isEmpty(Biojs_FeatureViewer_array[this.instance].opt.json)) { - Biojs_FeatureViewer_array[this.instance].paintFeatures(Biojs_FeatureViewer_array[this.instance].opt.json) - } - }, - - /** - * Default values for the options: - * target: "", - * json: {}, - * showSlider: true, - * showPrintButton: true, - * showFeatureTooltipOnMouseOver: true, - * highlightFeatureOnMouseOver: true, - * selectFeatureOnMouseClick: true, - * dragSites: true //beware that dragging implies a click on so the click event will be raised! - * selectionColor: "#ff8c00" - * @name Biojs.FeatureViewer-opt - */ - opt: { - target: "YourOwnDivId", - json: {}, - showSlider: true, - showPrintButton: true, - showFeatureTooltipOnMouseOver: true, - highlightFeatureOnMouseOver: true, - selectFeatureOnMouseClick: true, - dragSites: true, - selectionColor: "#ff8c00" //make sure it does not exist at http://wwwdev.ebi.ac.uk/das-srv/uniprot/das/uniprot/stylesheet - }, - - /** - * Array containing the supported event names - * @name Biojs.FeatureViewer-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.FeatureViewer#onFeatureClick - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} featureInfo A json object with the information for the selected feature, including id. - * @example - * //It is not recommended to use this event to highlight and sustain that highlight after a click on a - * //feature, instead set to ture the options selectFeatureOnMouseClick. - * myPainter.onFeatureClick( - * function( obj ) { - * var tooltip = obj.featureLabel + - * " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - * "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - * "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - * alert("Clicked: " + tooltip ); - * Biojs.console.log(obj.shape); //rapha�l object - * } - * ); - * - * */ - "onFeatureClick", - /** - * @name Biojs.FeatureViewer#onFeatureOn - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} featureInfo A json object with the information for the selected feature, including id. - * @example - * // It is not recommended to use this event to display a tooltip or highlight the features on mouse over, - * // instead set to true the options showFeatureTooltipOnMouseOver and highlightFeatureOnMouseOver - * - * myPainter.onFeatureOn( - * function( obj ) { - * var tooltip = obj.featureLabel + - * " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - * "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - * "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - * alert("On feature: " + tooltip ); - * Biojs.console.log(obj.shape); //rapha�l object - * } - * ); - * - * */ - "onFeatureOn", - /** - * @name Biojs.FeatureViewer#onFeatureOff - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} featureInfo A json object with the information for the selected feature, including id. - * @example - * - * myPainter.onFeatureOff( - * function( obj ) { - * var tooltip = obj.featureLabel + - * " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - * "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - * "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - * alert("Off feature: " + tooltip ); - * Biojs.console.log(obj.shape); //rapha�l object - * } - * ); - * - * */ - "onFeatureOff", - /** - * @name Biojs.FeatureViewer#onFeatureSelected - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} featureInfo A json object with the information for the selected feature, including id. - * @example - * //Will only be raised if selectFeatureOnMouseClick is true - * myPainter.onFeatureSelected( - * function( obj ) { - * var tooltip = obj.featureLabel + - * " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - * "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - * "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - * alert("Selected feature: " + tooltip ); - * Biojs.console.log(obj.shape); //rapha�l object - * } - * ); - * - * */ - "onFeatureSelected", - /** - * @name Biojs.FeatureViewer#onFeatureUnselected - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} type The name of the event. - * @eventData {Object} featureInfo A json object with the information for the selected feature, including id. - * @example - * //Will only be raised if selectFeatureOnMouseClick is true - * myPainter.onFeatureUnselected( - * function( obj ) { - * var tooltip = obj.featureLabel + - * " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - * "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - * "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - * alert("Unselected feature: " + tooltip ); - * Biojs.console.log(obj.shape); //rapha�l object - * } - * ); - * - * */ - "onFeatureUnselected" - ], - - /** - * Private: Finds an element within the target div for this component, - * search is expanded to all descendants in the target. - * @param {String} {idToFind} Element id - * */ - _getElementWithinTarget: function(idToFind) { - return jQuery("#"+this.opt.target).find("#"+idToFind); - }, - - /** - * Private: Finds the first child element within the target div; - * this element corresponds to the Raphaël canvas holder. - * */ - _getHolder: function() { - return jQuery('#'+this.opt.target).children("#uniprotFeaturePainter-holder")[0]; - }, - - /** - * - * @param {string} newSelectionColor New selection color - */ - setSelectionColor: function(newSelectionColor) { - this.opt.selectionColor = newSelectionColor; - }, - - /** - * Manual customization of vertical and horizontal grid lines as well as style. - * Depending on the selected values for the style radio buttons and the vertical and horizontal - * check buttons, this method changes the current style and adds/removes the gridlines. - * - * @example - * myPainter.customize("centered",true,true); - * - * @param {string} rdbStyle Radio buttons grouping styles, possible values: nonOverlapping, rows, centered. - * @param {boolean} chkHorizontal Check button for horizontal grid lines. - * @param {boolean} chkVertical Check button for vertical grid lines. - */ - customize: function(selectedStyle, paintHorizontalGrid, paintVerticalGrid) { - var config = this.opt.json.configuration; - - if ((selectedStyle == "") || - ((selectedStyle != "") && (selectedStyle == config.style)) ) { //Style did not change - if (paintVerticalGrid != config.verticalGrid) { //vertical grid changed - config.verticalGrid = paintVerticalGrid; - if (paintHorizontalGrid != config.horizontalGrid) { //both vertical and horizontal changed - config.horizontalGrid = paintHorizontalGrid; - if (paintVerticalGrid && paintHorizontalGrid) { //both are true now, paint lines - //Draw the vertical grid lines - this._paintVerticalGridLines(config.verticalGridLineLength, config.requestedStop, config.requestedStart, config.rulerLength, config.rulerY, config.pixelsDivision, config.leftMargin, this.raphael); - //Draw the horizontal grid lines - this._paintHorizontalGridLines(config.horizontalGrid, config.horizontalGridNumLines, config.gridLineHeight, config.nonOverlapping, config.leftMargin, config.rightMargin, config.sequenceLineY, config.rulerY, config.sizeX, this.raphael); - } else { //either vertical or horizontal is false, repaint without zoom calculation - this._repaint('withoutZoom'); - } - } else { //only vertical changed - if (paintVerticalGrid) { //vertical is now true, just paint lines - //Draw the vertical grid lines - this._paintVerticalGridLines(config.verticalGridLineLength, config.requestedStop, config.requestedStart, config.rulerLength, config.rulerY, config.pixelsDivision, config.leftMargin, this.raphael); - } else {//vertical in now false, take out the lines --> repaint all without zoom calculations - this._repaint('withoutZoom'); - } - } - } else { //vertical did not change - if (paintHorizontalGrid != config.horizontalGrid) { //only horizontal changed - config.horizontalGrid = paintHorizontalGrid; - if (paintHorizontalGrid) { //both are true now, paint lines - //Draw the horizontal grid lines - this._paintHorizontalGridLines(config.horizontalGrid, config.horizontalGridNumLines, config.gridLineHeight, config.nonOverlapping, config.leftMargin, config.rightMargin, config.sequenceLineY, config.rulerY, config.sizeX, this.raphael); - } else { //horizontal is false, repaint without zoom calculation - this._repaint('withoutZoom'); - } - } //else nothing changed then do nothing - } - } else {//style changed, recalculate features distribution and repaint - config.style = selectedStyle; - config.horizontalGrid = paintHorizontalGrid; - config.verticalGrid = paintVerticalGrid; - this._updateFeaturesToStyle(selectedStyle); - var holder = this._getHolder(); - holder.innerHTML = ""; - holder.style.height = (config.sizeY+config.sizeYKey) + "px"; - holder.style.width = config.sizeX + "px"; - this.raphael = Raphael(holder, config.sizeX, config.sizeY+config.sizeYKey); - this._repaint('withoutZoom'); - } - }, - - /** - * Paint the features according to the values specified in the json object defined when creating the object. - * This method initializes the holder, paints the slider and print button depending on the options, and - * paints the features and legend. - * - * @example - * myPainter.paintFeatures(); - * - * @param {Object} [json] The json object describing the configuration, features, and legend to be displayed. - */ - paintFeatures: function(json) { - if ( json ) { - this.opt.json = json; - } - this._init(); - this._paintSlider(); - this._repaint(); - }, - - /** - * Opens a new window/tab in the browser with the graphical representation as a plain image. - * Note: For IE it does not reflect the drags/drops on sites - * - * @example - * //It only works in Firefox or Chrome, IE may require a web service to handle this (which is not supported in this component). - * myPainter.exportFeaturesToImage(); - * - */ - exportFeaturesToImage: function() { -// if (typeof FlashCanvas != "undefined") { -// FlashCanvas.initElement(canvas); -// } - var config = this.opt.json.configuration; - var dataURL = ""; - if (jQuery.browser.msie) { //canvas does not work (not even with IE 9) - this.$imageExported = jQuery('
          ') - .html('Image export is not supported for IE') - .dialog({ - autoOpen: true, - title: 'Exported image', - modal: true, - width: config.sizeX+20 - }); - } else { - svg = this._getHolder().innerHTML; - var canvas = document.createElement("canvas"); - canvg(canvas, svg); - dataURL = canvas.toDataURL(); - this.$imageExported = jQuery('
          ') - .html('exported image') - .dialog({ - autoOpen: true, - title: 'Exported image', - modal: true, - width: config.sizeX+20 - }); - } -// jQuery('#uniprotFeaturePainter-imageExportedDiv').empty(); -// jQuery('#uniprotFeaturePainter-imageExported').empty(); -// jQuery('#uniprotFeaturePainter-imageExportedDiv').remove(); -// jQuery('#uniprotFeaturePainter-imageExported').remove(); - -// window.print(); -// jQuery("#uniprotFeaturePainter-image").attr("src", dataURL); -// window.open(dataURL); -// var html=""; -// html+= document.getElementById('uniprotFeaturePainter-divimage').innerHTML; -// html+=""; -// console.log(html); -// var printWin = window.open('','','left=0,top=0,width=1,height=1,toolbar=0,scrollbars=0,status =0'); -// printWin.document.write(html); -// printWin.document.close(); -// printWin.focus(); -// printWin.print(); -// printWin.close(); - }, - - /** - * Applies a zoom in or zoom out; it should not be used if the slider is available. - * - * @example - * myPainter.zoom(2,10); - * - * @param init - * @param end - */ - zoom: function(init, end) { - var config = this.opt.json.configuration; - var sequenceLength = config.sequenceLength; - if ((init >= 1) && (end <= sequenceLength)) { - this._repaint(undefined, init, end); - } - }, - - // - // Private methods - // - /* - * Private: Initializes the component. - */ - _init: function() { - //console.log(this.opt); - var config = this.opt.json.configuration; - //First create the slider, button, and holder - var painter_div = jQuery("#" + this.opt.target); - painter_div.text(''); - if (this.opt.showSlider && this.opt.showPrintButton) { - painter_div.append(this._withSliderAndButton(config.sizeX, config.sizeY, config.sizeYKey)); - } else if (this.opt.showPrintButton) { - painter_div.append(this._withButtonOnly(config.sizeX, config.sizeY, config.sizeYKey)); - } else if (this.opt.showSlider) { - painter_div.append(this._withSliderOnly(config.sizeX)); - } - painter_div.append('
          '); - painter_div.append('
          '); - - var holder = this._getHolder(); - if (!holder) { - this.$errorMsg = jQuery('
          ') - .html('There was an unexpected failure, the image cannot be displayed.') - .dialog({ - autoOpen: true, - title: 'Error', - modal: true/*, - buttons: { - Ok: function() { jQuery(this).dialog('close'); } - }*/ - }); - //this.$errorMsg.dialog('open'); - throw "Error"; - } - holder.innerHTML = ""; - holder.style.height = (config.sizeY+config.sizeYKey) + "px"; - holder.style.width = config.sizeX + "px"; - this.raphael = Raphael(holder, config.sizeX, config.sizeY+config.sizeYKey); - }, - - /** - * Private: Clears all divs content. - * @param {boolean} [withoutZoom=false] When true, it sets to 0 the total count for all feature types. - * @ignore - */ - _clear: function(withoutZoom) { - this.raphael.clear(); - this.connections = []; - if (!withoutZoom) { - //console.log(legend.key); - var keyShapes = this.opt.json.legend.key; - if (keyShapes) { - for (var i = 0; i < keyShapes.length; i++) { - keyShapes[i].label.total = 0; - } - } - } - }, - - /** - * Private: Paints the shapes and rectangles. - * @param {boolean} [withoutZoom=false] When true, this method recalculates the total for each feature type. - * @ignore - */ - _paintJson: function(withoutZoom) { - var config = this.opt.json.configuration; - for (var i = 0; i < this.opt.json.featuresArray.length; i++) { - var elem = this.opt.json.featuresArray[i]; - if (!((elem.featureEnd < config.requestedStart) || (elem.featureStart > config.requestedStop))) {//within the range - this._paint(elem, config.sequenceLineY); - if (!withoutZoom) { - this._increaseKeyTotal(elem.typeLabel); - } - } - } - }, - - /** - * Private: Paints the legend (segment and key). - * @ignore - */ - _paintKey: function() { - var legend = this.opt.json.legend; - //console.log(key); - var keySegment = legend.segment - var font = {'text-anchor':'start'}; - var shape = this.raphael.text(keySegment.xPos, keySegment.yPos, keySegment.text).attr(font); - shape.attr({"stroke": "black", "stroke-width": 0.1}); - var keyShapes = legend.key; - for (var i = 0; i < keyShapes.length; i++) { - this._paint(keyShapes[i].shape); - var shapeText = keyShapes[i].label; - var font = {'text-anchor':'start'}; - var shape = this.raphael.text(shapeText.xPos, shapeText.yPos, shapeText.text + ' (' + shapeText.total + ')').attr(font); - shape.attr({"stroke": "black", "stroke-width": 0.1}); - } - }, - - /** - * Private: Paints the ruler. - * @ignore - */ - _paintRuler: function() {//holder size, left and right margins of the holder, and number of amino acids - var config = this.opt.json.configuration; - //console.log(config); - //Draw the ruler - var ruler = this.raphael.path("M" + config.leftMargin + " " + config.rulerY + "L" + (config.sizeX-config.rightMargin) + " " + config.rulerY); - ruler.attr({fill: "black", stroke: "black", "fill": 1, "stroke-width": 1}); - //Draw the divisions - var divisions = 1.0 * config.rulerLength / config.pixelsDivision; //number of divisions with label - var divisionValue = 1.0 * (config.requestedStop-config.requestedStart+1) / divisions; //seed value for labels - var divisionSize = config.rulerLength / (divisions*10); //inter-divisions - divisions = Math.round(divisions); - divisionValue = Math.round(divisionValue); - for (var i = 1; i < divisions*10; i++) { //10 inter-divisions for each division - var posX = Math.round(i*divisionSize + config.leftMargin); - if ((divisionValue*i/10) < config.requestedStop) { - if (i%10 == 0) { - var line = this.raphael.path("M" + posX + " " + (config.rulerY-6) + "L" + posX + " " + (config.rulerY+6)); - line.attr({fill: "black", stroke: "black", "fill": 1, "stroke-width": 1}); - var text = this.raphael.text(posX, config.aboveRuler, "" + ((divisionValue*i/10)+config.requestedStart-1)); - text.attr({fill: "black"}); - if ((config.verticalGrid == 'true') || (config.verticalGrid == true)) { - var line = this.raphael.path("M" + posX + " " + (config.rulerY+6) + "L" + posX + " " + config.verticalGridLineLength); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - } else if (i%5 == 0) { - var line = this.raphael.path("M" + posX + " " + (config.rulerY-4) + "L" + posX + " " + (config.rulerY+4)); - line.attr({fill: "grey", stroke: "grey", "fill": 1, "stroke-width": 1}); - } /*else { - var line = this.raphael.path("M" + posX + " " + (rulerY-2) + "L" + posX + " " + (rulerY+2)); - line.attr({fill: "grey"}); - } */ - } - } - //always draw the start and the stop - var text = this.raphael.text(config.leftMargin, config.belowRuler, "" + config.requestedStart); - text.attr({fill: "blue"}); - var text = this.raphael.text(config.rulerLength + config.leftMargin, config.belowRuler, "" + config.requestedStop); - text.attr({fill: "blue"}); - if ((config.verticalGrid == 'true') || (config.verticalGrid == true)) { - var line = this.raphael.path("M" + config.leftMargin + " " + (config.rulerY+6) + "L" + config.leftMargin + " " + config.verticalGridLineLength); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - var line = this.raphael.path("M" + (config.rulerLength + config.leftMargin) + " " + (config.rulerY+6) + "L" + (config.rulerLength + config.leftMargin) + " " + config.verticalGridLineLength); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - //Now create the sequence line - var sequenceLine = this.raphael.path("M" + config.leftMargin + " " + config.sequenceLineY + "L" + (config.sizeX-config.rightMargin) + " " + config.sequenceLineY); - sequenceLine.attr({fill: "blue", stroke: "blue", "fill": 1, "stroke-width": 1}); - //Paint the horizontal grid lines - this._paintHorizontalGridLines(config.horizontalGrid, config.horizontalGridNumLines, config.gridLineHeight, config.nonOverlapping, config.leftMargin, config.rightMargin, config.sequenceLineY, config.rulerY, config.sizeX, this.raphael); - }, - - /** - * Private: Paints the slider - * @ignore - */ - _paintSlider: function() {//holder size, left and right margins of the holder, and number of amino acids - if (this.opt.showSlider == true) { - var config = this.opt.json.configuration; - var start = config.requestedStart; - var stop = config.requestedStop; - var sequenceLength = config.sequenceLength; - var slider_div = this._getElementWithinTarget('uniprotFeaturePainter-slider'); - if (!slider_div) { - return; - } - - this.slider_start = start; - this.slider_stop = stop; - slider_div.text(''); - slider_div.append(''); - slider_div.append('
          '); - var myself = this; - this.zoomSlider = jQuery('
          ').appendTo(slider_div); - - //console.log(jQuery('#uniprotFeaturePainter-slider-bar' )); - - this._getElementWithinTarget('uniprotFeaturePainter-slider-bar').slider({ - range: true, - min: 1, - max: sequenceLength, - values: [start, stop], - slide: function(event, ui) { - myself._getElementWithinTarget('uniprotFeaturePainter-slider-values').html('Zoom - Start: '+ui.values[0] + ', End: ' + ui.values[1]); - slider_start = ui.values[0]; - slider_stop = ui.values[1]; - }, - change: function(event, ui) { - myself._repaint(undefined, ui.values[0], ui.values[1]); - } - }); - - this._getElementWithinTarget('uniprotFeaturePainter-slider-values').html('Zoom - Start:' + start + ', End:' + stop); - } - }, - - /** - * Private: Repaints everything: ruler, shapes, and legend. - * @param {boolean} [withoutZoom=false] When false, it zooms according to the slider values. - * @param {int} [newStart] Zoom from this sequence start value. - * @param {int} [newStop] Zoom to this sequence end value. - * @ignore - */ - _repaint: function(withoutZoom, newStart, newStop) { - //recalculate start and stop - var config = this.opt.json.configuration; - if (newStart && newStop){ - this.slider_start = newStart; - this.slider_stop = newStop; - } - if ((this.slider_start != 0) && (this.slider_stop != 0)){ - config.requestedStart = this.slider_start; - config.requestedStop = this.slider_stop; - } - config.unitSize = config.rulerLength / (config.requestedStop-config.requestedStart+1); - this._clear(withoutZoom); - this._paintRuler(); - //recalculate cx, x, and width for features within the ranges - if (!withoutZoom) { - for (var i = 0; i < this.opt.json.featuresArray.length; i++) { - var elem = this.opt.json.featuresArray[i]; - if (!((elem.featureEnd < config.requestedStart) || (elem.featureStart > config.requestedStop))) {//within the range - this._applyZoomToFeature(elem); - } - } - } - this._paintJson(withoutZoom); - this._paintKey(); - }, - - /** - * Private: Function to create slider and print button. - * @param {int} sizeX Width. - * @param {int} sizeY Height for the features holder. - * @param {int} sizeYKey Height for the legend. - * @ignore - */ - _withSliderAndButton: function (sizeX, sizeY, sizeYKey) { - var text = - '' + - '' + - '' + - '' + - '' + - '
          ' + - '
          ' + - '
          ' + - '
          ' + - '' + - '
          ' + - '
          ' + - '
          ' + - '' + - ''; - return text; - }, - /** - * Private: Function to create slider only. - * @param {int} sizeX Width. - * @ignore - */ - _withSliderOnly: function(sizeX) { - var text = - '' + - '' + - '' + - '' + - '
          ' + - '
          ' + - '
          ' + - '
          '; - return text; - }, - /** - * Private: Function to create print button only. - * @param {int} sizeX Width. - * @param {int} sizeY Height for the features holder. - * @param {int} sizeYKey Height for the legend. - * @ignore - */ - _withButtonOnly: function (sizeX, sizeY, sizeYKey) { - var text = - '' + - '' + - '' + - '' + - '
          ' + - '
          ' + - '' + - '
          ' + - '
          ' + - '
          ' + - '' + - ''; - return text; - }, - - /** - * Private: click only rectangle event - * @param myself this object is raising the event. - * @param shapeRectangle Container for shapes, or the shape itself for rectangles. - * @param obj feature object. - * @param eventName Name of the event to be raised. - * @ignore - */ - _raiseEvent: function(myself, shapeRectangle, obj, eventName) { - connection = myself.connections[shapeRectangle.connectionIndex-1]; - if (connection) {//will not enter if undefined in chrome and firefox - try { - shapeRectangle = connection.from; - } catch (error) {} //will be catched in IE - } - myself.raiseEvent(eventName, { - featureId: obj.featureId, - featureLabel: obj.featureLabel, - featureStart: obj.featureStart, - featureEnd: obj.featureEnd, - featureTypeLabel: obj.featureTypeLabel, - typeCode: obj.typeCode, - typeCategory: obj.typeCategory, - evidenceText: obj.evidenceText, - evidenceCode: obj.evidenceCode, - shape: shapeRectangle - }); - }, - - _featureClick: function(onlySelect, myself, raphaelObj, featureObj) { - myself._clickCounter = myself._clickCounter + 1; - if (onlySelect) { - myself._originalColor = raphaelObj.attrs.stroke; - myself._originalFillColor = raphaelObj.attrs.fill; - } else {//both highlight and select - if (myself._clickCounter > 1) {//mouse has not leave the feature (it is down now but up is true already - myself._originalColor = raphaelObj.attrs.stroke; - myself._originalFillColor = raphaelObj.attrs.fill; - } - } - raphaelObj.animate({"fill-opacity": 1.0}, 500); - if (raphaelObj == myself._previousClickedShape) {//the second click will deselect - if (myself._originalColor == myself.opt.selectionColor) { //it is selected, will be deselected - myself._originalColor = myself._previousClickedColor; - myself._originalFillColor = myself._previousClickedFillColor; - raphaelObj.attr({stroke: myself._previousClickedColor, fill: myself._previousClickedFillColor}); - //only select this.animate({"fill-opacity": 1.0}, 500); - featureObj.isSelected = false; - myself._raiseEvent(myself, raphaelObj, featureObj, 'onFeatureUnselected'); - } else { //it is deselected (even counter), will be selected - if (onlySelect || (myself._clickCounter%2 != 0)) { - raphaelObj.attr({stroke: myself.opt.selectionColor, fill: myself.opt.selectionColor}); - raphaelObj.animate({"fill-opacity": 1.0}, 500); - } - featureObj.isSelected = true; - myself._raiseEvent(myself, raphaelObj, featureObj, 'onFeatureSelected'); - } - } else { - //deselect the previous feature - if (myself._previousClickedShape && (myself._previousClickedShape != "")) { - try { - myself._previousClickedShape.attr({stroke: myself._previousClickedColor, fill: myself._previousClickedFillColor}); - myself._previousClickedShape.animate({"fill-opacity": .5}, 500); - myself._previousClickedFeature.isSelected = false; - myself._raiseEvent(myself, myself._previousClickedShape, featureObj, 'onFeatureUnselected'); - } catch (error) {Biojs.console.log(error);} - } - //keep the last clicked shape info - myself._previousClickedColor = myself._originalColor; - myself._previousClickedFillColor = myself._originalFillColor; - myself._previousClickedShape = raphaelObj; - myself._previousClickedFeature = featureObj; - //change colour to highlight colour - if (onlySelect) { - raphaelObj.attr({stroke: myself.opt.selectionColor, fill: myself.opt.selectionColor}); - raphaelObj.animate({"fill-opacity": 1.0}, 500); - } //else : it was already done by the hover function - featureObj.isSelected = true; - myself._raiseEvent(myself, raphaelObj, featureObj, 'onFeatureSelected'); - } - //raise CLICK event - myself._raiseEvent(myself, raphaelObj, featureObj, 'onFeatureClick'); - }, - - /** - * Private: Gets a JSON element representing SVG-features and creates a Rapha�l object and paints features; - * it also adds tooltip and move, mousein, mouseout, and drag events for features. - * @param {Object} obj SVG representation for features. - * @param {int} sequenceLineY Y position for the sequence line. - * @ignore - */ - _paint: function(obj, sequenceLineY) { - var dotRadius = 1; - var shape; - if (obj.type == "path") { - if (obj.featureId || !sequenceLineY) { //feature, must be connected - shape = this.raphael.path(obj.path); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else { //line - var path = this.raphael.path(obj.path); - path.attr({"fill": obj.fill, "stroke": obj.stroke, "stroke-width": obj.strokeWidth}); - } - } else if (obj.type == "text") { - if (obj.featureId || !sequenceLineY) { - shape = this.raphael.text(obj.x, obj.y, obj.text); - shape.attr({"stroke": obj.stroke, "fill-opacity": obj.fillOpacity, "stroke-width": 2}); - } else { - var text = this.raphael.text(obj.x, obj.y, obj.text); - text.attr({"fill": obj.fill}); - } - } else if (obj.type == "circle") { - shape = this.raphael.circle(obj.cx, obj.cy, obj.r); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else if (obj.type == "rect") { - if (obj.width == 0) { //For some really long sequences make sure the rectangle has width. - obj.width = 1; - } - shape = this.raphael.rect(obj.x, obj.y, obj.width, obj.height); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else if (obj.type == "diamond") { - shape = this.raphael.uniprotFeaturePainter_diamond(obj.cx, obj.cy, obj.r); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else if (obj.type == "bridge") { - shape = this.raphael.uniprotFeaturePainter_bridge(obj.cx, obj.cy, obj.width, obj.height); - obj.fill = "none"; - shape.attr({ - "fill": obj.fill, - "stroke": obj.stroke, - "fill-opacity": 0.0 - }); - } else if (obj.type == "triangle") { - shape = this.raphael.uniprotFeaturePainter_triangle(obj.cx, obj.cy, obj.r); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else if (obj.type == "conPath") { //deprecated - var rad = 4; - var vert = 8; - if (obj.text == "N") { - shape = this.raphael.uniprotFeaturePainter_NPath(obj.x, obj.y, rad, vert); - } else if (obj.text == "O") { - shape = this.raphael.uniprotFeaturePainter_OPath(obj.x, obj.y, rad, vert); - } else if (obj.text == "C") { - shape = this.raphael.uniprotFeaturePainter_CPath(obj.x, obj.y, rad, vert); - } else {//C-O-N - //C - rad = 2; - vert = 6; - var space = 4; - shape = this.raphael.uniprotFeaturePainter_CONPath(obj.x, obj.y, rad, vert, space); - } - shape.attr({"stroke": obj.stroke, "fill-opacity": obj.fillOpacity, "stroke-width": 2}); - } else if (obj.type == "wave") { - shape = this.raphael.uniprotFeaturePainter_wave(obj.cx, obj.cy, obj.r); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } else if (obj.type == "hexagon") { - shape = this.raphael.uniprotFeaturePainter_hexagon(obj.cx, obj.cy, obj.r); - shape.attr({"fill": obj.fill, "stroke": obj.stroke, "fill-opacity": obj.fillOpacity}); - } - if (obj.isSelected) { - this._previousClickedShape = shape; - this._previousClickedColor = shape.attrs.stroke; - this._previousClickedFeature = obj; - shape.attr({"fill": this.opt.selectionColor, "stroke": this.opt.selectionColor, "fill-opacity": this.opt.selectionColor}); - } - if (sequenceLineY) { - var myself = this; - if (this.opt.selectFeatureOnMouseClick) {//events are the same for both shapes and rectangles - if (this.opt.highlightFeatureOnMouseOver) { //highlight, select, and raise both over and click events - _clickedShape = false; - shape.click( - function() { - _clickedShape = true; - myself._featureClick(false, myself, this, obj); - } - ); - shape.hover( - function() {//on - myself._originalColor = shape.attrs.stroke; - myself._originalFillColor = shape.attrs.fill; - this.attr({stroke: myself.opt.selectionColor, fill: myself.opt.selectionColor}); - this.animate({"fill-opacity": 1.0}, 500); - //raise ON event - myself._raiseEvent(myself, this, obj, 'onFeatureOn'); - }, - function() {//off - if (!_clickedShape) { //return to the original colour - this.attr({stroke: myself._originalColor, fill: myself._originalFillColor}); - } - _clickedShape = false; - myself._clickCounter = 0; - this.animate({"fill-opacity": .5}, 500); - //raise OFF event - myself._raiseEvent(myself, this, obj, 'onFeatureOff'); - } - ); - } else { //only select, and raise both over and click events - shape.click( - function() { - myself._featureClick(true, myself, this, obj); - } - ); - shape.hover( - function() {//on - //raise ON event - myself._raiseEvent(myself, this, obj, 'onFeatureOn'); - }, - function() {//off - this.animate({"fill-opacity": .5}, 500); - //raise OFF event - myself._raiseEvent(myself, this, obj, 'onFeatureOff'); - } - ); - } - } else { - if (this.opt.highlightFeatureOnMouseOver) { //only highlight, and raise both over and click events - shape.click( - function() { - //raise CLICK event - myself._raiseEvent(myself, this, obj, 'onFeatureClick'); - } - ); - shape.hover( - function() {//on - myself._originalColor = this.attrs.stroke; - myself._originalFillColor = shape.attrs.fill; - this.attr({stroke: myself.opt.selectionColor, fill: myself.opt.selectionColor}); - this.animate({"fill-opacity": 1.0}, 500); - //raise ON event - myself._raiseEvent(myself, this, obj, 'onFeatureOn'); - }, - function() {//off - this.attr({stroke: myself._originalColor, fill: myself._originalFillColor}); - this.animate({"fill-opacity": .5}, 500); - //raise OFF event - myself._raiseEvent(myself, this, obj, 'onFeatureOff'); - } - ); - } else { //raise both over and click events - shape.click( - function() { - //raise CLICK event - myself._raiseEvent(myself, this, obj, 'onFeatureClick'); - } - ); - shape.hover( - function() {//on - //raise ON event - myself._raiseEvent(myself, this, obj, 'onFeatureOn'); - }, - function() {//off - //raise OFF event - myself._raiseEvent(myself, this, obj, 'onFeatureOff'); - } - ); - } - } - if ((obj.type != "rect") && ((obj.type != "bridge"))){ //shapes are movable and have a link to the sequence line - //dragging - if (this.opt.dragSites) { - shape.drag( - function (dx, dy) { //move - if (!this.attr("cx") && !this.attr("x")) {//path (http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js) - var trans_x = dx-this.ox; - var trans_y = dy-this.oy; - this.translate(trans_x,trans_y); - this.ox = dx; - this.oy = dy; - } else { - var att = this.type == "rect" || this.type == "text" - ? {x: this.ox + dx, y: this.oy + dy} - : {cx: this.ox + dx, cy: this.oy + dy}; - this.attr(att); - } - //Repaints all connections - myself.raphael.uniprotFeaturePainter_connection(myself.connections[this.connectionIndex-1]); - myself.raphael.safari(); - }, - function () { //dragger - if (!this.attr("cx") && !this.attr("x")) { //path (http://www.nathancolgate.com/post/2946823151/drag-and-drop-paths-in-raphael-js) - this.ox = 0; - this.oy = 0; - } else { - this.ox = this.type == "rect" || this.type == "text" ? this.attr("x") : this.attr("cx"); - this.oy = this.type == "rect" || this.type == "text" ? this.attr("y") : this.attr("cy"); - } - this.animate({"fill-opacity": 1.0}, 500); - }, - function () { //up - this.animate({"fill-opacity": .5}, 500); - } - ); - } - //dot - var dot = this.raphael.circle(obj.x, sequenceLineY, dotRadius); - dot.attr({"fill": 1, stroke: obj.stroke, "stroke-width": 1}); - //connection - try { - //console.log(obj); - var connectionLine = this.raphael.uniprotFeaturePainter_connection(dot, shape, "#000"); - //console.log(connectionLine); - this.connections.push(connectionLine); - shape.connectionIndex = this.connections.length; - } catch (err) {Biojs.console.log(err);} - } - } - //tooltip - if (this.opt.showFeatureTooltipOnMouseOver == true) { - if (obj.featureId) {//only features in the sequence have tooltips - //console.log(obj); - //console.log(shape); - obj.featureId = obj.featureId.replace(/:|\./g, "_"); - shape.node.id = "uniprotFeaturePainter_" + obj.featureId; - //shape.id = shape.node.id; - var tooltip = obj.featureLabel + - " (" + obj.featureStart + ", " + obj.featureEnd + "; length " + (obj.featureEnd-obj.featureStart+1) + ")" + - "
          Type: " + obj.featureTypeLabel + " - " + obj.typeCode + " - " + obj.typeCategory + - "
          Evidence: " + obj.evidenceText + " - " + obj.evidenceCode; - var myFeatureObj = myself._getElementWithinTarget("uniprotFeaturePainter_" + obj.featureId); - //This one works fine: xph.tooltip.v0.7b - //myFeatureObj.tooltip({text: tooltip}); - //This one works fine: bassistance.de - myFeatureObj.tooltip({ - track: true, - delay: 0, - showURL: false, - bodyHandler: function() { - return tooltip; - } - }); - } - } - this.raphael.safari(); - }, - - /** - * Private: Counts the features per type so they will be correctly displayed on the legend. - * @param {string} keyName Feature type. - * @ignore - */ - _increaseKeyTotal: function(keyName) { - //console.log(key); - var keyShapes = this.opt.json.legend.key; - for (var i = 0; i < keyShapes.length; i++) { - if (keyShapes[i].label.text == keyName) { - keyShapes[i].label.total = keyShapes[i].label.total + 1; - return; - } - } - }, - - /** - * Private: Recalculates (x,y) positions for a particular feature, used when a zoom has been called. - * @param {Object} el Element whose x, y, and width needs to be recalculated according to the new zoom. - * @ignore - */ - _applyZoomToFeature: function(el) { - config = this.opt.json.configuration; - if (config.requestedStart != 1) { - fstart = el.featureStart - config.requestedStart; - fstop = el.featureEnd - config.requestedStart; - } else { - fstart = el.featureStart; - fstop = el.featureEnd; - } - xInit = Math.round(fstart*config.unitSize + config.leftMargin); - xEnd = Math.round(fstop*config.unitSize + config.leftMargin); - width = xEnd - xInit; - if (el.type == 'hexagon') { //typeName == 'Glycosilation' - xInit = xInit - (el.r/2); - } - el.cx = xInit; - el.x = xInit; - el.width = width; - }, - - /** - * Private: Paints the horizontal grid lines. - * @param {boolean} horizontalGrid Should horizontal lines be painted? - * @param {int} horizontalGridNumLines Number of horizontal grid lines to be painted. - * @param {int} gridLineHeight Pixels separation between lines. - * @param {boolean} nonOverlapping Is nonOverlapping style selected? - * @param {int} leftMargin Pixels to left margin. - * @param {int} rightMargin Pixels to right margin. - * @param {int} sequenceLineY Y position for the sequence line. - * @param {int} rulerY Y position for the ruler. - * @param {int} sizeX Width. - * @param {Object} raphael SVG features representation. - * @ignore - */ - _paintHorizontalGridLines: function(horizontalGrid, horizontalGridNumLines, gridLineHeight, nonOverlapping, leftMargin, rightMargin, sequenceLineY, rulerY, sizeX, raphael) { - //Draw the grid lines - if ((horizontalGrid == 'true') || (horizontalGrid == true)) { - for (i = 1; i <= horizontalGridNumLines; i++) { - if (!nonOverlapping) { - var line = raphael.path("M" + leftMargin + " " + (sequenceLineY + i*gridLineHeight) - + "L" + (sizeX-rightMargin) + " " + (sequenceLineY + i*gridLineHeight)); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - var lineUp = raphael.path("M" + leftMargin + " " + (sequenceLineY - i*gridLineHeight) - + "L" + (sizeX-rightMargin) + " " + (sequenceLineY - i*gridLineHeight)); - lineUp.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } else { - var lineUp = raphael.path("M" + leftMargin + " " + (rulerY + (i+1)*gridLineHeight) - + "L" + (sizeX-rightMargin) + " " + (rulerY + (i+1)*gridLineHeight)); - lineUp.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - } - if (!nonOverlapping && (horizontalGridNumLines != 0)) { //we need an extra horizontal grid line at the bottom - var line = raphael.path("M" + leftMargin + " " + (sequenceLineY + (horizontalGridNumLines+1)*gridLineHeight) - + "L" + (sizeX-rightMargin) + " " + (sequenceLineY + (horizontalGridNumLines+1)*gridLineHeight)); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - if (nonOverlapping && (horizontalGridNumLines != 0)) { //we need an extra horizontal grid line at the bottom - var line = raphael.path("M" + leftMargin + " " + (rulerY + (horizontalGridNumLines+2)*gridLineHeight) - + "L" + (sizeX-rightMargin) + " " + (rulerY + (horizontalGridNumLines+2)*gridLineHeight)); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - } - }, - - /** - * Private: Paints the vertical grid lines. - * @param {int} verticalGridLineLength Vertical grid line length. - * @param {int} stop Requested stop for the sequence. - * @param {int} start Requested start for the sequence. - * @param {int} rulerLength Ruler length. - * @param {int} rulerY Y position for the ruler. - * @param {int} pixelsDivision Pixels between amino acids. - * @param {int} leftMargin Pixels to left margin. - * @param {Object} raphael SVG features representation. - * @ignore - */ - _paintVerticalGridLines: function(verticalGridLineLength, stop, start, rulerLength, rulerY, pixelsDivision, leftMargin, raphael) { - //Draw the vertical grid lines - var divisions = 1.0 * rulerLength / pixelsDivision; //number of divisions with label - var divisionValue = 1.0 * (stop-start+1) / divisions; //seed value for labels - var divisionSize = rulerLength / (divisions*10); //inter-divisions - divisions = Math.round(divisions); - divisionValue = Math.round(divisionValue); - for (var i = 1; i < divisions*10; i++) { //10 inter-divisions for each division - var posX = Math.round(i*divisionSize + leftMargin); - if ((divisionValue*i/10) < stop) { - if (i%10 == 0) { - var line = raphael.path("M" + posX + " " + (rulerY+6) + "L" + posX + " " + verticalGridLineLength); - line.attr({stroke: "black", "stroke-width": 0.7, "stroke-opacity": this._GRID_OPACITY}); - } - } - } - }, - - /** - * Modifies the variables in the configuration JSON element related to the style according to the new style to be applied; it also modifies the (x,y) - * positions for all features and the legend. - * @param {string} newStyle New style to be applied - * @ignore - */ - _updateFeaturesToStyle: function (newStyle) { - if (newStyle == this._ROWS) { - this.opt.json.configuration.sequenceLineY = this.opt.json.configuration.sequenceLineYRows; - this.opt.json.configuration.sizeY = this.opt.json.configuration.sizeYRows; - this.opt.json.configuration.verticalGridLineLength = this.opt.json.configuration.verticalGridLineLengthRows; - this.opt.json.configuration.horizontalGridNumLines = this.opt.json.configuration.horizontalGridNumLinesRows; - this.opt.json.legend.segment.yPos = this.opt.json.legend.segment.yPosRows; - this.opt.json.configuration.nonOverlapping = false; - } else if (newStyle == this._NON_OVERLAPPING) { - this.opt.json.configuration.sequenceLineY = this.opt.json.configuration.sequenceLineYNonOverlapping; - this.opt.json.configuration.sizeY = this.opt.json.configuration.sizeYNonOverlapping; - this.opt.json.configuration.verticalGridLineLength = this.opt.json.configuration.verticalGridLineLengthNonOverlapping; - this.opt.json.configuration.horizontalGridNumLines = this.opt.json.configuration.horizontalGridNumLinesNonOverlapping; - this.opt.json.legend.segment.yPos = this.opt.json.legend.segment.yPosNonOverlapping; - this.opt.json.configuration.nonOverlapping = true; - } else { //this._CENTERED - this.opt.json.configuration.sequenceLineY = this.opt.json.configuration.sequenceLineYCentered; - this.opt.json.configuration.sizeY = this.opt.json.configuration.sizeYCentered; - this.opt.json.configuration.verticalGridLineLength = this.opt.json.configuration.verticalGridLineLengthCentered; - this.opt.json.configuration.horizontalGridNumLines = this.opt.json.configuration.horizontalGridNumLinesCentered; - this.opt.json.legend.segment.yPos = this.opt.json.legend.segment.yPosCentered; - this.opt.json.configuration.nonOverlapping = false; - } - for (var i = 0; i < this.opt.json.featuresArray.length; i++) { - var elem = this.opt.json.featuresArray[i]; - if (newStyle == this._ROWS) { - elem.cy = elem.rowsStyle.y; - elem.y = elem.rowsStyle.y; - elem.height = elem.rowsStyle.heightOrRadius; - elem.r = elem.rowsStyle.heightOrRadius; - } else if (newStyle == this._NON_OVERLAPPING) { - elem.cy = elem.nonOverlappingStyle.y; - elem.y = elem.nonOverlappingStyle.y; - elem.height = elem.nonOverlappingStyle.heightOrRadius; - elem.r = elem.nonOverlappingStyle.heightOrRadius; - } else { //this._CENTERED - elem.cy = elem.centeredStyle.y; - elem.y = elem.centeredStyle.y; - elem.height = elem.centeredStyle.heightOrRadius; - elem.r = elem.centeredStyle.heightOrRadius; - } - } - for (var i = 0; i < this.opt.json.legend.key.length; i++) { - var elem = this.opt.json.legend.key[i].shape; - if (newStyle == this._ROWS) { - this.opt.json.legend.key[i].label.yPos = this.opt.json.legend.key[i].label.yPosRows; - elem.cy = elem.rowsStyle.y; - elem.y = elem.rowsStyle.y; - elem.height = elem.rowsStyle.heightOrRadius; - elem.r = elem.rowsStyle.heightOrRadius; - } else if (newStyle == this._NON_OVERLAPPING) { - this.opt.json.legend.key[i].label.yPos = this.opt.json.legend.key[i].label.yPosNonOverlapping; - elem.cy = elem.nonOverlappingStyle.y; - elem.y = elem.nonOverlappingStyle.y; - elem.height = elem.nonOverlappingStyle.heightOrRadius; - elem.r = elem.nonOverlappingStyle.heightOrRadius; - } else { //this._CENTERED - this.opt.json.legend.key[i].label.yPos = this.opt.json.legend.key[i].label.yPosCentered; - elem.cy = elem.centeredStyle.y; - elem.y = elem.centeredStyle.y; - elem.height = elem.centeredStyle.heightOrRadius; - elem.r = elem.centeredStyle.heightOrRadius; - } - } - }, - - /** - * @ignore - **/ - initRaphael: function(){ - //var uniprotFeaturePainter_el; - - /* - * Creates an hexagon <_> (from top to bottom) - * x, y: coordinates of the top vertex - * size: size of the internal square - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_hexagon = function(x, y, size) { - x = x - (size/2); - var path = ["M", x, y]; - path = path.concat(["L", x-size, y+(size/2)]); - path = path.concat(["L", x, y+size]); - path = path.concat(["L", x+size, y+size]); - path = path.concat(["L", x+size+size, y+(size/2)]); - path = path.concat(["L", x+size, y]); - return this.path(path.concat(["Z"]).join(" ")); - }; - /* - * Creates a triangle /_\ (fro top to bottom) - * x, y: coordinates of the top vertex - * size: size of the bottom edge - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_triangle = function(x, y, size) { - var path = ["M", x, y]; - path = path.concat(["L", (x + size / 2), (y + size)]); - path = path.concat(["L", (x - size / 2), (y + size)]); - return this.path(path.concat(["Z"]).join(" ")); - }; - /* - * Creates a wave (from top to bottom) - * /\/\ - * |/\/\| - * x, y: coordinates of the lowest top centered vertex /\./\ - * size: size of the bottom edge of the sub-triangles /_\ - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_wave = function(x, y, size) { - var path = ["M", x, y]; - path = path.concat(["L", x-(size/2), y-size]); // \ - path = path.concat(["L", x-size, y]); // / - path = path.concat(["L", x-size, y+size]); // | - path = path.concat(["L", x-(size/2), y+(size/2)]); // / - path = path.concat(["L", x, y+size]); // \ first wave - path = path.concat(["L", x+(size/2), y+(size/2)]); // / - path = path.concat(["L", x+size, y+size]); // \ - path = path.concat(["L", x+size, y]); // | - path = path.concat(["L", x+(size/2), y-size]); // \ - return this.path(path.concat(["Z"]).join(" ")); - } - /* - * Creates a diamond (from top to bottom) - * x, y: coordinates of the top vertex - * r: radius from the center - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_diamond = function(x, y, r) { - var path = ["M", x, y]; - path = path.concat(["L", x-r, y+r]); - path = path.concat(["L", x, y+(r*2)]); - path = path.concat(["L", x+r, y+r]); - return (this.path(path.concat(["Z"].join(" ")))); - } - /** - * Creates a bridge - * @param x coordinate - * @param y coordinate - * @param width - * @param height - * @returns {*|Array} - */ - Raphael.fn.uniprotFeaturePainter_bridge = function (x, y, width, height) { - //console.log(x,y,width, height); - var path = ["M", x, y-1]; - path = path.concat(["L", x , y - 1 - height]); - path = path.concat(["L", x + width , y - 1 - height ]); - path = path.concat(["L", x+ width, y - 1 ]); - return (this.path(path)); - } - /* - * Creates an N path - * x, y: coordinates of the letter (as it would be painted as a String) - * width - * height - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_NPath = function(x, y, width, height) { - var path = ["M", (x-width),(y+height)]; - path = path.concat(["L", (x-width), y]); - path = path.concat(["L", (x+width), (y+height-1)]); - path = path.concat(["L", (x+width),(y-1)]); - return (this.path(path)); - } - /* - * Creates an O path - * x, y: coordinates of the letter (as it would be painted as a String) - * width - * height - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_OPath = function(x, y, width, height) { - var path = ["M", (x), (y)]; - path = path.concat(["C", (x-width), (y), (x-width), (y+height), (x), (y+height)]); - path = path.concat(["M", (x), (y)]); - path = path.concat(["C", (x+width), (y), (x+width), (y+height), (x), (y+height)]); - return (this.path(path)); - } - /* - * Creates a C path - * x, y: coordinates of the letter (as it would be painted as a String) - * width - * height - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_CPath = function(x, y, width, height) { - var path = ["M", (x+width), (y)]; - path = path.concat(["C", (x-width), (y), (x-width), (y+height), (x+width), (y+height)]); - return (this.path(path)); - } - /* - * Creates a C-O-N path - * x, y: coordinates of the letter (as it would be painted as a String) - * width - * height - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_CONPath = function(x, y, width, height, space) { - //C - var path = ["M", (x-width-space), (y)]; - path = path.concat(["C", (x-width-space-(width*2)), (y), (x-width-space-(width*2)), (y+height), (x-width-space), (y+height)]); - //- - path = path.concat(["M", (x-width-space+1), (y+height/2)]); - path = path.concat(["L", (x-width-1), (y+height/2)]); - //O - path = path.concat(["M", (x), (y)]); - path = path.concat(["C", (x-width), (y), (x-width), (y+height), (x), (y+height)]); - path = path.concat(["M", (x), (y)]); - path = path.concat(["C", (x+width), (y), (x+width), (y+height), (x), (y+height)]); - //- - path = path.concat(["M", (x+width+1), (y+height/2)]); - path = path.concat(["L", (x+width+space-1), (y+height/2)]); - //N - path = path.concat(["M", (x+width+space), (y+height)]); - path = path.concat(["L", (x+width+space), y-2]); - path = path.concat(["L", (x+width*3+space), (y+height)]); - path = path.concat(["L", (x+width*3+space), (y-2)]); - return (this.path(path)); - } - /* - * Creates a dynamic connection (from http://raphaeljs.com/graffle.html) - */ - /** - * @ignore - **/ - Raphael.fn.uniprotFeaturePainter_connection = function (obj1, obj2, line, bg) { - //console.log('connection'); - //console.log(obj1); - //console.log(obj2); - if (obj1.line && obj1.from && obj1.to) { - //console.log('if'); - line = obj1; - obj1 = line.from; - obj2 = line.to; - } - var bb1 = obj1.getBBox(); //console.log('bb1'); console.log(bb1); - if ((!bb1.x) && (obj1.type == "circle")) { //it should not be necessary but it fails to get the BBox the first time the widget is called by ajax - //console.log('!bb1 and circle'); - bb1 = {height: obj1.attrs.r*2, width: obj1.attrs.r*2, x: obj1.attrs.cx-obj1.attrs.r, y:obj1.attrs.cy-obj1.attrs.r}; - //console.log(bb1); - } - var bb2 = obj2.getBBox(); //console.log('bb2'); //console.log(bb2); - if ((!bb2.x) && (obj2.type == "circle")) { //it should not be necessary but it fails to get the BBox the first time the widget is called by ajax - //console.log('!bb2 and circle'); - bb2 = {height: obj2.attrs.r*2, width: obj2.attrs.r*2, x: obj2.attrs.cx-obj2.attrs.r, y:obj2.attrs.cy-obj2.attrs.r}; - //console.log(bb1); - } - var p = [{x: bb1.x + bb1.width / 2, y: bb1.y - 1}, - {x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1}, - {x: bb1.x - 1, y: bb1.y + bb1.height / 2}, - {x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2}, - {x: bb2.x + bb2.width / 2, y: bb2.y - 1}, - {x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1}, - {x: bb2.x - 1, y: bb2.y + bb2.height / 2}, - {x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2}], - d = {}, dis = []; - //console.log('p'); console.log(p); - for (var i = 0; i < 4; i++) { - for (var j = 4; j < 8; j++) { - var dx = Math.abs(p[i].x - p[j].x), - dy = Math.abs(p[i].y - p[j].y); - if ((i == j - 4) || (((i != 3 && j != 6) || p[i].x < p[j].x) && ((i != 2 && j != 7) || p[i].x > p[j].x) && ((i != 0 && j != 5) || p[i].y > p[j].y) && ((i != 1 && j != 4) || p[i].y < p[j].y))) { - dis.push(dx + dy); - d[dis[dis.length - 1]] = [i, j]; - } - } - } - if (dis.length == 0) { - var res = [0, 4]; - } else { - res = d[Math.min.apply(Math, dis)]; - } - var x1 = p[res[0]].x, - y1 = p[res[0]].y, - x4 = p[res[1]].x, - y4 = p[res[1]].y; - dx = Math.max(Math.abs(x1 - x4) / 2, 10); - dy = Math.max(Math.abs(y1 - y4) / 2, 10); - var x2 = [x1, x1, x1 - dx, x1 + dx][res[0]].toFixed(3), - y2 = [y1 - dy, y1 + dy, y1, y1][res[0]].toFixed(3), - x3 = [0, 0, 0, 0, x4, x4, x4 - dx, x4 + dx][res[1]].toFixed(3), - y3 = [0, 0, 0, 0, y1 + dy, y1 - dy, y4, y4][res[1]].toFixed(3); - var path = ["M", x1.toFixed(3), y1.toFixed(3), "C", x2, y2, x3, y3, x4.toFixed(3), y4.toFixed(3)].join(","); - if (line && line.line) { - line.bg && line.bg.attr({path: path}); - line.line.attr({path: path}); - } else { - var color = typeof line == "string" ? line : "#000"; - return { - bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}), - line: this.path(path).attr({stroke: color, fill: "none"}), - from: obj1, - to: obj2 - }; - } - }; - } - }); - -var Biojs_FeatureViewer_array = new Array(); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.GeneExpressionSummary.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.GeneExpressionSummary.js deleted file mode 100755 index aee7783390..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.GeneExpressionSummary.js +++ /dev/null @@ -1,434 +0,0 @@ -/** - * Gene expression summary - * - * @class - * @extends Biojs - * - * @author John Gomez-Carvajal, Rafael Jimenez - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires GeneExpressionSummary.css - * @dependency - * - * @param {Object} options An object with the options for Sequence component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} identifier - * ENSEMBL gene identifier or UniProt Acc needed as input to fetch the Gene expression summary data - * - * @option {string} [featuresUrl='http://www-test.ebi.ac.uk/gxa/das/s4/features'] - * Url of the REST service which provides the summary data. - * - * @option {string} [legend=true] - * Option to display the provenance legend. - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * This component needs to request data from a web service. To bypass the same origin policy - * (http://en.wikipedia.org/wiki/Same_origin_policy) this component needs a proxy. - * You could use your own proxy by modifying this value or one of the BioJS proxies: - * '../biojs/dependencies/proxy/proxy.php' or '../biojs/dependencies/proxy/proxy.jsp' - * - * @example - * var instance = new Biojs.GeneExpressionSummary({ - * target: 'YourOwnDivId', - * identifier: 'ENSG00000066279' - * }); - * - */ -Biojs.GeneExpressionSummary = Biojs.extend( -/** @lends Biojs.GeneExpressionSummary# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - this.setIdentifier(this.opt.identifier); - }, - - /** - * Default values for the options - * @name Biojs.GeneExpressionSummary-opt - */ - opt: { - target: "YourOwnDivId", - identifier: undefined, - featuresUrl: 'http://www-test.ebi.ac.uk/gxa/das/s4/features', - legend: true, - proxyUrl: '../biojs/dependencies/proxy/proxy.php' - }, - - /** - * Array containing the supported event names - * @name Biojs.GeneExpressionSummary-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.GeneExpressionSummary#onRequestError - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onRequestError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - **/ - "onRequestError", - /** - * @name Biojs.GeneExpressionSummary#onDbError - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onDbError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - **/ - "onDbError" - ], - /** - * Fetch the data by means of identifier. - * @param {string} identifier The segment identifier. - * - * @example - * instance.setIdentifier("ENSG00000100867"); - * - * @example - * instance.setIdentifier("Q61171"); - * - * @example - * instance.setIdentifier("ENSG000000000000"); - * - * @example - * instance.setIdentifier("P00000"); - * - */ - setIdentifier: function(id){ - this._drawTemplate(); - /* Uniprot or Ensembl ID? */ - this._identifierDb = this._checkIdentifier(id); - if(this._identifierDb == Biojs.GeneExpressionSummary.ID_UNIPROT){ - this._requestFeaturesFromUniprotAcc(id); - } else if (this._identifierDb == Biojs.GeneExpressionSummary.ID_ENSEMBL){ - this._requestFeatures(id); - } else { - this._processDbError(id); - } - }, - /* - * Function: Biojs.GeneExpressionSummary._drawTemplate - * Purpose: Draw HTML template used for placing the data afterwards - * Returns: - - * Inputs: - - */ - _drawTemplate: function(){ - this._selector = "#" + this.opt.target; - this._container = jQuery(this._selector); - this._container.html(""); - - this._container.addClass("GeneExpressionSummary"); - this._title = jQuery('
          ').appendTo(this._container); - - this._table = jQuery('
          ').appendTo(this._container); - this._row = jQuery("").appendTo(this._table); - this._leftColumn = jQuery("").appendTo(this._row); - this._rightColumn = jQuery("").appendTo(this._row); - - - - this._imageContainer = jQuery('
          ').appendTo(this._rightColumn); - this._summaryContainer = jQuery('
          ').appendTo(this._leftColumn); - this._footerContainer = jQuery('').appendTo(this._container); - }, - /* - * Function: Biojs.GeneExpressionSummary._checkIdentifier - * Purpose: Check if the indetifier provided by the user is ENSEMBL or UniProt - * Returns: Database name (uniprot or ensembl) - * Inputs: id -> {String} Identifier. - */ - _checkIdentifier: function(id){ - var self = this; - self._re = /^([A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])$/; - if (id.search(self._re) != -1){ - return Biojs.GeneExpressionSummary.ID_UNIPROT; - } else if(id.substring(0,4) == "ENSG"){ - return Biojs.GeneExpressionSummary.ID_ENSEMBL; - } - }, - /* - * Function: Biojs.GeneExpressionSummary._requestFeatures - * Purpose: Start a request using an ENSEMBL identifier - * Returns: - - * Inputs: id -> {String} Identifier. - */ - _requestFeatures: function( identifier ) { - if ( undefined !== identifier) { - if (identifier.length > 0) { - this.opt.identifier = identifier; - this._requestFeaturesXML(this.opt); - } else { - Biojs.console.log("no identifier value available"); - this._displayNoDataMessage(); - } - } else { - Biojs.console.log("identifier value is not valid"); - this._displayNoDataMessage(); - } - }, - - /* - * Function: Biojs.GeneExpressionSummary._requestFeaturesXML - * Purpose: Request data to the server - * Returns: - - * Inputs: opt -> {Object} options object. - */ - _requestFeaturesXML: function( opt ){ - var self = this; - var httpRequest = { - url: opt.featuresUrl, - data: "segment=" + opt.identifier, - methid: "GET", - /** @ignore No need to document this object */ - success: function(xml){ - Biojs.console.log("SUCCESS: data received"); - self._responseReceived(xml); - }, - error: this._processErrorRequest - }; - - // Using proxy? - // Redirect using the proxy and encode all params as url data - if ( opt.proxyUrl != undefined ) { - - // Redirect to proxy url - httpRequest.url = opt.proxyUrl; - - // Encode both url and parameters under the param url - httpRequest.data = [{ name: "url", value: opt.featuresUrl + "?segment="+opt.identifier }]; - - // Data type - httpRequest.dataType = "text"; - } - - jQuery.ajax(httpRequest); - - }, - - /* - * Function: Biojs.GeneExpressionSummary._responseReceived - * Purpose: Parses the xml file from the request and stores the information in an easy to access way - * Returns: {object[]} -> decoded features - * Inputs: xml -> {string} xml with the features. - */ - _responseReceived: function( xml ){ - var self = this; - var xmlDoc = ""; - var features = []; - - Biojs.console.log("Decoding " + xml); - - try { - xmlDoc = jQuery.parseXML( xml ); - - } catch (e) { - Biojs.console.log("ERROR decoding "); - Biojs.console.log(e); - } - - jQuery(xmlDoc).find('FEATURE') - .each( function(){ - features.push( self._decodeFeature(this) ); - }); - - if (features.length > 0) { - Biojs.console.log("Features decoded:"); - Biojs.console.log(features); - this._setFeatures(features); - } else { - this._displayNoDataMessage(); - } - }, - _displayNoDataMessage: function(){ - jQuery('#'+this.opt.target+'').html(Biojs.GeneExpressionSummary.MESSAGE_NODATA); - }, - - /* - * Function: Biojs.GeneExpressionSummary._requestFeaturesXML - * Purpose: Convert a feature from XML to js object - * Returns: {object} js object containing the data of the feature - * Inputs: featureNode -> {Node} The DOM Node - */ - _decodeFeature: function ( featureNode ) { - - Biojs.console.log("Decoding feature" + featureNode ); - - var feature = this._decodeNode( featureNode ); - - // Get the children of the feature node - var children = jQuery( featureNode ).children(); - - // Decode each child - for ( i = 0; i < children.length; i++ ) { - var objChild = this._decodeNode(children[i]); - - // Add child to the feature - if ( "NOTE" == children[i].nodeName ) { - if (feature[ children[i].nodeName ] == undefined ) feature[ children[i].nodeName ] = []; - feature[ children[i].nodeName ].push( objChild ); - } else { - feature[ children[i].nodeName ] = objChild; - } - } - - return feature; - }, - - /* - * Function: Biojs.GeneExpressionSummary._decodeNode - * Purpose: Convert a node to a js object - * Returns: {object} js object containing the data of the node - * Inputs: node -> {Node} The DOM Node - */ - _decodeNode: function (node) { - var obj = {} - - // Get attributes - jQuery.each( node.attributes, function(index, attr) { - obj[ attr.nodeName ] = attr.nodeValue; - }); - obj["text"] = jQuery(node).text(); - - return obj; - }, - - /* - * Function: Biojs.GeneExpressionSummary._setFeatures - * Purpose: Build the HTML in this container using the provided features object. - * Returns: - - * Inputs: f -> {object} Features to be displayed - */ - _setFeatures: function ( f ) { - - // Flush the containers - this._title.text(''); - this._imageContainer.text(''); - this._summaryContainer.text(''); - this._footerContainer.text(''); - - var self = this; - for ( i = 0; i < f.length; i++ ) { - var feature = f[i]; - if ( Biojs.GeneExpressionSummary.TYPE_DESCRIPTION == feature.TYPE.id ) { - this._title.text( feature.NOTE[0].text ); - - } else if ( Biojs.GeneExpressionSummary.TYPE_IMAGE == feature.TYPE.id ) { - var image = jQuery('').appendTo(this._imageContainer); - image.css("width","100%"); - image.css("height","auto"); - var caption = '

          '+ feature.LINK.text; - this._imageContainer.append(caption); - } else if ( Biojs.GeneExpressionSummary.TYPE_PROVENANCE == feature.TYPE.id && self.opt.legend == true) { - var footer = ''; - for ( n in feature.NOTE ) { - footer += feature.NOTE[n].text + ' '; - } - footer += ''+ feature.LINK.href + ''; - this._footerContainer.append(footer); - - } else { - var summary = '

          ' + feature.label + '
          '; - summary += '
          ' + feature.NOTE[0].text; - if(typeof feature.LINK != 'undefined'){ - summary += ' view all
          '; - } - this._summaryContainer.append(summary); - } - - } - }, - /* - * Function: Biojs.GeneExpressionSummary._requestFeaturesFromUniprotAcc - * Purpose: Start a request using a UniProt identifier - * Returns: - - * Inputs: id -> {String} UniProt identifier. - */ - _requestFeaturesFromUniprotAcc: function(id){ - var self = this; - /* URL where to get the mapping to an EMSEMBL id */ - self._serviceUrl = "http://www.ebi.ac.uk/uniprot/biomart/martservice?query=%3C?xml%20version=%221.0%22%20encoding=%22UTF-8%22?%3E%3C!DOCTYPE%20Query%3E%3CQuery%20%20virtualSchemaName%20=%20%22default%22%20formatter%20=%20%22TSV%22%20header%20=%20%220%22%20uniqueRows%20=%20%221%22%20count%20=%20%22%22%20datasetConfigVersion%20=%20%220.6%22%20%3E%3CDataset%20name%20=%20%22uniprot%22%20interface%20=%20%22default%22%20%3E%3CFilter%20name%20=%20%22accession%22%20value%20=%20%22" - self._serviceUrl += id; - self._serviceUrl += "%22/%3E%3CAttribute%20name%20=%20%22ensembl_id%22%20/%3E%3C/Dataset%3E%3C/Query%3E"; - self._url = ""; - if(self.opt.proxyUrl != ""){ - self._url= self.opt.proxyUrl + "?url=" + self._serviceUrl; - } else { - self._url= self._serviceUrl; - } - - /* process service */ - jQuery.ajax({ - type: "GET", - url: self._url, - dataType: "text", - success: function(a){self._requestFeatures(a);}, - error: function(a){self._processErrorRequest(a);} - }); - }, - /* - * Function: Biojs.GeneExpressionSummary._processErrorRequest - * Purpose: Process request error - * Returns: - - * Inputs: textStatus -> {String} Text status - */ - _processErrorRequest: function (textStatus){ - Biojs.console.log("ERROR: " + textStatus ); - self.raiseEvent( Biojs.GeneExpressionSummary.EVT_ON_REQUEST_ERROR, { message: textStatus } ); - }, - /* - * Function: Biojs.GeneExpressionSummary._processDbError - * Purpose: Process DB error - * Returns: - - * Inputs: id -> {String} Identifier. - */ - _processDbError: function (id){ - var self = this; - self._message = "Not recognize identifier: " + id; - Biojs.console.log("ERROR: " + self._message ); - self.raiseEvent( Biojs.GeneExpressionSummary.EVT_ON_DB_ERROR, { message: self._message } ); - } - -},{ - // Some static values - - // Events - EVT_ON_REQUEST_ERROR: "onRequestError", - EVT_ON_DB_ERROR: "onDbError", - - ID_UNIPROT: "uniprot", - ID_ENSEMBL: "ensembl", - MESSAGE_NODATA: "Sorry, we could not find summary data for your request", - - // Feature types - TYPE_IMAGE: "image", - TYPE_SUMMARY: "summary", - TYPE_DESCRIPTION: "description", - TYPE_PROVENANCE: "atlas-provenance" - -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.HeatmapViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.HeatmapViewer.js deleted file mode 100755 index f7a4d997d7..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.HeatmapViewer.js +++ /dev/null @@ -1,652 +0,0 @@ -/** - * - * This component takes a JSON data object and draws a D3 object - * The expected JSON format is specified under the option 'json' of the HeatmapViewer options. - * - * Please remember to use jQuery in compatibility mode, particularly a good idea if you use other libraries. - * - * @class - * @extends Biojs - * - * @author Guy Yachdav - * @version 1.0.0 - * @category 2 - * - * @requires jQuery Core 1.9.1 - * @dependency - * - * @requires D3 Version 3 - * @dependency - * - * @param {Object} options An object with the options for HeatmapViewer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} jsonData - * The jsonData object contains the data to be displayed - * The jsonData object must follow this format: - * - * [{ - * col: int, // columns position - * row: int, // row position - * label: string, // column label - * score: float, // cell's score - * row_label: string // row label - * }] - * - * Example 4 items grid - *
          - *    		[{
          - *		    "col": 0,
          - *		    "row": 0,
          - *		    "label": "M",
          - *		    "score": 27,
          - *		    "row_label": "A"
          - *		}, {
          - *		    "col": 0,
          - *		    "row": 1,
          - *		    "label": "M",
          - *		    "score": 5,
          - *		    "row_label": "C"
          - *		}, {
          - *		    "col": 1,
          - *		    "row": 0,
          - *		    "label": "M",
          - *		    "score": 43,
          - *		    "row_label": "D"
          - *		}, {
          - *		    "col": 1,
          - *		    "row": 1,
          - *		    "label": "M",
          - *		    "score": 58,
          - *		    "row_label": "E"
          - *		}]
          - *	
          - * - * @option {Onject} [user_defined_config={colorLow: 'blue', colorMed: 'white', colorHigh: 'red'}] - * Configuration options for the component - * - * @option {Onject} [show_zoom_panel=true] - * Display the zoom panel. default: true - * - * @option {Onject} [showScale=true] - * Display the scale object. default: true - * - * @example - * var painter = new Biojs.HeatmapViewer({ - * jsonData: - * [{ - * "col": 0, - * "row": 0, - * "label": "M", - * "score": 27, - * "row_label": "A" - * }, { - * "col": 0, - * "row": 1, - * "label": "M", - * "score": 5, - * "row_label": "C" - * }, { - * "col": 1, - * "row": 0, - * "label": "M", - * "score": 43, - * "row_label": "D" - * }, { - * "col": 1, - * "row": 1, - * "label": "M", - * "score": 58, - * "row_label": "E" - * }], - * user_defined_config: { - * colorLow: 'blue', - * colorMed: 'white', - * colorHigh: 'red' - * }, - * target: 'YourOwnDivId' - * }); - * - */ - -Biojs.HeatmapViewer = Biojs.extend( - /** @lends Biojs.HeatmapViewer */ - { - - /** - * public variables - */ - target: undefined, - - /** - * private variables - */ - _MAIN_HEAT_MAP_DIV: 'main_heatmap_div', - _ZOOM_HEAT_MAP_DIV: 'zoom_heatmap_div', - _SLIDER_DIV: 'slider_heatmap_div', - _SCALE_DIV: 'scale_div', - - _origData: undefined, - _zoomedData: undefined, - - viewer_config: { - dimensions: {}, - displayDiv: '', - colorLow: 'green', - colorMed: 'white', - colorHigh: 'red', - scoreLow: -100, - scoreMed: 0, - scoreHigh: 100, - offset: 0, - x_axis: [], - y_axis: [], - canvas_margin: { - top: 30, - right: 30, - bottom: 30, - left: 30 - }, - labels: { - max_font_size: 20, - min_font_size: 11 - }, - main_heatmap: { - min_cell_width: 2, - max_cell_width: 100, - orig_cell_width: 0 - }, - zoom_area: { - cell_width: 20 - }, - slider: { - start_value: 0, - increments: 50 - } - - }, - - constructor: function(options) { - this._origData = this.opt.jsonData; - this.target = this.opt.target; - this._init(); - this._draw(); - - }, - - opt: { - /** - * Default values for the options: - * target: "YourOwnDivId", - * jsonData: {}, - * showScale: true, - * showExportToImageButton: false, - * @name Biojs.HeatmapViewer-opt - */ - target: 'YourOwnDivId', - jsonData: {}, - showScale: true, - showExportToImageButton: false, - show_zoom_panel: true - }, - - eventTypes: [ - - /* Event Names - The parent class Biojs build the event handlers automatically - with the names defined here. Use this.raiseEvent(, - ) for triggering an event from this component. Where, - is a string (defined in eventTypes) and is - an object which should be passed to the registered listeners. - - Define your event names following the syntax: - “”, - “”, - : - . - “” - */ - ], - - SCALE: (function($) { - var data_array = []; - var my = {}; - var dataLow, dataMid, dataHigh; - var colorLow, colorMid, colorHigh; - var target; - var svg; - var d, i; - - var drag = d3.behavior.drag() - .on("drag", function(d, i) { - d.x += d3.event.dx - d3.select(this).attr("transform", function(d, i) { - return "translate(" + [d.x] + ",20)" - }) - }); - - /** - * [init description] - * @param {[type]} _config [description] - * @return {[type]} [description] - */ - my.init = function(_config) { - var scoreLow = _config.scoreLow; - var scoreMid = _config.scoreMid; - var scoreHigh = _config.scoreHigh; - var colorLow = _config.colorLow; - var colorMid = _config.colorMid; - var colorHigh = _config.colorHigh; - var target = _config.target; - - for (var idx = scoreLow; idx <= scoreHigh; idx++) - data_array.push(idx); - - var width = 960, - height = 200; - - var colorScale = d3.scale.linear() - .domain([scoreLow, scoreMid, scoreHigh]) - .range([colorLow, colorMid, colorHigh]); - - var x = 50, - y = 20; - - var svg = d3.select("#" + target) - .append("svg").attr("id", target + "_svg") - .attr("width", "100%") - // .attr("width", heatmapviewer_config.heatmap_config.dimensions.canvas_width + heatmapviewer_config.heatmap_config.canvas_margin.right + heatmapviewer_config.heatmap_config.canvas_margin.left) - .attr("height", "40"); - - var g = svg.append("g") - .data([{ - "x": x, - "y": y - }]) - .attr("transform", "translate(" + x + ",20)") - .call(drag); - - g.selectAll("lines") - .data(data_array) - .enter().append("svg:line") - .attr("x1", function(d, i) { - return i; - }) - .attr("y1", 0) - .attr("x2", function(d, i) { - return i; - }) - .attr("y1", 20) - .style("stroke", function(d) { - return (colorScale(d)); - }) - .style("stroke-width", 5); - - g.append("text") - .attr("y", -5) - .attr("x", -15) - .text(-100) - .attr("transform", "translate(0, 0 )"); - - var midPt = data_array.length / 2; - g.append("text") - .attr("class", "caption") - .attr("y", -5) - .attr("x", midPt - 2) - .text(0); - var maxPt = data_array.length; - - g.append("text") - .attr("class", "caption") - .attr("y", -5) - .attr("x", maxPt - 2) - .text(100); - } - return my; - }(jQuery)), - -/** - * Public module that renders a heatmap - * @param {[type]} $ [description] - * @return {[type]} [description] - */ - HEATMAP: (function($) { - var svg; - var my = {}; - - var max_font_size = 20, - min_font_size = 11; - - var jsonData = undefined, - target = undefined; - - var config = { - axis_line_stroke: '2', - axis_line_stroke_color: '#000', - dimensions: { - canvas_width: 0, - canvas_height: 0, - cell_width: 0, - cell_height: 0, - cell_count: 0, - row_count: 0 - }, - x_axis: [], - y_axis: [], - jsonData: {}, - offset: 0, - show_frame: true - - }; - - my.settarget = function(_target) { - target = _target; - return my; - }, - my.gettarget = function() { - return this.target; - } - my.init = function(_configObj, _jsonData, _targteDiv) { - config = $.extend(config, _configObj); - this.settarget(_targteDiv); - jsonData = _jsonData; - return my; - } - getData = function(argument) { - return jsonData; - } - - var draw_axis = function() { - var d, i; - var font_size = Math.min((config.dimensions.cell_width - 10), max_font_size); - var myHorizontalAxisLine = svg.append("svg:line") - .attr("x1", 0) - .attr("y1", 0 - 3) - .attr("x2", config.dimensions.cell_width * (config.dimensions.cell_count + 1)) - .attr("y2", 0 - 3) - .style("stroke", config.axis_line_stroke_color) - .style("stroke-width", config.axis_line_stroke); - - - var myVerticalAxisLine = svg.append("svg:line") - .attr("x1", 0 - 5) - .attr("y1", 0) - .attr("x2", 0 - 5) - .attr("y2", config.dimensions.canvas_height) - .style("stroke", config.axis_line_stroke_color) - .style("stroke-width", config.axis_line_stroke); - - - svg.selectAll("x_axis").data(config.x_axis).enter().append("text").style("font-size", font_size).text(function(d) { - return d; - }).attr("x", function(d, i) { - return i * config.dimensions.cell_width; - }).attr("y", function(d) { - return -5; - }); - - // TODO rework positioning - svg.selectAll("y_axis").data(config.y_axis).enter().append("text").style("font-size", font_size).text(function(d) { - return d; - }).attr("x", function(d) { - return (config.canvas_margin.right - 5) * -1; - }).attr("y", function(d, i) { - return i * config.dimensions.cell_width + config.dimensions.cell_width; - }); - } - - my.draw = function() { - draw_heatmap(); - // present axis only if the computed size for the font is more then the set threshold size - if (config.dimensions.cell_width > min_font_size) - draw_axis(); - } - - /** - * [draw_heatmap description] - * @param {[type]} argument - * @return {[type]} - */ - var draw_heatmap = function(argument) { - - svg = d3.select("#" + target) - .append("svg").attr("id", target + "_svg") - .attr("width", config.dimensions.canvas_width + config.canvas_margin.right + config.canvas_margin.left) - .attr("height", config.dimensions.canvas_height + config.canvas_margin.top + config.canvas_margin.bottom) - .append("g") - .attr("transform", "translate(" + config.canvas_margin.right + "," + config.canvas_margin.top + ")"); - - - var colorScale = d3.scale.linear() - .domain([config.scoreLow, config.scoreMed, config.scoreHigh]) - .range([config.colorLow, config.colorMed, config.colorHigh]); - - - svg.selectAll(".heatmapDiv") - .data(getData(), function(d) { - return d.col + ': ' + d.row; - }) - .enter().append("svg:rect") - .attr("x", function(d) { - return (d.col - config.offset) * config.dimensions.cell_width; - }) - .attr("y", function(d) { - return d.row * config.dimensions.cell_height; - }) - .attr("width", function(d) { - return config.dimensions.cell_width; - }) - .attr("height", function(d) { - return config.dimensions.cell_height; - }) - .style("fill", function(d) { - if (d.label == d.row_label) return ('black '); - else return colorScale(d.score); - }) - .append("svg:title") - .text(function(d) { - return d.label + d.col + d.row_label + " Score: " + d.score; - }); - } - return my; - }(jQuery)), - /** - * Private: renders a sliding frame on top of main matrix to show zoomed in area - * @param {Object} _config viewer's configuration - * @ignore - */ - _show_sliding_window: function(_config) { - var myself = this; - var current_x; - var dimensions = _config.dimensions; - var svg = _config.svg; - var max_frame = dimensions.cell_width * dimensions.cell_count - dimensions.frame_width; - var x = y = 0; - var d, i; - var drag = d3.behavior.drag() - .on("dragend", function(d, i) { - if (d.x < 0) - d.x = 0; - if (d.x > max_frame) - d.x = max_frame; - current_x = d.x; - myself._drawZoomDiv(d); - d3.select(this).style('cursor', '-webkit-grab'); - d3.select(this).style('cursor', '-moz-grab'); - }) - .on("drag", function(d, i) { - d.x += d3.event.dx; - d.y += d3.event.dy; - d3.select(this).attr("transform", function(d, i) { - if (d.x < 0) - return "translate(0)"; - if (d.x > max_frame) - return "translate(" + (max_frame + 10) + ")"; - - d3.select(this).style('cursor', '-webkit-grabbing'); - d3.select(this).style('cursor', '-moz-grabbing'); - return "translate(" + [d.x] + ")"; - }) - }); - - svg.append("svg:rect") - .attr("x", 0) - .attr("y", -5) - .attr("width", dimensions.frame_width) - .attr("height", dimensions.height + 15) - .style("fill-opacity", 0) - .style("stroke", "blue") - .style("stroke-width", 4) - .style("cursor", "-webkit-grab") - .style("cursor", "-moz-grab") - .data([{ - "x": x - }]) - .attr("transform", "translate(" + x + "," + y + ")") - .call(drag); - }, - - /** - * Private: renders the viewer object - * @ignore - */ - _draw: function() { - var $hmDiv = jQuery("#" + this.opt.target); - - [this._MAIN_HEAT_MAP_DIV, this._SCALE_DIV, this._ZOOM_HEAT_MAP_DIV].forEach(function(entry) { - $hmDiv.append(jQuery('
          ') - .attr('id', entry) - .css('width', '75%') - .css('margin', '25px')); - }); - this.HEATMAP.init(this.viewer_config, this._origData, this._MAIN_HEAT_MAP_DIV).draw(); - - - if (this.opt.showScale) - this.SCALE.init({ - colorLow: this.viewer_config.colorLow, - colorMid: this.viewer_config.colorMed, - colorHigh: this.viewer_config.colorHigh, - scoreLow: this.viewer_config.scoreLow, - scoreMid: this.viewer_config.scoreMed, - scoreHigh: this.viewer_config.scoreHigh, - target: this._SCALE_DIV - - }) - - if (this.viewer_config.dimensions.cell_width < this.viewer_config.labels.min_font_size) { - this.viewer_config.main_heatmap.orig_cell_width = this.viewer_config.dimensions.cell_width; - - if (this.opt.show_zoom_panel) { - this._show_sliding_window({ - dimensions: { - cell_width: this.viewer_config.dimensions.cell_width, - cell_count: this.viewer_config.dimensions.cell_count, - frame_width: 60 * this.viewer_config.dimensions.cell_width, - height: this.viewer_config.dimensions.row_count * this.viewer_config.dimensions.cell_width - }, - svg: d3.select("#" + this._MAIN_HEAT_MAP_DIV + "_svg > g") - }); - this._drawZoomDiv(); - } - - } - }, - /** - * Private: intialize the viewer. overrides defaults with user defined options - * @ignore - */ - _init: function() { - var tmpData = this._origData; - var tmpCfg = this.viewer_config; - - // read in user defined _config - if (this.opt.user_defined_config != 'undefined') { - var _tmpUserCfg = this.opt.user_defined_config; - ['colorLow', 'colorHigh', 'colorMed'].forEach(function(entry) { - if (tmpCfg[entry]) - tmpCfg[entry] = _tmpUserCfg[entry]; - }); - } - this._calcHeatMap({ - start: 0, - end: (tmpData.length / 20) // TODO get number of rows autormatically! - }); - }, - /** - * Private: renders a secondary heatmap for a selected region in the data - * @param {Object} d {x:, y: } defines the data range to display - * @ignore - */ - _drawZoomDiv: function(d) { - var start = 0; - - if (typeof d !== 'undefined') - start = Math.floor(d.x / this.viewer_config.main_heatmap.orig_cell_width); - var end = start + this.viewer_config.slider.increments; - this.viewer_config.offset = start; - - this._calcHeatMap({ - start: start, - end: end - }); - var $zoom_div = jQuery('#' + this._ZOOM_HEAT_MAP_DIV); - if ($zoom_div) { - $zoom_div.empty(); - this.HEATMAP.init(this.viewer_config, this._zoomedData, this._ZOOM_HEAT_MAP_DIV).draw(); - } - }, - /** - * Private: Determines cell's size, grid size, - * if rangeObj provided it determines the above only for the data within that range - * populated the x and y axis - * @param {[Object]} rangeObj {start: , end: }} defines the data range to dislpay (optional) - * @ignore - */ - _calcHeatMap: function(rangeObj) { - var dimensions = {}; - var x_axis = []; - var y_axis = []; - - var jsonData, tmpStart; - tmpStart = 0; - - var $hmDiv = jQuery("#" + this.target); - dimensions.canvas_width = $hmDiv.width(); - if (this._origData) { - if (typeof this.opt.jsonData != 'undefined') { - jsonData = this._origData.slice(rangeObj.start * 20, rangeObj.end * 20); - tmpStart = rangeObj.start; - } - var tmpCol = 0, - tmpRow = 0, - i = 0; - jQuery.each(jsonData, function(k, v) { - if (v.row == 0) { - x_axis.push(v.label); - if (v.col > tmpCol) - tmpCol = v.col; - } - if ((v.col - tmpStart) == 0) - y_axis.push(v.row_label); - - if (v.row > tmpRow) - tmpRow = v.row; - }); - dimensions.cell_count = tmpCol - this.viewer_config.offset; - dimensions.row_count = tmpRow; - var tmpCellSize = Math.max(Math.min(((dimensions.canvas_width - this.viewer_config.canvas_margin.right - this.viewer_config.canvas_margin.left) / (dimensions.cell_count + 1)), - this.viewer_config.main_heatmap.max_cell_width), this.viewer_config.main_heatmap.min_cell_width); - - dimensions.cell_height = dimensions.cell_width = tmpCellSize; - dimensions.canvas_height = (dimensions.row_count + 1) * dimensions.cell_height; - this._zoomedData = jsonData; - } - this.viewer_config.dimensions = jQuery.extend(true, {}, dimensions); - this.viewer_config.x_axis = x_axis; - this.viewer_config.y_axis = y_axis; - this.viewer_config.slider.increments = Math.floor((dimensions.canvas_width / this.viewer_config.zoom_area.cell_width) - 1); - } -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorld.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorld.js deleted file mode 100755 index da59a880f2..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorld.js +++ /dev/null @@ -1,244 +0,0 @@ -/** - * This is the description of the HelloWorld component. Here you can set any HTML text - * for putting on the generated documentation. - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options An object with the options for HelloWorld component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [fontFamily='"Andale mono", courier, monospace'] - * Font list to be applied to the component content. - * - * @option {string} [fontColor="white"] - * HTML color code for the font. - * - * @option {string} [backgroundColor="#7BBFE9"] - * Background color for the entire div content. - * - * @option {Object} [selectionFontColor="white"] - * This color will be used to change the font color of selected text. - * - * @option {Object} [ selectionBackgroundColor="yellow"] - * This color will be used to change the background of selected text. - * - * @example - * var instance = new Biojs.HelloWorld({ - * target : "YourOwnDivId", - * selectionBackgroundColor : '#99FF00' - * }); - * - */ -Biojs.HelloWorld = Biojs.extend ( -/** @lends Biojs.HelloWorld# */ -{ - constructor: function (options) { - // In JavaScript ŇthisÓ always refers to the ŇownerÓ of the function we're executing (http://www.quirksmode.org/js/this.html) - // Let's preserve the reference to 'this' through the variable self. In this way, we can invoke/execute - // our component instead of the object where 'this' is being invoked/executed. - var self = this; - - // For practical use, create an object with the main DIV container - // to be used in all of the code of our component - this._container = jQuery("#"+self.opt.target); - - // Apply options values - this._container.css({ - 'font-family': self.opt.fontFamily, // this is one example of the use of self instead of this - 'background-color': self.opt.backgroundColor, - 'color': self.opt.fontColor, - 'font-size': '36px', - 'text-align': 'center', - 'vertical-align':'middle', - 'display': 'table-cell', - 'width': '597px', - 'height': '300px' - }); - - // Disable text selection and - // Change the selection mouse pointer - // from text to hand. - this._container.css({ - '-moz-user-select':'none', - '-webkit-user-select':'none', - 'user-select':'none' - }); - - // Set the content - text = 'Hello World!'; - - for( i=0; i< text.length; i++ ) { - this._container.append('' + text[i] + ''); - } - - // Internal method to initialize the event of select 'Hello' - this._addSelectionTrigger(); - - // Internal method to set the onClick event - this._addSimpleClickTrigger(); - }, - - /** - * Default values for the options - * @name Biojs.HelloWorld-opt - */ - opt: { - target: "YourOwnDivId", - fontFamily: '"Andale mono", courier, monospace', - fontColor: "white", - backgroundColor: "#7BBFE9", - selectionFontColor: "black", - selectionBackgroundColor: "yellow" - }, - - /** - * Array containing the supported event names - * @name Biojs.HelloWorld-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.HelloWorld#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} selected Selected character. - * @example - * instance.onClick( - * function( objEvent ) { - * alert("The character " + objEvent.selected + " was clicked."); - * } - * ); - * - * */ - "onClick", - - /** - * @name Biojs.HelloWorld#onHelloSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text, will be 'Hello' obviously. - * @example - * instance.onHelloSelected( - * function( objEvent ) { - * alert("The word " + objEvent.textSelected + " was selected."); - * } - * ); - * - * */ - "onHelloSelected" - ], - - /** - * Change the font size. Do nothing it no value is provided. - * - * @param {string} [size] The new font size in pixels. - * - * @example - * instance.setSize("72px"); - */ - setSize: function(size) { - if ( size != undefined ){ - jQuery("#"+this.opt.target).css('font-size', size); - } - }, - - _addSelectionTrigger: function() { - - var self = this; - var isMouseDown = false; - - // Create the CSS class called selected to change both background and color - - jQuery('' - ).appendTo('head'); - - // - // Add the click event to each character in the content - // But remember, we must to figure out when 'Hello' is selected only - this._container.find('span') - .mousedown(function() { - - // Turn on the flag - isMouseDown = true; - - // A new selection is starting - // Reset all by removing the CSS "selected" class if already applied - self._container.children('span').removeClass('selected') - - // Apply the class for this span/character - // NOTE: "this" refers to the internal object 'span' - // NOT to the component's instance - jQuery(this).addClass('selected'); - - }).mouseover(function() { - // Check if the mouse is being dragged - if (isMouseDown) { - jQuery(this).addClass('selected'); - } - }) - .mouseup(function() { - - /// Turn off the flag - isMouseDown = false; - - var textSelected = ''; - - // Get the entire selected word - self._container.children('span.selected') - .each(function(){ - textSelected += jQuery(this).text(); - }); - - // Since requirements, only "Hello" word should be selected - // to raise the event - if (textSelected == 'Hello') { - self.raiseEvent('onHelloSelected', { - textSelected : textSelected - }) - } - }); - }, - - _addSimpleClickTrigger: function () { - - var self = this; - - // Add the click event to each character in the content - this._container.find('span') - .click( function(e) { - // A letter was clicked! - // Let's discover which one was it - // TIP: e.target contains the clicked DOM node - var selected = jQuery(e.target).text(); - - // Create an event object - var evtObject = { "selected": selected }; - - // We're ready to raise the event onClick of our component - self.raiseEvent('onClick', evtObject); - }); - } - -}); - - - - - - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorldYUI.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorldYUI.js deleted file mode 100755 index 13571bdd3c..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.HelloWorldYUI.js +++ /dev/null @@ -1,229 +0,0 @@ -/** - * This is the description of the HelloWorldYUI component. Here you can set any HTML text - * for putting on the generated documentation. - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 1 - * - * @requires YUI Core 3.3.0 - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options An object with the options for HelloWorldYUI component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [fontFamily=ÔŇAndale monoÓ, courier, monospaceŐ] - * Font list to be applied to the component content. - * - * @option {string} [fontColor="white"] - * HTML color code for the font. - * - * @option {string} [backgroundColor="#7BBFE9"] - * Background color for the entire div content. - * - * @option {Object} [selectionFontColor="white"] - * This color will be used to change the font color of selected text. - * - * @option {Object} [ selectionBackgroundColor="yellow"] - * This color will be used to change the background of selected text. - * - * @example - * var instance = new Biojs.HelloWorldYUI({ - * target : "YourOwnDivId", - * selectionBackgroundColor : '#FFFF00' - * }); - * - */ -Biojs.HelloWorldYUI = Biojs.extend ( -/** @lends Biojs.HelloWorldYUI# */ -{ - constructor: function (options) { - var self = this; -// var toggleClass = function (span) { -// span.toggleClass( 'selected' ); -// if ( span.hasClass('selected') ) { -// span.css('color', self.opt.selectionFontColor) -// .css("background-color", self.opt.selectionBackgroundColor); -// } else { -// span.css('color', self.opt.fontColor) -// .css("background-color", self.opt.backgroundColor); -// } -// }; -// - - // Apply options values - $("#"+self.opt.target).css({ - 'font-family': self.opt.fontFamily, - 'background-color': self.opt.backgroundColor, - 'color': self.opt.fontColor, - 'font-size': '36px', - 'text-align': 'center', - 'vertical-align':'middle', - 'display': 'table-cell', - 'width': '597px', - 'height': '300px' - }); - - // Disable text selection and - // Change the selection mouse pointer - // from text to hand. - $("#"+self.opt.target).css({ - '-moz-user-select':'none', - '-webkit-user-select':'none', - 'user-select':'none' - }); - - // Set the content - text = 'Hello World with YUI+jQuery!'; - contentHTML = ''; - for( i=0; i< text.length; i++ ) { - contentHTML += '' + text[i] + ''; - } - $( contentHTML ).appendTo( "#"+self.opt.target ); - - // Internal method to initialize mouse events - self._addSelectionTrigger(); - }, - - /** - * Default values for the options - * @name Biojs.HelloWorldYUI-opt - */ - opt: { - target: "YourOwnDivId", - fontFamily: '"Andale mono", courier, monospace', - fontColor: "white", - backgroundColor: "#7BBFE9", - selectionFontColor: "black", - selectionBackgroundColor: "yellow" - }, - - /** - * Array containing the supported event names - * @name Biojs.HelloWorldYUI-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.HelloWorldYUI#onHelloSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text, will be 'Hello' obviously. - * @example - * instance.onHelloSelected( - * function( objEvent ) { - * alert("The word " + objEvent.textSelected + " was selected."); - * } - * ); - * - * */ - "onHelloSelected" - ], - - /** - * Change the font size. Do nothing it no value is provided. - * - * @param {string} [size] The new font size in pixels. - * - * @example - * instance.setSize("72px"); - */ - setSize: function(size) { - if ( size != undefined ){ - $("#"+this.opt.target).css('font-size', size); - } - }, - - /** - * Set text 'Hi there! who are you?' - * - * @example - * instance.sayHello(); - */ - sayHello: function() { - var self = this; - // Set the content - text = 'Hi there! who are you?'; - contentHTML = ''; - for( i=0; i< text.length; i++ ) { - contentHTML += '' + text[i] + ''; - } - $( "#"+self.opt.target ).html( contentHTML ); - }, - - - - _addSelectionTrigger: function() { - - var self = this; - var isMouseDown = false; - - /** - * @private - * @function - */ - var toggleClass = function (span) { - if ( span.hasClass('selected') ) { - span.removeClass('selected'); - span.setStyle('color', self.opt.fontColor); - span.setStyle("background-color", self.opt.backgroundColor); - } else { - span.addClass('selected'); - span.setStyle('color', self.opt.selectionFontColor); - span.setStyle("background-color", self.opt.selectionBackgroundColor); - } - }; - - YUI().use('node', function (Y) { - - - Y.all('#' + self.opt.target + ' span').on("mousedown", function( e ) { - isMouseDown = true; - - var allSpan = Y.all('#' + self.opt.target + ' span'); - - allSpan.removeClass('selected'); - allSpan.setStyle('color', self.opt.fontColor); - allSpan.setStyle("background-color", self.opt.backgroundColor); - - toggleClass( e.currentTarget ); - }); - - - Y.all('#' + self.opt.target + ' span').on("mouseover", function(e) { - if (isMouseDown) { - toggleClass( e.currentTarget ); - } - }); - - - Y.all('#' + self.opt.target + ' span').on("mouseup", function() { - isMouseDown = false; - var textSelected = ''; - - $('#' + self.opt.target + ' span.selected' ) - .each(function(){ - textSelected += $(this).text(); - }); - - if (textSelected == 'Hello') { - self.raiseEvent('onHelloSelected', { - textSelected : textSelected - }) - } - }); - - - }); - } - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeature.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeature.js deleted file mode 100755 index ddd100de54..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeature.js +++ /dev/null @@ -1,203 +0,0 @@ -/** - * Component to represent one summary feature. Originally design to display protein expression information from the Human Protein Atlas (HPA) - * - * @class - * @extends Biojs - * - * @author Rafael C Jimenez - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires Biojs.HpaSummaryFeature.css - * @dependency - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} title - * Title of the summary - * - * @option {string} imageUrl - * URL of an image file with expression data - * - * @option {string} imageTitle - * Title or description of an image file with expression data - * - * @option {string} notes - * List of point including summary information for this feature - * - * @option {string} linkUrl - * List of points including summary information for this feature - * - * @option {string} linkTitle - * List of points including summary information for this feature - * - * @option {string} width [900px] - * List of points including summary information for this feature - * - * @option {string} imageWidth [200px] - * List of points including summary information for this feature - * - * @example - * var instance = new Biojs.HpaSummaryFeature({ - * target: 'YourOwnDivId', - * title: 'HPA001012 Normal Tissue immunohistochemistry summary', - * imageUrl: 'http://www.proteinatlas.org/images/1012/ihc_selected_medium.jpg', - * imageTitle: 'Immunohistochemical staining of human lymph node shows strong cytoplasmic positivity in lymphoid cells outside reaction centra', - * notes: ["Lymphoid tissues showed moderate to strong cytoplasmic positivity. Remaining normal cells were generally negative","Two (or more) antibodies yielding similar staining patterns which are consistent with available gene/protein characterization data","Expression summary: Selective cytoplasmic expression in lymphoid cells","Reliable score: High","Validation score: Supportive","67 normal tissues by immunohistochemistry"], - * linkUrl:'http://www.proteinatlas.org/ENSG00000089820/normal', - * linkTitle:'HPA original source', - * width: '585px', - * imageWidth: '150px' - * }); - * - */ - -Biojs.HpaSummaryFeature = Biojs.extend ( - /** @lends Biojs.HpaSummaryFeature# */ - { - constructor: function (options) { - this._draw(); - }, - /* - * Function: Biojs.GeneExpressionSummary._draw - * Purpose: Draw HPA summary feature - * Returns: - - * Inputs: opt -> {Object} options object. - */ - _draw: function(){ - var self = this; - self._componentPrefix = "hpaSummaryFeature_"; - - /* Create a component container */ - self._componentDiv = jQuery('
          '); - self._componentDiv.css('width',self.opt.width); - - /* Create table */ - self._leftColumn = jQuery(''); - self._leftColumn.css({ - 'width': self.opt.imageWidth, - 'vertical-align': 'top' - }); - self._rightColumn = jQuery(''); - self._rightColumn.css({ - 'vertical-align': 'top' - }); - self._mainRow = jQuery(''); - self._mainRow.append(self._leftColumn); - self._mainRow.append(self._rightColumn); - self._table = jQuery('
          '); - self._table.append(self._mainRow); - self._table.css('width', '100%'); - - /* Create container for left column */ - self._leftContainer = jQuery('
          '); - - /* Create image title */ - if (self.opt.imageTitle != "") { - self._imageTitle = jQuery('
          '+self.opt.imageTitle+'
          '); - } - - /* Create image */ - if (self.opt.imageUrl != "") { - /* HPA image */ - self._image = jQuery(''); - self._image.css({ - 'width': '100%' - }); - if(self.opt.imageTitle != ""){ - self._image.attr({ - 'alt': 'HPA image', - 'title': self.opt.imageTitle - }); - } - } - - /* Create link icon */ - self._linkImage = jQuery('
          '); - - /* Create link in left column including: image, link icon and image title */ - if (self.opt.linkUrl != "") { - self._link = jQuery(''); - if(self.opt.linkTitle != ""){ - self._link.attr({ - 'title': self.opt.linkTitle - }); - } - if (self.opt.imageUrl != "") { - self._link.append(self._image); - } - self._link.append(self._linkImage); - self._leftContainer.append(self._link); - if (self.opt.imageTitle != "" && self.opt.imageUrl != "") { - /* Include image legend in left column */ - self._leftContainer.append(self._imageTitle); - } - } else { - /* Still print image if there is no link */ - self._leftContainer.append(self._image); - if (self.opt.imageTitle != "" && self.opt.imageUrl != "") { - /* Include image legend in left column */ - self._leftContainer.appenf(self._imageTitle); - } - } - - /* Create title in right column */ - self._contentTitle = jQuery('
          '+self.opt.title+'
          '); - - /* Create notes in right column */ - self._contentNotes = jQuery('
            '); - jQuery.each(self.opt.notes, function(k, v) { - self._contentNotes.append(jQuery('
          • ' + v + '
          • ')) - }); - - /* Put everything together */ - jQuery("#"+self.opt.target).append(self._componentDiv); - self._componentDiv.append(self._table); - self._leftColumn.append(self._leftContainer); - self._rightColumn.append(self._contentTitle); - self._rightColumn.append(self._contentNotes); - }, - /** - * Default values for the options - * @name Biojs.HpaSummaryFeature-opt - */ - opt: { - target: '', - title: '', - imageUrl: '', - imageTitle: '', - notes: [], - linkUrl:'', - linkTitle:'', - width: '900px', - imageWidth: '200px' - }, - /** - * Array containing the supported event names - * @name Biojs.HpaSummaryFeature-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.HpaSummaryFeature#onFeatureSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text. - * @example - * instance.onTextSelected( - * function( objEvent ) { - * alert(objEvent.textSelected); - * } - * ); - * - * */ - "onTextSelected" - ] -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeatures.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeatures.js deleted file mode 100755 index b1ed02b332..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.HpaSummaryFeatures.js +++ /dev/null @@ -1,247 +0,0 @@ -/** - * Component to represent Human Protein Atlas summary protein expression - * information from a DAS XML - * - * @class - * @extends Biojs.HpaSummaryFeature - * - * @author Rafael C Jimenez - * @version 1.0.0 - * @category 2 - * - * @requires Biojs.HpaSummaryFeature.css - * @dependency - * - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} hpaDasUrl - * Url pointing to an XML including HPA infomration in DAS format - * - * @option {string} width [900px] - * List of points including summary information for this feature - * - * @option {string} imageWidth [200px] - * List of points including summary information for this feature - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * Proxy to bypass the same origin policy ({@link http://en.wikipedia.org/wiki/Same_origin_policy}) - * - * @example - * var instance = new Biojs.HpaSummaryFeatures({ - * target: 'YourOwnDivId', - * hpaDasUrl: 'http://das.proteinatlas.org/das/proteinatlas/features?segment=Q9NTI5', - * width: '585px', - * imageWidth: '150px' - * }); - * - */ - -Biojs.HpaSummaryFeatures = Biojs.HpaSummaryFeature.extend ( - /** @lends Biojs.HpaSummaryFeatures# */ - { - constructor: function (options) { - var self = this; - this.setHpaDasUrl(self.opt.hpaDasUrl); - }, - /* - * Function: Biojs.HpaSummaryFeatures.setHpaDasUrl - * Purpose: Set an URL with HPA DAS XML to start the query and visualization of HPA summary features - * Returns: - - * Inputs: hpaDasUrl -> {String} DAS XML with HPA summary information - */ - - /** - * Set an URL with HPA DAS XML to start the query and visualization of HPA summary features - * @param {string} hpaDasUrl DAS XML with HPA summary information - * - * @example - * instance.setHpaDasUrl("http://www.ebi.ac.uk/~rafael/web/copa/biojs/src/test/data/Q9NTI5_hpa_summary.xml"); - * - * @example - * instance.setHpaDasUrl("http://www.ebi.ac.uk/~rafael/web/copa/biojs/src/test/data/unknownsegment.xml"); - * - */ - setHpaDasUrl: function(hpaDasUrl){ - var self = this; - /* URL where to get DAS XML */ - self._url; - if(self.opt.proxyUrl != ""){ - self._url= self.opt.proxyUrl + "?url=" + hpaDasUrl; - } else { - self._url= hpaDasUrl; - } - - /* get XML */ - jQuery.ajax({ - type: "GET", - url: self._url, - dataType: "xml", - success: function(a){self._processDasHpaXml(a);}, - error: function(a){self._processErrorRequest(a);} - }); - }, - /* - * Function: Biojs.HpaSummaryFeatures._processDasHpaXml - * Purpose: process HPA XML - * Returns: - - * Inputs: xml -> {String} DAS XML with HPA summary information - */ - _processDasHpaXml: function (xml) - { - var self = this; - Biojs.console.log("SUCCESS: data received"); - var antibodies = this._getAntibodiesAccessions(xml); - if(antibodies.length > 0){ - var html = this._createHtmlContainer(antibodies); - jQuery('#'+self.opt.target+'').html(html); - this._displayHpaSummaries(xml,antibodies) - } else { - jQuery('#'+self.opt.target+'').html(Biojs.HpaSummaryFeatures.MESSAGE_NODATA); - } - - }, - /* - * Function: Biojs.HpaSummaryFeatures._processErrorRequest - * Purpose: Process request error - * Returns: - - * Inputs: textStatus -> {String} Text satus - */ - _processErrorRequest: function (textStatus){ - var self = this; - Biojs.console.log("ERROR: " + textStatus ); - self.raiseEvent( Biojs.HpaSummaryFeatures.EVT_ON_REQUEST_ERROR, { message: textStatus } ); - }, - /* - * Function: Biojs.HpaSummaryFeatures._getAntibodiesAccessions - * Purpose: get antibodies accessions - * Returns: - - * Inputs: xml -> {String} DAS XML with HPA summary information - */ - _getAntibodiesAccessions: function (xml){ - var tempSet = new Object(); - jQuery(xml).find("PARENT").each(function(){ - var antibodyTextSplit = jQuery(this).attr("id").split("_"); - if(antibodyTextSplit.length == 2){ - tempSet[antibodyTextSplit[0]] = true; - } - }); - var antibodies = new Array(); - for (var a in tempSet){ - antibodies.push(a); - } - return antibodies; - }, - /* - * Function: Biojs.HpaSummaryFeatures._createHtmlContainer - * Purpose: create HTML container to later populate HPA data - * Returns: - - * Inputs: antibodies -> {Array} List of antibodies - */ - _createHtmlContainer: function(antibodies) { - var self = this; - var html = ''; - jQuery.each(antibodies, function(key, value){ - html += '
            Antibody '+value+'
            ' - html += '
            '; - html += '
            '; - html += '
            '; - html += '
            '; - html += '
            '; - }); - return html; - }, - /* - * Function: Biojs.HpaSummaryFeatures._displayHpaSummaries - * Purpose: Disaply HPA summaries inside the HTML container - * Returns: - - * Inputs: xml -> {String} DAS XML with HPA summary information - */ - _displayHpaSummaries: function(xml){ - var self = this; - jQuery(xml).find("FEATURE").each(function(){ - if (jQuery(this).attr("id").indexOf("_summary") != -1) { - /* Get notes */ - var notes = new Array(); - var xmlNotes = jQuery(this).find("NOTE"); - xmlNotes.each(function(){ - notes.push(jQuery(this).text()); - }); - /* Get links */ - var imageUrl = ""; - var imageTitle = ""; - var linkUrl = ""; - var linkTitle = ""; - var xmlLinks = jQuery(this).find("LINK"); - xmlLinks.each(function(){ - if (jQuery(this).attr("href").indexOf(".jpg") != -1 || jQuery(this).attr("href").indexOf(".png") != -1) { - imageUrl = jQuery(this).attr("href"); - imageTitle = jQuery(this).text(); - } - else - if (jQuery(this).text().indexOf("original source") != -1) { - linkUrl = jQuery(this).attr("href"); - linkTitle = jQuery(this).text(); - } - }); - new Biojs.HpaSummaryFeature({ - target: jQuery(this).attr("id"), - title: jQuery(this).attr("label"), - imageUrl: imageUrl, - imageTitle: imageTitle, - notes: notes, - linkUrl: linkUrl, - linkTitle: linkTitle, - width: self.opt.width, - imageWidth: self.opt.imageWidth - }); - } - }); - - }, - - /** - * Default values for the options - * @name Biojs.HpaSummaryFeatures-opt - */ - opt: { - target: 'hpaSummaryFeatues', - hpaDasUrl: '', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - width: '900px', - imageWidth: '200px' - }, - /** - * Array containing the supported event names - * @name Biojs.HpaSummaryFeatures-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.HpaSummaryFeatures#onRequestError - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onRequestError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - **/ - "onRequestError" - ] -},{ - // Some static values - COMPONENT_PREFIX: "hpaSummaryFeatures_", - MESSAGE_NODATA: "Sorry, we could not find summary data for your request", - // Events - EVT_ON_REQUEST_ERROR: "onRequestError", -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsBundleD3.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsBundleD3.js deleted file mode 100755 index 701d857bff..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsBundleD3.js +++ /dev/null @@ -1,1021 +0,0 @@ -/** - * This component uses the D3 library and specifically its implementation of the bundle algorithm to - * represent a network of protein interactions. - * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 0.9.0_alpha - * @category 1 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires D3 - * @dependency - * - * @requires InteractionsD3 CSS - * @dependency - * - * @param {Object} options An object with the options for the InteractionsD3 component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * @option {string} width - * Width of the SVG element, if given in percentage, it will use it on proportion of the container - * @option {string} height - * Height of the SVG element, if given in percentage, it will use it on proportion of the container - * @option {string} radius - * Radius of the nodes representing the proteins - * @option {string} textLength - * Space in pixels to be reserved for the labels around the circle - * - * @example - * var instance = new Biojs.InteractionsBundleD3({ - * target: "YourOwnDivId", - * }); - * var pid=1; - * for (var i=0;i<100;i++) - * instance.addProtein({id:'p'+pid++,group:1,organism:"human"}); - * for (var i=0;i<100;i++) - * instance.addProtein({id:'p'+pid++,group:1,organism:"TB"}); - * for (var i=1;i<200;i++){ - * instance.addInteraction("p"+(i),"p"+(100+i),{id:"p"+(i)+"_p"+(100+i),feature1:"value"}); - * instance.addInteraction("p"+(i),"p"+(i%17),{id:"p"+(i)+"_p"+(i%17),feature1:"value"}); - * } - * instance.restart(); - */ -Biojs.InteractionsBundleD3 = Biojs.extend ( - /** @lends Biojs.InteractionsBundleD3# */ - { - cluster:null, - bundle:null, - vis:null, - splines:[], - model:{}, - organisms:{}, - proteins:[], - interactions:[], - interactionsA:{}, - svg:null, - - //Transformation values - tTranslate:null, - tScale:null, - - constructor: function (options) { - var self = this; - self.cluster=null; - self.bundle=null; - self.vis=null; - self.splines=[]; - self.model={"name":"", "children":[] }; - self.organisms={}; - self.proteins=[]; - self.interactions=[]; - self.svg=null; - self.interactionsA={}; - - this._container = $("#"+self.opt.target); - this._container.empty(); - $(this._container).addClass("graphCircle"); - - var w = $(this._container).width(), - h = $(this._container).height(); - - w = (self.opt.width.indexOf("%")!=-1)?w*(self.opt.width.substring(0, self.opt.width.length-1)*1)/100.0:self.opt.width*1; - self.opt.width=w; - - h = (self.opt.height.indexOf("%")!=-1)?h*(self.opt.height.substring(0, self.opt.height.length-1)*1)/100.0:self.opt.height*1; - self.opt.height=h; - - var rx = w / 2, - ry = h / 2; - - var tmpR=(rxb[1]){ - return -1; - }else - return 1; - return 0; - }); - }, - _paintLegend:function(legend,type){ - var self = this; - legend.filter(function(d) { return d[0]== "label" && d[1]==type; }).append("text") - .attr("x", self.opt.width/2 - 6) - .attr("y", 7-self.opt.height/2) - .attr("dy", ".35em") - .style("text-anchor", "end") - .style("font-size", "1.2em") - .text(type+":"); - if (type.indexOf("Resize By")==0){ - - legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("path") - .attr("class", "figure") - .attr("d", function(d) { - var h=2*self.opt.radius*Math.sqrt(d[0][2]); - return "M0,0L0,10M0,5L"+h+",5M"+h+",0L"+h+",10 "; - }) - .attr("transform", function(d) { - return "translate(" + (self.opt.width/2 - 18 - 2*self.opt.radius*Math.sqrt(d[0][2])) + ", -" + self.opt.height/2 + ")"; - }) - .style("fill", "transparent") - .style("stroke", "black"); - legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") - .attr("x", function(d) { - return (self.opt.width/2 - 22 - 5*self.opt.radius); - }) - .attr("y", 7-self.opt.height/2 ) - .attr("dy", ".35em") - .style("text-anchor", "end") - .text(function(d) { return (d[0][1]*1.0).toFixed(2); }); - - }else{ - - legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("rect") - .attr("x", self.opt.width/2 - 18) - .attr("y", -self.opt.height/2) - .attr("width", 13) - .attr("height", 13) - .style("fill", function(d,i) { - if (typeof d[2]== "undefined") - return self.color(i); - return d[2]; - }); - legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") - .attr("x", self.opt.width/2 - 24) - .attr("y", 7-self.opt.height/2) - .attr("dy", ".35em") - .style("text-anchor", "end") - .text(function(d) { return d[0]; }); - } - }, - _paintLegends: function(){ - var self = this; - var w=18 + self.longestLegend*7 + 10; - var legendBlock = self.svg.insert("g",".link") - .attr("class", "legendBlock"); - self._sortLegends(); - legendBlock.append("rect") - .attr("x", self.opt.width/2 -w) - .attr("y", -self.opt.height/2) - .attr("height", 6 + self.legends.length *16) - .attr("width", w) - .style("fill", "#ddd") - .style("fill-opacity","0.4"); - - var legend = legendBlock.selectAll(".mainLegend") - .data(self.legends) - .enter().insert("g") - .attr("class", "mainLegend") - .attr("transform", function(d, i) { return "translate(0," + (3 + i * 16) + ")"; }); - for (var i=0; i< self.legendTypes.length; i++) - self._paintLegend(legend,self.legendTypes[i]); - - }, - longestLegend:4, - legendTypes:[], - /** - * Adds a legend to the graphic - * - * @example - * instance.addLegends(["Legend red"],"Color","#FF0000"); - * instance.restart(); - */ - addLegends:function(legends,type,color){ - var self = this; - if (self.legends==null) self.legends=[],self.legendTypes=[]; - - if (legends==null) { - self.legends = null; - self.legendTypes=[]; - self.longestLegend=4; - return; - } - if (type=="Resize By") - type = type+ " "+legends[0]; - if (self.legendTypes.indexOf(type)==-1) { - self.legends.push(["label",type]); - self.legendTypes.push(type); - if (type.length>self.longestLegend) - self.longestLegend=type.length; - } - - if (type.indexOf("Resize By")==0){ //is a size label - self.legends.push([legends,type]); - } else //is a color label - for (var i=0;iself.longestLegend) - self.longestLegend=legends[i].length; - } - }, - - /** - * Hides the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.hide('[id *="node-p1"]'); - */ - hide: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("visibility", 'hidden'); - self.vis.selectAll(selector).selectAll(" .legend").attr("visibility", 'hidden'); - }, - /** - * Shows the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.show('[id *="node-p1"]'); - */ - show: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("visibility", 'visible'); - self.vis.selectAll(selector).selectAll(" .legend").attr("visibility",function(d) { return (d.showLegend)?"visible":"hidden";}); - }, - /** - * Highlight the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.highlight(".figure"); - */ - highlight: function(selector){ - var self=this; - self.vis.selectAll(selector).style("stroke", '#0f0'); - }, - /** - * Set the fill's color of the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * @param {string} color a color in web format eg. #FF0000 - * - * @example - * instance.setFillColor(".figure","#FF0000"); - */ - setFillColor: function(selector,color){ - var self=this; - self.vis.selectAll(selector).style("fill", color); - }, - /** - * Set the stroke's color of the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * @param {string} color a color in web format eg. #FF0000 - * - * @example - * instance.setColor(".figure","#FF0000"); - */ - setColor: function(selector,color){ - var self=this; - self.vis.selectAll(selector).style("stroke", color); - }, - /** - * Shows/Hide the legend(id) of the protein - * - * @param {string} protein the id of the protein to swap the visibility of the legend - * - * @example - * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); - */ - showLegend: function(selector,typeLegend){ - var self=this; - self.vis.selectAll(selector).selectAll(".legend").attr("visibility", "visible").text(function(d) { - d.typeLegend=typeLegend; - if (d.typeLegend=="id") - return d.id; -// else if (d.typeLegend.indexOf("features.")==0) -// return d.features[d.typeLegend.substr(9)]; - else - return d.features[d.typeLegend]; - }); - }, - - /** - * Scales the area of a protein - * - * @param {string} protein the id of the protein to scale - * @param {integer} scale value to scale a node - * - * @example - * instance.setSizeScale("#figure_p188",4); - */ - setSizeScale: function(selector,scale){ - var self=this; - - - self.vis.selectAll(selector).attr("r", function(d) { - d.size=scale; - return self.opt.radius*Math.sqrt(d.size); - }); - }, - /** - * Scales the size of the proteins which value has been modify by other means - * - * @param {string} selector a CSS3 selector to choose the nodes to resize - * - * @example - * var j=0; - * for (var i in instance.proteins) - * instance.proteins[i].size=1+(j++)%4; - * instance.refreshSizeScale(".figure"); - */ - refreshSizeScale: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("r", function(d) { - return self.opt.radius*Math.sqrt(d.size); - }); - }, - - - /** - * Shows/Hide the legend(id) of the protein - * - * @param {string} protein the id of the protein to swap the visibility of the legend - * - * @example - * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); - */ - hideLegend: function(selector){ - var self=this; - self.vis.selectAll(selector).selectAll(".legend").attr("visibility", "hidden"); - }, - /** - * Shows/Hide the legend(id) of the protein - * - * @param {string} protein the id of the protein to swap the visibility of the legend - * - * @example - * instance.swapShowLegend("#node-p"+(pid-1)+" .legend"); - */ - swapShowLegend: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("visibility", function(d) { - d.showLegend = !d.showLegend; - return (d.showLegend)?"visible":"hidden"; - }); - }, - /** - * - * Resizing the graph depending on the size of the window. - * - * @param self - */ - _resize: function (self) { - var width = window.innerWidth, height = window.innerHeight; - self.vis.attr("width", width).attr("height", height); - self.force.size([width, height]).resume(); - }, - colors: [ "#1f77b4", "#aec7e8", "#ff7f0e", "#ffbb78", "#2ca02c", "#98df8a", "#d62728", "#ff9896", "#9467bd", "#c5b0d5", "#8c564b", "#c49c94", "#e377c2", "#f7b6d2", "#7f7f7f", "#c7c7c7", "#bcbd22", "#dbdb8d", "#17becf", "#9edae5", - "#0077b4", "#11c7e8", "#227f0e", "#33bb78", "#44a02c", "#55df8a", "#662728", "#779896", "#8867bd", "#99b0d5", "#AA564b", "#BB9c94", "#CC77c2", "#DDb6d2", "#EE7f7f", "#FFc7c7", "#00bd22", "#11db8d", "#22becf", "#33dae5", - "#1f00b4", "#ae11e8", "#ff220e", "#ff3378", "#2c442c", "#98558a", "#d66628", "#ff7796", "#9488bd", "#c599d5", "#8cAA4b", "#c4BB94", "#e3CCc2", "#f7DDd2", "#7fEE7f", "#c7FFc7", "#bc0022", "#db118d", "#1722cf", "#9e33e5", - "#1f7700", "#aec711", "#ff7f22", "#ffbb33", "#2ca044", "#98df55", "#d62766", "#ff9877", "#946788", "#c5b099", "#8c56AA", "#c49cBB", "#e377FC", "#f7b6FD", "#7f7fEE", "#c7c7FF", "#bcbd00", "#dbdb11", "#17be22", "#9eda33" - ] - }); - - - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsD3.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsD3.js deleted file mode 100755 index 94da99b4c6..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsD3.js +++ /dev/null @@ -1,1085 +0,0 @@ -/** - * This component uses the D3 library and specifically its implementation of the force algorithm to - * represent a network of protein interactions. - * - * @class - * @extends Biojs - * - * @author Gustavo A. Salazar - * @version 0.9.1_beta - * @category 1 - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires D3 - * @dependency - * - * @requires InteractionsD3 CSS - * @dependency - * - * @param {Object} options An object with the options for the InteractionsD3 component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * @option {string} width - * Width of the SVG element, if given in percentage it will use it on proportion of the container - * @option {string} height - * Height of the SVG element, if given in percentage it will use it on proportion of the container - * @option {string} radius - * Radius of the nodes representing the proteins - * @option {string} enableEdges - * Force the proteins to stay in the defined area of the SVG - * - * @example - * var instance = new Biojs.InteractionsD3({ - * target: "YourOwnDivId", - * }); - * for (var pid=1;pid<=15;pid++) - * instance.addProtein({ "id":pid,"name":pid,"showLegend":false,"typeLegend":"id","organism":"human"+pid%3,"features":{"f1":"val1","f2":"val2","f3":"val3"}}); - * - * for (var pid=1;pid<=30;pid++) - * instance.addInteraction(Math.floor((Math.random()*15)+1),Math.floor((Math.random()*15)+1) ,{score:Math.random()}); - * instance.restart(); - */ -Biojs.InteractionsD3 = Biojs.extend ( - /** @lends Biojs.InteractionsD3# */ - { - force:null, - vis:null, - interactions:[], - interactionsA:{}, - proteins:[], - proteinsA:{}, - node_drag:null, - color: null, - foci: [], - organisms: {}, - - //Transformation values - tTranslate:null, - tScale:null, - - constructor: function (options) { - var self = this; - self.force =null; - self.vis =null; - self.interactions=[]; - self.interactionsA={}; - self.proteins=[]; - self.proteinsA={}; - self.node_drag=null; - self.color= null; - self.foci=[]; - self.organisms={}; - - this._container = $("#"+self.opt.target); - this._container.empty(); - $(this._container).addClass("graphNetwork"); - - var width = $(this._container).width(), - height = $(this._container).height(); - - if (self.opt.width.indexOf("%")!=-1) - width = width*(self.opt.width.substring(0, self.opt.width.length-1)*1)/100.0; - else - width=self.opt.width*1; - self.opt.width=width; - - if (self.opt.height.indexOf("%")!=-1) - height = height*(self.opt.height.substring(0, self.opt.height.length-1)*1)/100.0; - else - height=self.opt.height*1; - self.opt.height=height; - - this._container.width(width); - this._container.height(height); - - self.color = function() { - return d3.scale.ordinal().range(self.colors); - }(); - - self.zoom=d3.behavior.zoom(). - scaleExtent([(self.opt.enableEdges)?1:0.1, 10]) - .on("zoom", redraw); - self.vis = d3.select("#"+self.opt.target).append("svg") - .attr("width", width) - .attr("height", height) - .attr("pointer-events", "all") - .call(self.zoom) - .append('svg:g'); - - self.vis.append('svg:rect') - .attr('width', width*20) - .attr('height', height*20) - .attr('x', -width*10) - .attr('y', -height*10) - .attr('fill', 'white') - .attr('stroke','white'); - - self.rect= self.vis.append('svg:rect') - .attr("class", "frame") - .attr('width', width) - .attr('height', height) - .attr('fill', 'white') - .attr('stroke','white') - .attr("stroke-dasharray","5,5"); - - - self.perspective=d3.select("#"+self.opt.target + " svg").append('svg:g'); - - - - function redraw(x,y,scaleP) { - var trans=null,scale=null; - if (typeof x!="undefined" && typeof y!="undefined"){ - trans=[x,y]; - scale = scaleP; - }else{ - trans=d3.event.translate; - scale = d3.event.scale; - } - self.tTranslate=trans; - self.tScale=scale; - if (self.opt.enableEdges) { - if(scale<1)scale=1; - d3.behavior.zoom().scaleExtent([1, Infinity]); - if (trans[0]>0)trans[0]=0; - if (trans[1]>0)trans[1]=0; - - var W = self.rect[0][0].width.animVal.value, H= self.rect[0][0].height.animVal.value; - var Ws = W*scale, Hs = H*scale; - if (Wsb[1]){ - return -1; - }else - return 1; - return 0; - }); - }, - _paintLegend:function(legend,type){ - var self = this; - legend.filter(function(d) { return d[0]== "label" && d[1]==type; }).append("text") - .attr("x", self.opt.width - 6) - .attr("y", 7) - .attr("dy", ".35em") - .style("text-anchor", "end") - .style("font-size", "1.2em") - .text(type+":"); - if (type.indexOf("Resize By")==0){ - - legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("path") - .attr("class", "figure") - .attr("d", function(d) { - var h=2*self.opt.radius*Math.sqrt(d[0][2]); - return "M0,0L0,10M0,5L"+h+",5M"+h+",0L"+h+",10 "; - }) - .attr("transform", function(d) { - return "translate(" + (self.opt.width - 18 - 2*self.opt.radius*Math.sqrt(d[0][2])) + "," + 0 + ")"; - }) - .style("fill", "transparent") - .style("stroke", "black"); - legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") - .attr("x", function(d) { - return (self.opt.width - 22 - 5*self.opt.radius); - }) - .attr("y", 7) - .attr("dy", ".35em") - .style("text-anchor", "end") - .text(function(d) { return (d[0][1]*1.0).toFixed(2); }); - - }else{ - legend.filter(function(d) { return d[0]!="label" && d[1]==type; }).append("rect") - .attr("x", self.opt.width - 18) - .attr("width", 13) - .attr("height", 13) - .style("fill", function(d,i) { - if (typeof d[2]== "undefined") - return self.color(i); - return d[2]; - }); - legend.filter(function(d) { return d[0]!="label" && d[1]== type; }).append("text") - .attr("x", self.opt.width - 24) - .attr("y", 7) - .attr("dy", ".35em") - .style("text-anchor", "end") - .text(function(d) { return d[0]; }); - } - }, - _paintLegends: function(){ - var self = this; - var w=18 + self.longestLegend*7 + 10; - var legendBlock = self.perspective.insert("g",".link") - .attr("class", "legendBlock"); - self._sortLegends(); - legendBlock.append("rect") - .attr("x", self.opt.width -w) - .attr("height", 6 + self.legends.length *16) - .attr("width", w) - .style("fill", "#ddd") - .style("fill-opacity","0.4"); - - var legend = legendBlock.selectAll(".mainLegend") - .data(self.legends) - .enter().insert("g") - .attr("class", "mainLegend") - .attr("transform", function(d, i) { - return "translate(0," + (3 + i * 16) + ")"; - }); - for (var i=0; i< self.legendTypes.length; i++) - self._paintLegend(legend,self.legendTypes[i]); - - }, - longestLegend:4, - legendTypes:[], - /** - * Adds a legend to the graphic - * - * @example - * instance.addLegends(["Legend red"],"Color","#FF0000"); - * instance.restart(); - */ - addLegends:function(legends,type,color){ - var self = this; - if (self.legends==null) self.legends=[],self.legendTypes=[]; - - if (legends==null) { - self.legends = null; - self.legendTypes=[]; - self.longestLegend=4; - return; - } - if (type=="Resize By") - type = type+ " "+legends[0]; - if (self.legendTypes.indexOf(type)==-1) { - self.legends.push(["label",type]); - self.legendTypes.push(type); - if (type.length>self.longestLegend) - self.longestLegend=type.length; - } - - if (type.indexOf("Resize By")==0){ //is a size label - self.legends.push([legends,type]); - } else //is a color label - for (var i=0;iself.longestLegend) - self.longestLegend=legends[i].length; - } - }, - /** - * Hides the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.hide("[id = node_10]"); - */ - hide: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("visibility", 'hidden'); - self.vis.selectAll(selector).selectAll(" .legend").attr("visibility", 'hidden'); - }, - /** - * Shows the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.show("[id = node_10]"); - */ - show: function(selector){ - var self=this; - self.vis.selectAll(selector).attr("visibility", 'visible'); - self.vis.selectAll(selector).selectAll(" .legend").attr("visibility",function(d) { return (d.showLegend)?"visible":"hidden";}); - }, - /** - * Highlight the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * - * @example - * instance.highlight("[id *= node_1]"); - */ - highlight: function(selector){ - var self=this; - self.vis.selectAll(selector).style("stroke", '#3d6'); - }, - /** - * Set the fill's color of the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * @param {string} color a color in web format eg. #FF0000 - * - * @example - * instance.setFillColor(".figure","#FF0000"); - */ - setFillColor: function(selector,color){ - var self=this; - self.vis.selectAll(selector).style("fill", color); - }, - /** - * Set the stroke's color of the elements on the graphic that match the selector. - * Check the CSS3 selectors documentation to build a selector string - * - * @param {string} selector a string to represent a set of elements. Check the CSS3 selectors documentation to build a selector string - * @param {string} color a color in web format eg. #FF0000 - * - * @example - * instance.setColor("[id *= node_2]","#FF0000"); - */ - setColor: function(selector,color){ - var self=this; - self.vis.selectAll(selector).style("stroke", color); - }, - /** - * If the protein has a fixed position in the graphic it gets released, or viceversa other wise - * - * @param {string} protein the id of the protein to swap is position on the graphic - * - * @example - * instance.swapFixed("3"); - */ - swapFixed: function(protein){ - var self=this; - var nodes=self.force.nodes(); - nodes.forEach(function(d, i) { - if (d.id==protein) - d.fixed = !d.fixed; - }); - }, - /** - * Shows the legend(id) of the protein - * - * @param {string} protein the id of the protein to swap the visibility of the legend - * - * @example - * instance.swapShowLegend("#node_5 .legend"); - */ - showLegend: function(selector,typeLegend){ - var self=this; - self.vis.selectAll(selector).selectAll(".legend").attr("visibility", "visible").text(function(d) { - d.typeLegend=typeLegend; - if (d.typeLegend=="id") - return d.id; - else //if (d.typeLegend.indexOf("features.")==0) - return d.features[d.typeLegend]; -// else -// return d[d.typeLegend]; - }); -// self.restart(); - }, - /** - * Scales the area of a protein - * - * @param {string} protein the id of the protein to scale - * @param {integer} scale value to scale a node - * - * @example - * instance.setSizeScale("#figure_1",4); - */ - setSizeScale: function(selector,scale){ - var self=this; - self.vis.selectAll(selector).attr("d", d3.svg.symbol() - .size(function(d) { - d.size=scale; - return (2*self.opt.radius)*(2*self.opt.radius)*scale; - }) - .type(function(d) { - return d3.svg.symbolTypes[self._figuresOrder[self.organisms[d.organism]]]; - }) - ); - }, - /** - * Scales the size of the proteins which value has been modify by other means - * - * @param {string} selector a CSS3 selector to choose the nodes to resize - * - * @example - * for (var i=0;iNOTE: The selection - * radio button options will just work if the instance of your object is globlal. Example: - * "var instance; window.onload = function() {instance = new Biojs.InteractionsFilterGraph(...)};" - * - * @class - * @extends Biojs - * - * @author Rafael Jimenez - * @version 1.0.0 - * @category 2 - * - * @requires Biojs.InteractionsFilterGraph.css - * @dependency - * - * @requires jQuery 1.7.2 - * @dependency - * - * @requires Cytoscape.js (latest version strongly suggested) - * @dependency - * - * @requires Arbor JS (included with Cytoscape.js) - * @dependency - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} instanceName - * Instance name of the object - * - * @option {string} interactions - * Object with binary interactions including interactors - * - * @option {string} filters - * Filtering options use to highlight interactions in the graph - * - * @option {string} graphHeight [400] - * Graph height - * - * @option {string} graphWidth [400] - * Graph width - * - * @example - * var instance = new Biojs.InteractionsFilterGraph({ - * target: "YourOwnDivId", - * instanceName: "instance", - * graphHeight: '350px', - * graphWidth: '100%', - * interactions: { - * "i1": ["P1","P2"], - * "i2": ["P3","P4"], - * "i3": ["P5","P6"], - * "i4": ["P2","P6"], - * "i5": ["P2","P4"], - * "i6": ["P6","P1"], - * "i7": ["P2","P6"] - * }, - * filters:{ - * timeSeries: { - * title: "Time after Sendai viral infection (hours)", - * presentation: "radio", - * active: true, - * dataType: "edges", - * data: { - * "2":["i2","i3","i4"], - * "6":["i2","i5","i6","i7"], - * "12":["i1","i2","i3","i4","i6","i7"] - * } - * } - * } - * }); - */ - - -Biojs.InteractionsFilterGraph = Biojs.extend( -/** @lends Biojs.InteractionsFilterGraph# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - //this._setExample(); - if(this._getObjectSize(this.opt.interactions)){ - this._setHtmlTemplate(); - this._createFilterOptions(); - this._setCytoscapeHeight(); - this._startCytoscape(); - } - }, - /** - * Default values for the options - * @name Biojs.InteractionsFilterGraph-opt - */ - opt: { - target: "YourOwnDivId", - instanceName: "instance", - graphHeight: 500, - graphWidth: 500, - interactions: {}, - filters:{} - }, - /** - * Array containing the supported event names - * @name Biojs.InteractionsFilterGraph-eventTypes - */ - eventTypes: [], - - _setExample: function(){ - this.opt.interactions = { - "i1": ["P1","P2"], - "i2": ["P3","P4"], - "i3": ["P5","P6"], - "i4": ["P2","P6"], - "i5": ["P2","P4"], - "i6": ["P6","P1"], - "i7": ["P2","P6"] - }; - this.opt.filters = { - timeSeries: { - title: "Time after Sendai viral infection (hours)", - presentation: "radio", - active: true, - dataType: "edges", - data: { - "2":["i2","i3","i4"], - "6":["i2","i5","i6","i7"], - "12":["i1","i2","i3","i4","i6","i7"] - } - }, - interactionTypes: { - title: "Interaction types", - presentation: "radio", - active: true, - dataType: "edges", - data: { - "association":["i3","i4"], - "physical association":["i2","i5","i6","i7"], - "colocalization":["i1","i2"] - } - }, - publications: { - title: "Publications", - presentation: "checkbox", - active: false, - dataType: "edges", - data: { - "pumned01":["i1","i2","i3","i4","i5","i6","i7"], - "pumned02":["i1","i2","i3","i4","i5","i6"], - "pumned03":["i1","i2","i3","i6"], - "pumned04":["i1","i3"], - "pumned05":["i3"] - } - } - }; - - }, - - _getObjectSize: function(object){ - var count = 0; - for (i in object) { - if (object.hasOwnProperty(i)) { - count++; - } - } - return count; - }, - - _setCytoscapeHeight: function(){ - this.opt.graphHeight = this.opt.graphHeight.toString(); - var height = this.opt.graphHeight; - if(this.opt.graphHeight.indexOf("px") != -1){ - height = this.opt.graphHeight.substring(0,this.opt.graphHeight.length - 2); - } - var filterHeight = jQuery("#"+this._filtersTarget).height(); - var cytoscapeHeight = parseInt(this.opt.graphHeight) - parseInt(filterHeight) - 5; - var cytoscape = jQuery("#"+this._cytoscapeTarget); - cytoscape.height(cytoscapeHeight); - //cytoscape.width(parseInt(cytoscape.width())-1); - }, - - /* - * Function: Biojs.HpaSummaryFeatures._getCytoscapeElements - * Purpose: Get an elements object defining the data structure of the graph - * Returns: {Object} elements object used by cytoscape - * Inputs: - - */ - _getCytoscapeElements: function(){ - var self = this; - var nodes = []; - var edges = []; - var elements = new Object(); - var nodeExists = {}; // id => true - var addNode = function(id){ - if( !nodeExists[id] ){ - nodes.push({ data: { id: id, weight: self.opt.nodeWeight }, classes: "allnodes" }); - - nodeExists[id] = true; - } - }; - - for(interactionId in self.opt.interactions){ - var interactors = self.opt.interactions[interactionId]; - - edges.push({ data: { id: interactionId, source: interactors[0], target: interactors[1]},classes: "alledges"}); - - addNode( interactors[0] ); - addNode( interactors[1] ); - } - elements = {"nodes": nodes, "edges": edges}; - return elements; - }, - - - /* - * Function: Biojs.HpaSummaryFeatures._startCytoscape - * Purpose: Start cytoscape and draw the network - * Returns: - - * Inputs: - - */ - _startCytoscape: function(){ - - var elements = this._getCytoscapeElements(); - - jQuery("#"+this._cytoscapeTarget).cytoscape({ - - // define the elements in the graph - elements: elements, - - // define the layout to use - layout: { - name:"arbor" - }, - - // define the visual style (like css) of the graph - style: [ - { - selector: "node", - css: { - shape: "ellipse", - backgroundColor: "#888", - height: "mapData(weight, 0, 100, 15, 30)", - width: "mapData(weight, 0, 100, 15, 30)", - content: "data(id)" - } - }, - - { - selector: ".unselect", - css: { - backgroundColor: "#888", - borderColor: "#ccc" - } - - }, - - { - selector: "edge", - css: { - lineColor: "#ccc", - targetArrowColor: "#ccc", - width: "mapData(weight, 0, 100, 2, 5)" - } - }, - - { - selector: "node:selected", - css: { - backgroundColor: "#cc0000" - } - }, - - { - selector: "edge:selected", - css: { - lineColor: "#ff9999" - } - } - - ], - - // define the callback for when cytoscape web is ready - ready: function(){ - window.cy = this; - } - }); - - - }, - - - /** - * The idea would be to load some stuff once cytoscape is ready. - * However it seems this cannot be done since the cy.ready or cy.done - * events of cytoscape do not work on this version. - */ - _onCytoscapeReady: function(){ - alert("asdasdaa"); - }, - - - /* - * Function: Biojs.HpaSummaryFeatures._printInteractionDetails - * Purpose: Print node and edges information - * Returns: - - * Inputs: nodes -> {String} String of interactors. - * edges -> {String} String of interactions. - */ - _printInteractionDetails: function(nodes, edges){ - var edgesMsg = jQuery('Interactions: '+edges+''); - var nodesMsg = jQuery('Interactors: '+nodes+''); - jQuery("#"+this._informationTarget).append(edgesMsg); - jQuery("#"+this._informationTarget).append(nodesMsg); - }, - - - /** - * Highlight a filter option in the graph - * @param {string} [dataElement] Data element of one filter option. - * @param {string} [filterName] Filter name of one filter option. - * - * @example - * instance.highlightFilterOption("6","timeSeries"); - * - * @example - * instance.highlightFilterOption("2","timeSeries"); - */ - highlightFilterOption: function(dataElement,filterName){ - jQuery(".miRadioBtn").not('.'+filterName+'RadioBtn').prop('checked', false); - //jQuery(".miRadioBtn").attr('checked', false); - if(typeof filterName != undefined){ - if(typeof dataElement != undefined){ - if(dataElement == 'none'){ - this.unselect(); - } - else if(typeof this.opt.filters[filterName].data[dataElement] != undefined){ - var edgeIds = ""; - var nodeIds = ""; - // SELECT EDGES - interactions - for (key in this.opt.filters[filterName].data[dataElement]) { - if (this.opt.filters[filterName].data[dataElement].hasOwnProperty(key)){ - var edgeId = this.opt.filters[filterName].data[dataElement][key]; - if(typeof edgeId != 'function'){ - edgeIds += "#" + edgeId + ", "; - // SELECT NODES - interactors - if(this.opt.interactions[edgeId] != undefined){ - for (i=0; i
            '); - var filterTitle = jQuery('
            '+this.opt.filters[key].title+'
            '); - var filterOptions = jQuery('
            '); - filterContainer.append(filterTitle); - filterContainer.append(filterOptions); - jQuery("#"+this._filtersTarget).append(filterContainer); - if(this.opt.filters[key].presentation == "radio"){ - this._createRadioButtons(this.opt.filters[key].data, key, '#'+key+'Options'); - } else if (this.opt.filters[key].presentation == "checkbox"){ - // todo - } else { - Biojs.console.log("ERROR: " + "filter presentation value unknown for filter " + key); - } - } - } - } - }, - - /* - * Function: Biojs.HpaSummaryFeatures._createCheckBox - * Purpose: Create checkbox options - * Returns: - - * Inputs: - - */ - _createCheckBox: function(data, filterName, target){ - }, - /* - * Function: Biojs.HpaSummaryFeatures._createRadioButtons - * Purpose: Create radio button options - * Returns: - - * Inputs: data -> {Object} Data for one filter. - * filterName -> {String} Filter name. - * target -> {String} HTML tag where to draw. - */ - _createRadioButtons: function(data, filterName, target){ - for (key in data) { - if (data.hasOwnProperty(key)){ - var br = jQuery('
            '); - var radioBtnContainer = jQuery(''); - var radioBtn = jQuery(''); - var radioBtnName = jQuery(''+key+''); - radioBtnContainer.append(radioBtn); - radioBtnContainer.append(radioBtnName); - radioBtnContainer.appendTo(target); - //br.appendTo('#timeSeriesRadioButtons'); - } - } - var nondeRadioBtn = jQuery(''); //checked="checked" - var noneRadioBtnName = jQuery('None'); - nondeRadioBtn.appendTo(target); - noneRadioBtnName.appendTo(target); - }, - - - /* - * Function: Biojs.HpaSummaryFeatures._setHtmlTemplate - * Purpose: Create an HTML template to later on populate with information - * Returns: - - * Inputs: - - */ - _setHtmlTemplate: function(){ - this.opt.graphWidth = this.opt.graphWidth.toString(); - var width = this.opt.graphWidth + "px"; - if(this.opt.graphWidth.indexOf("%") != -1 || this.opt.graphWidth.indexOf("px") != -1){ - width = this.opt.graphWidth; - } - var interactionFilters = jQuery('
            '); - var cytoscape = jQuery('
            '); - var information = jQuery('
            '); - jQuery("#"+this.opt.target).append(interactionFilters); - jQuery("#"+this.opt.target).append(cytoscape); - jQuery("#"+this.opt.target).append(information); - }, - - /* - * Variable: Biojs.HpaSummaryFeatures._setHtmlTemplate - * Purpose: Create an HTML template to later on populate with information - * Returns: - - * Inputs: - - */ - _cytoscapeTarget: "miCy", - _filtersTarget: "miInteractionFilters", - _informationTarget: "miInformation" - - - - - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsTable.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsTable.js deleted file mode 100755 index dda7668fc5..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractionsTable.js +++ /dev/null @@ -1,668 +0,0 @@ -/** - * Table to show binary molecular interactions. - * - * @class - * @extends Biojs.Table - * - * @author John Gomez - * @version 1.0.0 - * @category 3 - * - * @param {Object} options - * An object with the options for InteractionTable' component. - * - * @option {string[][]|Object} dataSet - * Either 2D string array containing the whole data to be displayed or a plain object defining the data source. - * - *
            - *    {
            - * 		url: <url>,
            - * 		proxyUrl: <proxy>,
            - * 		paramsMap: { "iDisplayStart": <newName1>, "iDisplayLength": <newName2>, ... },
            - * 		filter: <flag>,
            - * 		version: <MITAB_VERSION>,
            - *      totalRecords:<number>
            - *    }
            - *    
            - * where: - *
              - *
            • url is string containing the url data source.
            • - *
            • paramsMap Customize the name of the following params which will be passed to server: - *
                - *
              • iDisplayStart: index of the first expected record for paging.
              • - *
              • iDisplayLength: size of the fetched data (page size).
              • - *
              • sSearch: filter string entered by the user in case of filter is enabled.
              • - *
              - *
            • - *
            • filter is a boolean to show/hide the search box on the table top. - * The entered string will be passed to the server by means of 'sSearch' parameter. - * Personalize the parameter name using paramsMap.
            • - *
            • proxyUrl optional string containing the url of the proxy in case of needing access to server through a proxy.
            • - *
            • version either string or integer containing the version of MITAB format as follows: - * - *
            • - *
            • totalRecords integer containing the number of total records. MITAB format does not contains this value on the response. - * You must do a request to ask for it.
            • - *
            - * - *
            - *    {
            - * 		psiquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query',
            - * 		proxyUrl: '../biojs/dependencies/proxy/proxy.php',
            - *      version: "MITAB_VERSION_2_5_EXT",
            - *      query: "species:human",
            - *      filter: false
            - *    }
            - *    
            - * - *
            - *    ...soon
            - *    
            - * - * @example - * var myTable = new Biojs.InteractionsTable({ - * target: "YourOwnDivId", - * dataSet: { - * psicquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query', - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * query: "brca2", - * version: "MITAB_VERSION_2_5", - * filter: false - * }, - * rowSelection: true - * }); - * - */ -Biojs.InteractionsTable = Biojs.Table.extend( -/** @lends Biojs.InteractionsTable# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - - options.dataSet.version = (options.dataSet.version != undefined) ? options.dataSet.version : Biojs.InteractionsTable.MITAB_VERSION_2_5 - - this._useVersion ( options.dataSet.version ); - - // Calling super's constructor - this.base(options); - - }, - - /** - * Default values for the options - * @name Biojs.InteractionsTable-opt - */ - opt: { - target: "YourOwnDivId", - rowSelection: false, - version: "MITAB_VERSION_2_5", - psiquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query', - proxyUrl: '../biojs/dependencies/proxy/proxy.php' - }, - - /** - * Array containing the supported event names - * @name Biojs.InteractionsTable-eventTypes - */ - eventTypes: [], - - /** - * Do a query to PSICQUIC server by using the provided query in MIQL. - * Uses the structure of the URL to fetch data from PSICQUIC. - * @param {string} columns Column indexes to be hided. - * - * @example - * myTable.setQuery("species:human"); - * - */ - setQuery: function ( query ) { - - // remove this properties to set a new query - delete this.opt.dataSet.url; - delete this.opt.totalRecords; - - // set the new query - this.opt.dataSet.query = query; - - // request data - this.setDataSource(this.opt.dataSet); - }, - - /** - * Get the actual query. - * Uses the structure of the URL to fetch data from PSICQUIC. - * - * @return {string} Current query. - * - * @example - * alert( "The query is " + myTable.getQuery() ); - */ - getQuery: function () { - return unescape(this.opt.dataSet.query); - }, - - /* - * Function: Biojs.InteractionTable._requestQueryCount - * Purpose: Request total rows counting with the provided query for pagination purposes. - * Since the PSIQUIC service does not provides the total row count with retrieved data, - * it's necessary to do another request in order to get it. - * Inputs: dataSet -> {Object} Settings of the data set. - * action -> {function} Callback function having the dataSet as argument. - */ - _requestQueryCount: function ( dataSet, action ) { - var self = this; - - dataSet.url = dataSet.psicquicUrl + '/' + dataSet.query; - dataSet.paramsMap = { "iDisplayStart": "firstResult", "iDisplayLength": "maxResults" }; - - jQuery.ajax({ - url: dataSet.proxyUrl, - dataType: "text", - data: [{ name: "url", value: dataSet.url + '?format=count' }], - success: function ( data ) { - dataSet.totalRecords = parseInt(data) | 0; - action.call( self, dataSet ); - } - }); - }, - - /** - * Rebuild the table - * - * @example - * myTable.setDataSource({ - * psicquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query', - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * query: "pubid:(10837477 OR 12029088)", - * version: "MITAB_VERSION_2_5", - * filter: false - * }); - * - */ - setDataSource: function ( dataSet ) { - - if ( dataSet instanceof Array ) { - // Local data - // invoke parent's setDataSource - this.base( dataSet ); - - } else { - // Remote data - if ( dataSet.hasOwnProperty("totalRecords") && dataSet.hasOwnProperty("url") ) { - // Already have the number of records for pagination - // then, invoke parent's setDataSource - this.base( dataSet ); - - } else { - // Set the new query - this.opt.dataSet = {}; - this.opt.dataSet.psicquicUrl = dataSet.psicquicUrl; - this.opt.dataSet.proxyUrl = dataSet.proxyUrl; - this.opt.dataSet.version = dataSet.version; - this.opt.dataSet.filter = dataSet.filter; - this.opt.dataSet.query = escape(dataSet.query); - this.opt.dataSet.url = dataSet.psicquicUrl + '/' + dataSet.query; - this.opt.dataSet.paramsMap = { "iDisplayStart": "firstResult", "iDisplayLength": "maxResults" }; - // Request query counting rows and apply setDataSource then - this._requestQueryCount( this.opt.dataSet, this.base ); - } - } - }, - /* - * Function: Biojs.InteractionTable._decodeToJSON - * Purpose: Overrides the parent method to decode the received MITAB data into the expected JSON format. - * Returns: {Object} formatted in the expected JSON. - * Inputs: data -> {*} MITAB data received from the PSIQUIC server or another one. - */ - _decodeToJSON: function ( mitabData ) { - Biojs.console.log("DATA DECODING FROM MITAB to JSON"); - - var jsonData = {}; - var decoder = new Biojs.InteractionsTable.MITabTxtDecoder(mitabData); - - jsonData.aaData = decoder.decodeData(); - jsonData.iTotalRecords = this.getTotalRecords(); - jsonData.iTotalDisplayRecords = this.getTotalRecords(); - - delete decoder; - return jsonData; - }, - - /* - * Function: Biojs.InteractionTable._useVersion - * Purpose: Set the columns depending on the MITAB format version. - * Returns: - * Inputs: {string|int} Either the name or the number of columns of the MITAB version. - * Use values defined in the static members of Biojs.InteractionsTable declared at the end of this class. - */ - _useVersion: function (version) { - - var length = ( (typeof version) == "string" ) ? Biojs.InteractionsTable[version] : version; - - var columnsToHide = []; - - switch (length) { - - case Biojs.InteractionsTable.MITAB_VERSION_2_7: - for ( var i = 36; i < 42; i++ ) { - this.opt.columns[i] = Biojs.InteractionsTable.MITAB_COLUMNS[i]; - } - columnsToHide = [36,37,38,39,40,41]; - - case Biojs.InteractionsTable.MITAB_VERSION_2_6: - for ( var i = 31; i < 36; i++ ) { - this.opt.columns[i] = Biojs.InteractionsTable.MITAB_COLUMNS[i]; - } - columnsToHide = columnsToHide.concat([31,32,33,34,35]); - - case Biojs.InteractionsTable.MITAB_VERSION_2_5_EXT: - for ( var i = 15; i < 31; i++ ) { - this.opt.columns[i] = Biojs.InteractionsTable.MITAB_COLUMNS[i]; - } - columnsToHide = columnsToHide.concat([15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]); - - // Complex expansion - this.opt.columns[15].render = this._columnRender.showDescXRef; - - // Biological Role A - this.opt.columns[16].render = this._columnRender.showDescXRef; - - // Biological Role B - this.opt.columns[17].render = this._columnRender.showDescXRef; - - // Experimental Role A - this.opt.columns[18].render = this._columnRender.showRowDescXRef; - - // Experimental Role B - this.opt.columns[19].render = this._columnRender.showRowDescXRef; - - // Interactor Type A - this.opt.columns[20].render = this._columnRender.showDescXRef; - - // Interactor Type B - this.opt.columns[21].render = this._columnRender.showDescXRef; - - // XRef Interactor Type A - this.opt.columns[22].render = this._columnRender.showDescXRef; - - // Xref Interactor Type B - this.opt.columns[23].render = this._columnRender.showDescXRef; - - // XRef Interaction - this.opt.columns[24].render = this._columnRender.showDescXRef; - - // Annotation Interactor A - this.opt.columns[25].render = this._columnRender.showRowDescXRef; - - // Annotations Interactor B - this.opt.columns[26].render = this._columnRender.showRowDescXRef; - - // Annotations Interaction - this.opt.columns[27].render = this._columnRender.showRowDescXRef; - - // NCBI Taxonomy - this.opt.columns[28].render = this._columnRender.showDescXRef; - - // Parameters - this.opt.columns[29].render = this._columnRender.showRowDescXRef; - - // Creation Date - this.opt.columns[30].render = this._columnRender.showRowDescXRef; - - case Biojs.InteractionsTable.MITAB_VERSION_2_5: - - for ( var i = 0; i < 15; i++ ) { - this.opt.columns[i] = Biojs.InteractionsTable.MITAB_COLUMNS[i]; - } - columnsToHide = columnsToHide.concat([2,3,7,8,11,12,13]); - - this.opt.columns[0].render = this._columnRender.showProteinXRef; - this.opt.columns[1].render = this._columnRender.showProteinXRef; - this.opt.columns[2].render = this._columnRender.showValueXRef; - this.opt.columns[3].render = this._columnRender.showValueXRef; - this.opt.columns[4].render = this._columnRender.showValueXRef; - this.opt.columns[5].render = this._columnRender.showValueXRef; - - this.opt.columns[6].render = this._columnRender.showDescXRef; - - // NCBI Taxon - this.opt.columns[9].render = this._columnRender.showDescXRef; - this.opt.columns[10].render = this._columnRender.showDescXRef; - - // Interaction type - this.opt.columns[11].render = this._columnRender.showDescXRef; - - // source - this.opt.columns[12].render = this._columnRender.showDescXRef; - - // Interaction AC - this.opt.columns[13].render = this._columnRender.showInteractionXRef; - - // Confidence Score - this.opt.columns[14].render = this._columnRender.showRawValueXRef; - - break; - - default : - Biojs.console.log("Wrong version <"+length+"> "); - } - - - this.opt.hideColumns = columnsToHide; - - }, - - /* - * Object: Biojs.InteractionTable._columnRender.showProteinXRef - * Purpose: Store the render functions to format values on the table cells. - */ - _columnRender: { - - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender - * Purpose: Format the string :(DESC) as link to Protein - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showProteinXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - var xref = {}; - while ( tk.hasNext() ) { - xref = tk.decodeXRef(); - url = Biojs.InteractionsTable.DATABASE_URL[xref.key]; - newValue += '' + xref.value + '
            '; - } - delete tk; - return newValue; - }, - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender.showInteractionXRef - * Purpose: Format the string :(DESC) as link to Interaction - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showInteractionXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - var xref = {}; - while ( tk.hasNext() ) { - xref = tk.decodeXRef(); - url = Biojs.InteractionsTable.DATABASE_URL[xref.key]; - newValue += '' + xref.value + '
            '; - } - delete tk; - return newValue; - }, - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender.showValueXRef - * Purpose: Format the string :(DESC) as the VALUE text into a - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showValueXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - var comma = ""; - var xref; - while ( tk.hasNext() ) { - xref = tk.decodeXRef(); - newValue += comma + '' + xref.value + ''; - comma = ', '; - } - delete tk; - return newValue; - }, - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender.showDescXRef - * Purpose: Format the string :(DESC) as linked DESC to the ontology - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showDescXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - while ( tk.hasNext() ) { - xref = tk.decodeXRef(); - url = Biojs.InteractionsTable.DATABASE_URL[xref.key.replace(/-/gi,'')]; - newValue += '' + xref.desc + '
            '; - } - delete tk; - return newValue; - }, - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender.showDescXRef - * Purpose: Format the string :(DESC) as the VALUE text - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showRawValueXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - if ( tk.hasNext() ) { - xref = tk.decodeXRef(); - newValue = xref.value; - } - delete tk; - return newValue; - }, - /** - * @ignore - * - * Function: Biojs.InteractionTable._columnRender.showDescXRef - * Purpose: Format the string :(DESC) as the DESC text - * Returns: {string} the formatted value - * Inputs: - * col -> {int} column index (0-based) - * dataRow -> {string[]} 1D array containing the whole row on the cell being formatted. - * currentValue -> {string} raw cell value. - */ - showRowDescXRef: function (col, dataRow, currentValue) { - var tk = new Biojs.InteractionsTable.MITabTxtDecoder(currentValue); - var newValue = ""; - var comma = ""; - while ( tk.hasNext() ) { - xref = tk.decodeXRef(); - newValue += comma + xref.desc; - comma = ", "; - } - delete tk; - return newValue; - } - } -}, -{ - MITabTxtDecoder: function (str) { - this.buffer = ( str != undefined )? str : "" ; - this.offset = 0; - - this.nextToken = - /** - * @ignore - */ - function (delimiter) { - var token = ""; - var index; - if ( this.offset < this.buffer.length ) { - start = this.offset; - index = this.buffer.indexOf(delimiter, start); - - if ( index != -1 ) { - this.offset = index; - token = this.buffer.substring(start, index); - this.offset += delimiter.length; - } else { - this.offset = this.buffer.length; - token = this.buffer.substring(start); - } - } else { - // no more tokens - } - return token; - } - /** - * @ignore - */ - this.hasNext = function () { - return this.offset < this.buffer.length; - } - /** - * @ignore - */ - this.decodeXRef = function () { - - var token = ""; - var xref = { key:"", value:"", desc:"" }; - - token = this.nextToken(":"); - - if ( token.length > 1 ) { - - xref.key = token; - xref.value = this.nextToken("|").replace(/\"/gi,''); - - descIdx = xref.value.indexOf("("); - - if ( descIdx != -1 ) { - xref.desc = xref.value.substring( descIdx +1, xref.value.length -1); - xref.value = xref.value.substring( 0, descIdx); - } - - Biojs.console.log("XREF<"+ xref.key +">, VALUE<"+ xref.value +">, DESC<"+ xref.desc +">" ); - } - - return xref; - } - /** - * @ignore - */ - this.decodeRow = function () { - var row = []; - if ( this.hasNext() ) { - row = this.nextToken("\n").split("\t"); - } - return row; - } - /** - * @ignore - */ - this.decodeData = function () { - var data = []; - - while ( this.hasNext() ){ - data.push(this.decodeRow()); - } - return data; - } - - }, - /** - * Number of columns for MITAB 2.5 format. - * @type {int} - */ - MITAB_VERSION_2_5: 15, - /** - * Number of columns for MITAB 2.5 extended format. - * @type {int} - */ - MITAB_VERSION_2_5_EXT: 31, - /** - * Number of columns for MITAB 2.6 format. - * @type {int} - */ - MITAB_VERSION_2_6: 36, - /** - * Number of columns for MITAB 2.7 format. - * @type {int} - */ - MITAB_VERSION_2_7: 42, - /** - * Columns for all MITAB formats - * @type {Object[]} - */ - MITAB_COLUMNS: [ - { name: "Identifier A" }, - { name: "Identifier B"}, - { name: "Alternative id A"}, - { name: "Alternative id B"}, - { name: "Aliases for A"}, - { name: "Aliases for B"}, - { name: "Detection Method"}, - { name: "first author"}, - { name: "Id of publication"}, - { name: "NCBI taxon A"}, - { name: "NCBI taxon B"}, - { name: "Interaction type"}, - { name: "Source"}, - { name: "Interaction identifier(s)"}, - { name: "Confidence score"}, - { name: "Complex expansion"}, - { name: "Biological role A"}, - { name: "Biological role B"}, - { name: "Experimental role A"}, - { name: "Experimental role B"}, - { name: "Interactor type A"}, - { name: "Interactor type B"}, - { name: "Xref for interactor A"}, - { name: "Xref for interactor B"}, - { name: "Xref for the interaction"}, - { name: "Annotations for interactor A"}, - { name: "Annotations for Interactor B"}, - { name: "Annotations for the interaction"}, - { name: "NCBI Taxonomy identifier for the host organism"}, - { name: "Parameters of the interaction"}, - { name: "Creation date"}, - { name: "Update date"}, - { name: "Checksum for interactor A"}, - { name: "Checksum for interactor B"}, - { name: "Checksum for interaction"}, - { name: "negative"}, - { name: "Binding domain for interactor A"}, - { name: "Binding domain for interactor B"}, - { name: "Stoichiometry for interactor A"}, - { name: "Stoichiometry for interactor B"}, - { name: "Participant identification method for interactor A"}, - { name: "Participant identification method for interactor B"} - ], - /** - * Map to translate the XRef key into an URL - * @type {Object} - */ - DATABASE_URL: { - uniprotkb: 'http://www.uniprot.org/uniprot/', - intact: 'http://www.ebi.ac.uk/intact/', - taxid: 'http://www.uniprot.org/taxonomy/', - psimi: 'http://www.ebi.ac.uk/ontology-lookup/browse.do?ontName=MI&termId=' - } - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractiveInteractionTable.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractiveInteractionTable.js deleted file mode 100755 index dccd2d011b..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.InteractiveInteractionTable.js +++ /dev/null @@ -1,1221 +0,0 @@ - /* - * This is the description of the cInteractionTable component. - * Construct or refresh a dataTable of biomolecule interaction - * and provides a right click contextual menu for cell elements - * - * @class - * @extends Biojs - * - * @author Guillaume Launay - */ - -Biojs.InteractiveInteractionTable = Biojs.extend ( - /* - * @lends Biojs.InteractiveInteractionTable - * @requires jQuery core - * @dependency - * - * @requires jQuery-UI 1.10.3 - * @dependency - * - * @requires Cytoscape.js v2.0.2 - * @dependency - * - * @dependency - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * id of the div where the component should be displayed - * - * @option {string} pathId - * KEGG pathway ID - * - * @option {string} proxyUrl - * url of the proxy to use. - * - * @option {Object} expression - * expression values to highloght in the pathway. - * - * @option {string} upColor - * Prefered color for upregulated genes. - * - * @option {string} downColor - * Prefered color for downregulated genes. - * - * @option {string[]} genes - * Array containing the KEGG id of the genes to highlight. - * - * @option {Object[]} conditions - * Array containing the different conditions. - * - * @option {string} name - * Condition name. - * - * @option {string[]} values - * Array containing the gene expression values for the particular condition. - * - * @example - * var instance = new Biojs.KEGGViewer({ - * target: 'YourOwnDivId', - * pathId: 'hsa04910', - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * expression:{ - * upColor:'red', - * downColor:'blue', - * genes: ['hsa:7248', 'hsa:51763', 'hsa:2002', 'hsa:2194'], - * conditions: [ - * { - * name: 'condition 1', - * values: [-1, 0.5, 0.7, -0.3] - * }, - * { - * name: 'condition 2', - * values: [0.5, -0.1, -0.2, 1] - * }, - * { - * name: 'condition 3', - * values: [0, 0.4, -0.2, 0.5] - * } - * ] - * } - * - * }); - */ - -Biojs.KEGGViewer = Biojs.extend( -/** @lends Biojs.KEGGViewer# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - var self = this; - - if(options.expression && options.expression.conditions.length > 0) - self._initInfo(this.opt); - - self._query(this.opt); - }, - /** - * Default values for the options - * @name Biojs.KEGGViewer-opt - */ - opt: { - target: 'YourOwnDivId', - pathId: 'hsa04910', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - expression:{ - upColor:'red', - downColor:'blue', - genes: ['hsa:7248', 'hsa:51763', 'hsa:2002', 'hsa:2194'], - conditions: [ - { - name: 'condition 1', - values: [-1, 0.5, 0.7, -0.3] - }, - { - name: 'condition 2', - values: [0.5, -0.1, -0.2, 1] - }, - { - name: 'condition 3', - values: [0, 0.4, -0.2, 0.5] - } - ] - } - }, - /** - * Array containing the supported event names - * @name Biojs.KEGGViewer-eventTypes - */ - eventTypes: [], - /* - * Function: Biojs.KEGGViewer._initInfo - * Purpose: Initializes the info panel - * Inputs: opt -> {Object} component options. - */ - _initInfo: function(opt){ - - var self = this; - - var cond = ''; - opt.expression.conditions.forEach(function(e, i){ - cond+=''; - }); - - jQuery('

            ').appendTo('#'+opt.target); - - $( "#play" ).button({ - text: false, - icons: { - primary: "ui-icon-play" - } - }).click(function() { - var options; - if ( $(this).text() === "play" ) { - options = { - label: "stop", - icons: { - primary: "ui-icon-stop" - } - }; - $("#refresh").button("disable"); - - self._conditions = $("#condition > option"); - self._interval = setInterval(function(){ - - var conditions = self._conditions; - var selected = $('#condition').val(); - - var index; - for(var i=0; imax){ - max = val; - } - } - } - - opt.expression.min = min; - opt.expression.max = max; - - $( "#slider-range" ).slider({ - range: true, - min: min, - max: max, - step: 0.01, - slide: function( event, ui ) { - $( "#amount" ).text(ui.values[ 0 ] + " , " + ui.values[ 1 ] ); - } - }); - $("#amount").text($("#slider-range").slider("values", 0) +" , " + $("#slider-range").slider("values", 1)); - - $('#condition').change(function(){ - self._paintExpression(self); - }); - - }, - /* - * Function: Biojs.KEGGViewer._query - * Purpose: Queries KEGG using the provided KEGGId. - * Inputs: dataSet -> {Object} Settings of the data set. - */ - _query: function(dataSet){ - - var self = this; - $.ajax({ - dataType: 'xml', - url: dataSet.proxyUrl, - data: { - url:'http://rest.kegg.jp/get/'+dataSet.pathId+'/kgml' - }, - success: function(xml){ - self._renderPathway(xml, self); - } - }); - }, - /* - * Function: Biojs.KEGGViewer._clearExpression - * Purpose: Clears the highlighted genes - * Inputs: self -> {Object} component. - */ - _clearExpression: function(self){ - var nodes = self._cy.nodes(); - for(var j=0; j {Object} component. - */ - _paintExpression: function(self){ - - if($('#condition').val() == 'nocondition') - self._clearExpression(self); - - var min = $("#slider-range").slider("values", 0); - var max = $("#slider-range").slider("values", 1); - - var condition = {}; - for(var i=0; i max){ - color = self.opt.expression.upColor; - } - nodes[j].css("background-color", color); - } - } - } - - break; - } - } - }, - /* - * Function: Biojs.KEGGViewer._renderPathway - * Purpose: Paints the pathway - * Inputs: data -> {Object} JSON representation of the pathway - * self -> {Object} component. - */ - _renderPathway: function(data, self){ - var positions = {}, - node_map = {}; - var nodes = [], - links = [], - keggIds = []; - - $(data).find('entry').each(function(){ - var entry = $(this); - var type = entry.attr('type'); - var graphics = entry.find('graphics'); - - var text_valign = 'center', - shape = 'rectangle', - bkg_color = '#99ff99', - opacity = 0.9, - border_width = 0, - width = $(graphics).attr('width'), - height = $(graphics).attr('height'); - - if(type == 'gene'){ - border_width = 2; - }else if(type == 'ortholog'){ - border_width = 2; - }else if(type == 'compound'){ - shape = 'ellipse'; - bkg_color = '#aaaaee'; - text_valign = 'bottom'; - opacity = 1 - }else if(type == 'map'){ - shape = 'roundrectangle'; - bkg_color = '#00bfff'; - }else if( type == 'group'){ - //shape = 'roundrectangle'; - //bkg_color = '#ffffff'; - width = undefined; - height = undefined; - entry.find('component').each(function(){ - node_map[$(this).attr('id')].data.parent = entry.attr('id'); - }); - } - - var names = []; - if(graphics.attr('name') !== undefined){ - names = graphics.attr('name').split(','); - } - - var node = {}; - node.data = { - id: entry.attr('id'), - keggId: entry.attr('name').split(' '), - name: names[0], - names: names, - type: type, - link: entry.attr('link'), - width: width, - height: height, - shape: shape, - bkg_color: bkg_color, - text_valign: text_valign, - 'border-width': border_width - } - - keggIds.push(entry.attr('name')); - - node_map[entry.attr('id')] = node; - nodes.push(node); - - positions[entry.attr('id')] = { - x : +graphics.attr('x'), - y : +graphics.attr('y') - } - - }); - - $(data).find('relation').each(function(){ - var rel = $(this); - var type = rel.attr('type'); - - var subtypes = []; - rel.find('subtype').each(function(){ - var sub = $(this); - var name = sub.attr('name'), - line_style = 'solid', - target_arrow_shape = 'none', - text = ''; - - if(name == 'maplink'){ - target_arrow_shape = 'diamond'; - }else if(name == 'indirect effect'){ - line_style = 'dotted'; - target_arrow_shape = 'diamond' - }else if(name == 'state change'){ - line_style = 'dotted'; - }else if(name == 'missing interaction'){ - line_style = 'dotted'; - target_arrow_shape = 'triangle'; - }else if(name == 'phosphorylation'){ - target_arrow_shape = 'triangle'; - text = 'p+'; - }else if(name == 'dephosphorylation'){ - target_arrow_shape = 'triangle'; - text = 'p-'; - }else if(name == 'glycosylation'){ - line_style = 'dashed'; - target_arrow_shape = 'circle'; - }else if(name == 'ubiquitination'){ - line_style = 'dashed'; - target_arrow_shape = 'circle'; - }else if(name == 'methylation'){ - line_style = 'dashed'; - target_arrow_shape = 'circle'; - }else if(name == 'activation'){ - target_arrow_shape = 'triangle'; - }else if(name == 'inhibition'){ - target_arrow_shape = 'tee'; - }else if(name == 'expression'){ - target_arrow_shape = 'triangle'; - }else if(name == 'repression'){ - target_arrow_shape = 'tee'; - } - - links.push({ - data:{ - source: rel.attr('entry1'), - target: rel.attr('entry2'), - name: name, - reaction: type, - line_style: line_style, - target_arrow_shape: target_arrow_shape, - text: text - } - }); - }); - }); - - jQuery('
            ').appendTo('#'+self.opt.target).cytoscape({ - elements: { - nodes : nodes, - edges : links - }, - style: cytoscape.stylesheet().selector('node').css({ - 'content': 'data(name)', - 'text-valign': 'center', - 'width': 'data(width)', - 'height': 'data(height)', - 'shape':'data(shape)', - 'background-color': 'data(bkg_color)', - 'text-valign': 'data(text_valign)', - 'opacity': 'data(opacity)', - 'border-color': '#000000', - 'border-width': 'data(border-width)', - 'font-size': 11 - }).selector('edge').css({ - 'content': 'data(text)', - 'target-arrow-shape': 'data(target_arrow_shape)', - 'line-style': 'data(line_style)', - 'line-color':'#000000', - 'target-arrow-color':'#000000', - 'text-valign' : 'bottom' - }), - layout: { - name: "preset", - fit: false, - positions: positions - },ready:function(){ - var cy = this; - self._cy = cy; - } - }); - } -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.MmcifViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.MmcifViewer.js deleted file mode 100755 index 62f56a931a..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.MmcifViewer.js +++ /dev/null @@ -1,140 +0,0 @@ -/** - * This is the description of the MmcifViewer component. This component shows tabular views of information in PDB's mmcif files. - * - * @class - * @extends Biojs - * - * @author Swanand Gore - * @version 1.0.0 - * @category 0 - * - * - * @param {Object} options An object with the options for MmcifViewer component. - * - * - * @example - * var myview = new Biojs.MmcifViewer({ - * divid:"YourOwnDivId", pdbid:"1cbs" - * }); - * - */ -Biojs.MmcifViewer = Biojs.extend ( -/** @lends Biojs.MmcifViewer# */ -{ - /** - * Default values for the options - * @name Biojs.MmcifViewer-opt - */ - opt: { - divid: "YourOwnDivId", pdbid:'1cbs' - }, - - constructor: function (options) { - var self = this; - // make the top table with all categories listed - jQuery("#"+options.divid).html( '






            ' ); - self.pdbid = options.pdbid; - self.catable = null; - jQuery.ajax({ - url: 'http://puck.ebi.ac.uk:4000/mmcif/'+self.pdbid+'/categories', - data: {'varname':'catlist'}, - dataType: 'script', - crossDomain: 'true', - type: 'GET', - success: function(response, callOptions) { self.showCategoriesList(catlist); } - }); - }, - - showCategoriesList: function(catlist) { - var self = this; - for(var ci=0; ci < catlist.length; ci++) catlist[ci] = [catlist[ci]]; - var dtable = jQuery('#catlistTable').dataTable( { - "aaData": catlist, - "aoColumns": [ { "sTitle": "Categories" } ] - } ); - dtable.$('td').click( function () { - var sData = dtable.fnGetData( this ); - self.showAcategory(sData); - } ); - }, - standardizeVals: function(vals) { - if(vals instanceof Array) return vals; - return [vals]; - }, - showAcategory: function(catname) { - var self = this; - console.log( 'Start showing category '+catname ); - jQuery.ajax({ - url: 'http://puck.ebi.ac.uk:4000/mmcif/'+self.pdbid+'/'+catname, - data: {'varname':'catinfo'}, - dataType: 'script', - crossDomain: 'true', - type: 'GET', - success: function(response, callOptions) { self.showCategoryTable(catinfo); } - }); - //var dtable = jQuery('#catlistTable').dataTable( { - // "aaData": catlist, - // "aoColumns": [ { "sTitle": "Categories" } ] - //} ); - }, - - showCategoryTable: function(catinfo) { - var self = this; - var colinfo = [], rows = []; - for(var item in catinfo) { - colinfo.push( {"sTitle":item} ); - var vals = self.standardizeVals(catinfo[item]); - if(rows.length == 0) { - for(ri=0; ri < vals.length; ri++) rows.push([]); - } - for(ri=0; ri < vals.length; ri++) - rows[ri].push(vals[ri]); - } - if(self.catable!=null) { self.catable.fnDestroy(); jQuery("#categoryTable").html(""); } - //self.catable = null; - self.catable = jQuery('#categoryTable').dataTable( { - "aaData": rows, "aoColumns": colinfo, bDestroy:true //, "bRetrieve": true, "bDestroy": true - } ); - }, - - /** - * Array containing the supported event names - * @name Biojs.MmcifViewer-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.MmcifViewer#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} selected Selected character. - * @example - * instance.onClick( - * function( objEvent ) { - * alert("The character " + objEvent.selected + " was clicked."); - * } - * ); - * - * */ - "onClick", - - /** - * @name Biojs.MmcifViewer#onHelloSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text, will be 'Hello' obviously. - * @example - * instance.onHelloSelected( - * function( objEvent ) { - * alert("The word " + objEvent.textSelected + " was selected."); - * } - * ); - * - * */ - "onHelloSelected" - ] -}); - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBLogos.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBLogos.js deleted file mode 100755 index ac0dd21d3d..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBLogos.js +++ /dev/null @@ -1,261 +0,0 @@ -/** - * PDBLogos shows a set of icons to give a quick summary of salient features of a PDB entry. - * See more info on PDBLogos at http://pdbe.org/prints - * - * @class - * @extends Biojs - * - * @author John Gomez-Carvajal - * @version 1.0.0 - * @category 2 - * - * @requires Raphael 2.1.0 - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options An object with the options for PDBLogos component. - * - * @option {string} target - * Identifier/HTMLElement of the div container where the component should be rendered. - * - * @option {string} identifier - * PDB entry id for which prints will be rendered. - * - * @option {Object} raphael - * A Raphael object instead of div to render PDBprints into. - * - * @option {int} startX - * X-coordinate of point where rendering the array of PDBprints will start in the Raphael canvas - * - * @option {int} startY - * Y-coordinate of point point where rendering the array of PDBprints will start in the Raphael canvas - * - * @option {int} interval - * Gap size between successive PDBprints in a vertical or horizontal array - * - * @option {int} size - * Length of an icon logo - * - * @option {string} [color="#588FE5"] - * Color for background as HTML color code. - * - * @option {char} orient - * Rendering orientation either vertical or horizontal - * - * @option {string} [pdb3DIcon='biojs/css/images/3d.png'] - * Image URL to be used as 3D structure's icon - * - * @example - * var instance = new Biojs.PDBLogos({ - * target: "YourOwnDivId", - * identifier: "1cbs" - * }); - * - */ -Biojs.PDBLogos = Biojs.extend ( -/** @lends Biojs.PDBLogos# */ -{ - /** - * Default values for the options - * @name Biojs.PDBLogos-opt - */ - opt: { - target: "YourOwnDivId", - raphael: null, - identifier:"", - startX: 10, - startY: 10, - interval: 10, - size: 40, - orient: 'h', - logosURL: 'http://www.ebi.ac.uk/pdbe-apps/widgets/pdbprints', - logos: [], - color: "#588FE5", - pdb3DIcon: 'biojs/css/images/3d.png' - }, - - /** - * Array containing the supported event names - * @name Biojs.PDBLogos-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.PDBLogos#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} identifier PDB actual entry. - * @eventData {string} category Name of the PDBLogo category clicked. - * @eventData {string} printsUrl Url of the PDB general information. - * @example - * instance.onClick( - * function( e ) { - * alert("Logo " + e.category + " of PDB " + e.identifier + " was clicked."); - * } - * ); - * - * */ - "onClick" - ], - - constructor: function (options) { - this._initCanvas(); - if( !Biojs.Utils.isEmpty(this.opt.identifier) ) { - this._doRequest(this.opt.identifier); - } - }, - - _initCanvas: function() { - var config = this.opt; - - // Make Raphael object if not provided already - if ( !Biojs.Utils.isEmpty( config.raphael ) ){ - config.raphael.remove(); - config.raphael = null; - } - - var sizex = config.startX + config.size * Biojs.PDBLogos.CATEGORY.lenght; - var sizey = config.startY + (config.interval+config.size); - - if(config.orient == Biojs.PDBLogos.VERTICAL) { - sizey = config.startY + config.size * Biojs.PDBLogos.CATEGORY.lenght; - sizex = config.startX + (config.interval+config.size); - } - config.raphael = Raphael(config.target, sizex, sizey); - }, - - /** - * Sets the pdb identifier generating a new request of logos. - * - * @param {string} value PDB entry. - * - * @example - * instance.setIdentifier("1j3s"); - * - */ - setIdentifier: function ( value ) { - this.opt.identifier = value; - this._initCanvas(); - this._doRequest(value); - }, - - _doRequest: function(identifier){ - - var self = this; - - jQuery.ajax({ - url: 'http://www.ebi.ac.uk/pdbe-apps/widgets/pdbprints', - data: { 'varname':'printsdata', 'pdbid': identifier, color: "transparent" }, - dataType: 'script', - crossDomain: 'true', - type: 'GET', - success: function(response, callOptions) { self._printsLayout(printsdata); } - }); - }, - - - _printsLayout: function(data) { - var self = this; - var config = this.opt; - var ix = config.startX; - var iy = config.startY; - var i=0; - - config.logos = []; - - data[config.identifier].PDBStructure = [ config.pdb3DIcon, 'structure']; - - for( category in Biojs.PDBLogos.CATEGORY ) { - - var isizeY = config.size, isizeX = config.size; - var imgUrl = data[config.identifier][category][0]; - var printsURL = "http://www.pdbe.org"; - - ix = config.startX; - iy = config.startY; - - if( config.orient == Biojs.PDBLogos.VERTICAL ) { - iy += config.size * (i++); - } else { - ix += config.size * (i++); - } - - if(category == "PDBeLogo") { - config.logos.push( - config.raphael.text(ix, iy + self.opt.size/4, config.identifier) - .attr({ - 'font-family':'Mono', - 'text-anchor':'start', - 'font-size': self.opt.size/3, - 'cursor':'pointer', - 'title':'View all about PDB ' + config.identifier - }) - .data("identifier", config.identifier) - .mouseup( function() { - window.open( "http://www.pdbe.org/" + this.data("identifier") ); - }) - ); - - imgUrl = "http://www.ebi.ac.uk/pdbe-apps/widgets/html/PDBeWatermark_horizontal_128.png"; - isizeX = config.size * 0.9; - isizeY = config.size/2; - iy += config.size/2; - - } else { - - printsURL += "/"+config.identifier+"/" + Biojs.PDBLogos.CATEGORY[category]; - - if ( category == "PDBStructure" ) { - printsURL = "http://www.ebi.ac.uk/pdbe-srv/view/entry/" + config.identifier + "/openastex"; - } - - // Add icon background - config.raphael.rect(ix, iy, isizeX, isizeY, 7).attr({'fill':self.opt.color}); - } - - config.logos.push( - config.raphael.image(imgUrl, ix, iy, isizeX, isizeY) - .attr({ - 'cursor':'pointer', - 'title':'View '+category - }) - .data({ - "printsURL": printsURL, - "category": category - }) - .mouseup( function() { - self.raiseEvent( Biojs.PDBLogos.EVT_ON_CLICK, { - printsURL: this.data("printsURL"), - identifier: config.identifier, - category: this.data("category") - }); - }) - .mouseover( function() { } ) - ); - - } - - } - -},{ - HORIZONTAL: 'h', - VERTICAL: 'v', - - CATEGORY: { - "PDBeLogo": "", - "PrimaryCitation": "citation", - "Taxonomy": "taxonomy", - "Expressed": "taxonomy", - "Experimental": "experimental", - "Protein": "primary", - "NucleicAcid": "primary", - "Ligands": "ligands", - "PDBStructure": "PDBStructure" - }, - - EVT_ON_CLICK: "onClick" - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBprints.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBprints.js deleted file mode 100755 index 5b38cc36dd..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.PDBprints.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * This is the description of the PDBprints component. This component renders a set of icons to give a quick summary of salient features of a PDB entry. - * See more info on PDBprints at http://pdbe.org/prints - * - * @class - * @extends Biojs - * - * @author Swanand Gore - * @version 1.0.0 - * @category 0 - * - * @requires Raphael 2.1.0 - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options An object with the options for PDBprints component. - * - * @option {list} targets - * This is a list of configuration options, each corresponding to PDBprints to be rendered in a div. - * Each config consists of following: - *
              - *
            • pdbids: PDB entry ids for which prints are to be rendered.
            • - *
            • divid: the id of div in which the prints are to be rendered.
            • - *
            • rapha: A Raphael object instead of div to render PDBprints into.
            • - *
            • startX: X-coordinate of point where rendering the array of PDBprints will start in the Raphael canvas - *
            • startY: Y-coordinate of point point where rendering the array of PDBprints will start in the Raphael canvas - *
            • interval: gap between successive PDBprints in a vertical or horizontal array - *
            • size: length of an icon logo in PDBprints - *
            • orient: vertical or horizontal rendering fo PDBprints - *
            - * - * @example - * var instance = new Biojs.PDBprints({ - * targets : [ - * {divid:"YourOwnDivId", pdbids:["1aac","1cbs"]} - * ] - * }); - * - */ -Biojs.PDBprints = Biojs.extend ( -/** @lends Biojs.PDBprints# */ -{ - /** - * Default values for the options - * @name Biojs.PDBprints-opt - */ - opt: { - target: "YourOwnDivId", rapha: null, pdbids:['2x9t'] - }, - - constructor: function (options) { - var self = this; - - var defconf = {size:40, orient:'h', interval:10, startX:10, startY:10}; - - // Make Raphael object if not provided already - var deldiv = []; - for(var ci=0; ci < self.opt.targets.length; ci++) { - var config = self.opt.targets[ci]; - for(var akey in defconf) { - if(!config[akey]) config[akey] = defconf[akey]; - } - if(!config['rapha']) { - var sizex = config.startX + config.size*8; - var sizey = config.startY + (config.interval+config.size)*config.pdbids.length; - if(config.orient == "v") { - sizey = config.startY + config.size*8; - sizex = config.startX + (config.interval+config.size)*config.pdbids.length; - } - config['rapha'] = Raphael(config['divid'], sizex, sizey); - } - } - var pdbids = ''; - for(var rapha in self.opt.targets) { - for(var pi=0; pi < self.opt.targets[rapha]['pdbids'].length; pi++) - pdbids += self.opt.targets[rapha]['pdbids'][pi]+","; - } - pdbids = pdbids.replace(/,$/,""); - - jQuery.ajax({ - url: 'http://www.ebi.ac.uk/pdbe-apps/widgets/pdbprints', - data: {'varname':'printsdata', 'pdbid':pdbids}, - dataType: 'script', - crossDomain: 'true', - type: 'GET', - success: function(response, callOptions) { self.printsLayout(printsdata); } - }); - }, - - printsLayout: function(printsdata) { - var self = this; - for(var ci=0; ci < self.opt.targets.length; ci++) { - var config = self.opt.targets[ci]; - self.printsLayout1(config, printsdata) - } - }, - printsLayout1: function(conf, printsdata) { - var self = this; - var printsize = 50, printsorient = 'h', printstartX = 10, printstartY = 10, printsInterval = 5; - printsize = conf.size; - printsorient = conf.orient; - printsInterval = conf.interval; - printstartX = conf.startX; - printstartY = conf.startY; - - var printscats = [ "PDBeLogo", "PrimaryCitation", "Taxonomy", "Expressed", "Experimental", "Protein", "NucleicAcid", "Ligands" ]; - var catsinfo = { - "PDBeLogo": [""], - "PrimaryCitation": ["citation"], - "Taxonomy": ["taxonomy"], - "Expressed": ["taxonomy"], - "Experimental": ["experimental"], - "Protein": ["primary"], - "NucleicAcid": ["primary"], - "Ligands": ["ligands"] - }; - for(var pi=0; pi < conf['pdbids'].length; pi++) { - var pid = conf['pdbids'][pi]; - for(var ci=0; ci < printscats.length; ci++) { - var cat = printscats[ci]; - var ix = printstartX + printsize*ci; - var iy = printstartY; - if(printsorient == 'v') { - ix = printstartX; - iy = printstartY + printsize*ci; - } - var imgurl = printsdata[pid][cat][0], isizeY = printsize, isizeX = printsize; - var printsURL = "http://pdbe.org"; - if(cat=="PDBeLogo") { - var pidlink = conf.rapha.text(ix,iy+printsize/4,pid).attr({'font-family':'Mono', 'text-anchor':'start', 'font-size':printsize/3}) - .attr({'cursor':'pointer','title':'a tooltip '+pid}).data("pdbid",pid); // TODO tooltips - pidlink.mouseup( function() { window.open("http://pdbe.org/"+this.data("pdbid")); } ); - imgurl = "http://www.ebi.ac.uk/pdbe-apps/widgets/html/PDBeWatermark_horizontal_128.png"; - isizeX = printsize*0.9; isizeY = printsize/2; iy += printsize/2; - } - else printsURL += "/"+pid+"/"+catsinfo[cat][0]; - var printsLogo = conf.rapha.image(imgurl,ix,iy,isizeX,isizeY).attr({'cursor':'pointer','title':'a tooltip '+cat}); - printsLogo.data("printsURL", printsURL); - printsLogo.mouseup( function() { window.open(this.data("printsURL")); } ); - printsLogo.mouseover( function() { } ); - } - if(printsorient == 'v') printstartX += printsize + printsInterval; - if(printsorient == 'h') printstartY += printsize + printsInterval; - } - }, - /** - * Array containing the supported event names - * @name Biojs.PDBprints-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.PDBprints#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} selected Selected character. - * @example - * instance.onClick( - * function( objEvent ) { - * alert("The character " + objEvent.selected + " was clicked."); - * } - * ); - * - * */ - "onClick", - - /** - * @name Biojs.PDBprints#onHelloSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text, will be 'Hello' obviously. - * @example - * instance.onHelloSelected( - * function( objEvent ) { - * alert("The word " + objEvent.textSelected + " was selected."); - * } - * ); - * - * */ - "onHelloSelected" - ] -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3D.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3D.js deleted file mode 100755 index d03876020c..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3D.js +++ /dev/null @@ -1,1260 +0,0 @@ -/** - * Pdb file 3D viewer component using JMol - * - * @class - * @extends Biojs - * - * @author John Gomez, Christine Jandrasits - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires jMol 12.0.48 - * @dependency - * - * @requires Protein3D CSS - * @dependency - * - * @param {Object} options An object with the options for Biojs.Protein3D component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {int} [width=597] - * Width in pixels. - * - * @option {int} [height=400] - * Height in pixels. - * - * @option {string} [jmolFolder="{BIOJS_HOME}/dependencies/jmol-12.0.48"] - * Relative path of the jMol library. - * - * @option {string} [loadingStatusImage="{BIOJS_HOME}/css/images/ajax-loader-1.gif"] - * Relative path of the image to be displayed on loading status. - * - * @option {string} [unpolarColor="salmon"] - * This value is used by displayUnpolar() method for coloring hydrophobic residues. - * - * @option {string} [negativeColor="red"] - * This value is used by displayNegative() method for coloring acidic(-) residues. - * - * @option {string} [positiveColor="blue"] - * This value is used by displayNegative() method for coloring basic(+) residues. - * - * @option {string} [polarColor="yellow"] - * This value is used by displayNegative() method for coloring hydrophylic residues. - * - * @option {string} [backgroundColor="white"] - * Background color of the jMol applet - * - * @option {bool} [enableControls=true] - * Enable for showing the control panel. If value is 'false', it disables both methods showControls and hideControls. - * - * - * @example - * var instance = new Biojs.Protein3D({ - * target: 'YourOwnDivId' - * }); - * - * - * // Example of loading a pdb file by means of an HTTP request to - * // 'http://www.ebi.ac.uk/pdbe/entry-files/pdb1wq6.ent' through the local proxy 'proxy.php'. - * // Note that instance.setPdb(data) is invoked once the data have been arrived. - * jQuery.ajax({ - * url: '../biojs/dependencies/proxy/proxy.php', - * data: 'url=http://www.ebi.ac.uk/pdbe/entry-files/pdb1wq6.ent', - * dataType: 'text', - * success: function(pdbFile){ - * instance.setPdb(pdbFile); - * }, - * error: function(qXHR, textStatus, errorThrown){ - * alert(textStatus); - * } - * }); - * - */ -Biojs.Protein3D = Biojs.extend( -/** @lends Biojs.Protein3D# */ -{ - constructor: function (options) { - - var self = this; - - var width = this.opt.width; - var height = this.opt.height; - - this._appletId = "jmolApplet" + self.getId(); - - this._container = jQuery('#' + this.opt.target).addClass('Protein3D'); - - // Container Width - if ( width == undefined ) { - width = this._container.css('width'); - - } else { - this._container.width( width ); - } - - // Container Height - if ( height == undefined ) { - height = this._container.css('height'); - - } else { - this._container.height( height ); - } - - this.opt.backgroundColor = ( this.opt.backgroundColor !== undefined )? this.opt.backgroundColor : this._container.css('background-color'); - - this._container.html(''); - - this._controlsContainer = jQuery('
            ') - .appendTo( this._container ); - - this._appletContainer = jQuery('
            ') - .appendTo( this._container ); - - this._loadingImage = jQuery('
            ') - .appendTo( this._container ) - .hide(); - - if (this.opt.loadingStatusImage !== undefined ) { - this._loadingImage.css( 'background-image', 'url(' + this.opt.loadingStatusImage + ')' ); - } - - this._initializeJmolApplet(); - - Biojs.console.log("ending Biojs.Protein3D constructor"); - }, - - /** - * Default options (and its values) for the Protein3D component. - * @name Biojs.Protein3D-opt - * @type Object - */ - opt: - { - target: 'component', - width: 597, - height: 400, - jmolFolder: '../biojs/dependencies/jmol-12.0.48', - unpolarColor: "salmon", - negativeColor: "red", - positiveColor: "blue", - polarColor: "yellow", - backgroundColor: "white", - enableControls: true, - loadingStatusImage: undefined, - surface: "None", - style: "Cartoon", - colorScheme: "By Chain", - antialias: false, - rotate: false - }, - - /** - * Array containing the supported event names - * @name Biojs.Protein3D-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.Protein3D#onPdbLoaded - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onPdbLoaded( - * function( objEvent ) { - * alert( (objEvent.result == "success")? "Pdb file "+ objEvent.file+" loaded." : objEvent.message ); - * } - * ); - * - * */ - "onPdbLoaded", - /** - * @name Biojs.Protein3D#onSelection - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} selectionType String with either value 'region' or 'positions'. - * @eventData {Object|Array} selection If the type of selection is a region, this will be a Object - * with attributes 'start' and 'end'. In other case, this will be an array - * containing the selected positions. - * - * @example - * instance.onSelection( - * function( objEvent ) { - * selection = (objEvent.selectionType === "region")? (objEvent.selection.start +" - "+ objEvent.selection.end) : objEvent.selection.join(','); - * alert( "Selected "+objEvent.selectionType+": "+selection ); - * } - * ); - * - * */ - "onSelection" - ], - - /* Internal members */ - _appletId: undefined, - _controlsReady: false, - _jmoljarfile: "JmolApplet.jar", - _jmolAppletInitialized: false, - _selection: undefined, - _selectionType: undefined, - - _display: { - property: { - polar: false, - unpolar: false, - positive: false, - negative: false - }, - surface: false, - halos: true - }, - - - _initializeJmolApplet: function() { - - var self = this; - - jmolInitialize( self.opt.jmolFolder ); - jmolSetAppletColor( self.opt.backgroundColor ); - jmolSetDocument(0); - - // Jmol needs a global function for executing up whenever a pbd is loaded - // Name for the function in global scope - var functionCbName = self._appletId + "_pdbLoadCb"; - - Biojs.console.log("registring callback function loadStructCallback " + functionCbName); - - // Register the function this._loadStructCallback as global for JmolApplet use - Biojs.registerGlobal( functionCbName , self._loadStructCallback ); - - // Tell Jmol the name of the function in global scope - jmolSetCallback("loadStructCallback", functionCbName ); - }, - - /** - * Shows the form of controls. - * - * @example - * instance.showControls(); - * - */ - showControls: function() { - this.changeControlsVisiblility(true); - }, - - /** - * Hides the form of controls. - * - * @example - * instance.hideControls(); - * - */ - hideControls: function() { - this.changeControlsVisiblility(false); - }, - - /** - * Shows/Hides the form of controls. - * - * @example - * instance.changeControlsVisiblility(true); - * - */ - changeControlsVisiblility: function( flag ) { - - if (this.opt.enableControls) { - - if (!this._controlsReady) { - this._buildControls(); - } - - if ( flag != this._controlsAreVisible() ) { - this._toggleControls(); - } - } - }, - - /** - * Returns the information about the region of the currently PDB file. - * - * @example - * //Show the region in an alert window. - * var selection = instance.getSelection(); - * alert("selected: "+ selection ); - * - * @returns {Object|Array} - * Returns a plain object if the current selection is a region. - * In this case, will contain the fields start and end; where "start" is greater than or equal to "end". - * Returns an array if the current selection is a set of positions. - * Returns undefined if there are not selection. - * - */ - getSelection: function(){ - return Biojs.Utils.clone(this._selection); - }, - - /** - * Restores the default display settings for the current PDB file. - * Note: for removing out the current selection use removeSelection(). - * - * @example instance.reset(); - */ - reset: function(){ - jmolScriptWait( this._getDisplayColor( this.opt.colorScheme ) + this._getDisplayStyle( this.opt.style ), this.getId() ); - - // TODO: use functions instead of jquery - - var theTargetDiv = jQuery("#"+this.opt.target); - theTargetDiv.find("div#controlSection > div#controls > input[type='checkbox']").attr("checked",false); - theTargetDiv.find('#styleSelect').val( this.opt.style ); - theTargetDiv.find('#colorSelect').val( this.opt.colorScheme ); - theTargetDiv.find('#surfaceSelect').val( this.opt.style ); - - for (var key in this._display.property) { - this._display.property[key] = false; - } - - this.setHalosVisible(true); - }, - - showLoadingImage: function(flag){ - var visible = (flag === undefined) ? true: flag; - - // Toggle loading image if its status is different than flag - if ( this._loadingImage.is(':visible') != visible ) { - this._controlsContainer.toggle(); - this._appletContainer.toggle(); - this._loadingImage.toggle(); - } - }, - - /** - * Sets the pdb file to be displayed. - * Also triggers the event whenever a new pdb file is loaded. - * - * @param {string} pdb The content of the pdb file. - * - * @example - * instance.showLoadingImage(); - * - * jQuery.ajax({ - * url: '../biojs/dependencies/proxy/proxy.php', - * data: 'url=http://www.ebi.ac.uk/pdbe/entry-files/pdb3u01.ent', - * dataType: 'text', - * success: function(pdbFile){ - * instance.setPdb(pdbFile); - * }, - * error: function(qXHR, textStatus, errorThrown){ - * alert(textStatus); - * } - * }); - * - */ - setPdb: function( pdb ){ - Biojs.console.log("LOADING pdb content"); - //Biojs.console.log(pdb); - - var self = this; - var surfaceCmd = this._getDisplaySurface( this.opt.surface ); - var styleCmd = this._getDisplayStyle( this.opt.style ); - var colorSchemeCmd = this._getDisplayColor( this.opt.colorScheme ); - - var scr = colorSchemeCmd + styleCmd + surfaceCmd + this._getSelectionScript( this._selection ); - - this.showLoadingImage(false); - - if ( this._jmolAppletInitialized ) { - this.reset(); - } - - htmlContent = jmolAppletInline([self._appletContainer.width(), self._appletContainer.height()], pdb, scr, self.getId() ); - - this._appletContainer.html( htmlContent ); - this._jmolAppletInitialized = true; - - Biojs.console.log("setPdb() ending"); - }, - - /** - * Reverts the highlighting of a region and removes the current selection. - * - * @example - * instance.removeSelection(); - * - */ - removeSelection: function(){ - this._selection = undefined; - var scr = 'select all; '; - scr += (!this._display.halos)? 'color translucent 1; ': 'selectionHalos off; '; - scr += 'select none;' - jmolScriptWait(scr, this.getId()); - }, - - // function that highlights the atoms in the given region - // has the same interface as in Dasty - - - /** - * Filters the currently provided PDB files: Only PDB files containing a part of the requested region - * are selectable. The specified region is highlighted in the displayed PDB file. - * - * @example - * // Selection of the region in the interval [100,150]. - * instance.setSelection({start: 100, end: 150}); - * - * @example - * // Selection of the positions 4, 8 and 100. - * instance.setSelection([4,8,100]); - * - * @example - * // Selection from 51 to 60, 87, and from 101 to 110 - * instance.setSelection([{start:51,end:60},87,{start:101,end:110}]); - * - * @param {Object|Array} selection Can be either a plain object or an array. - * If object, it must have the fields start and end; Where "start" is greater than or equal to "end". - * If array, it must contain numbers representing the positions to be selected. - */ - setSelection: function(selection){ - if ( selection instanceof Array ) { - this._selection = Biojs.Utils.clone(selection); - this._drawSelection(); - this.raiseEvent( Biojs.Protein3D.EVT_ON_SELECTION, { - selectionType: this._selectionType, - selection: Biojs.Utils.clone(selection) - }); - } - else if ( selection instanceof Object && selection.start <= selection.end ){ - this._selection = Biojs.Utils.clone(selection); - this._drawSelection(); - this.raiseEvent( Biojs.Protein3D.EVT_ON_SELECTION, { - selectionType: "region", - selection: Biojs.Utils.clone(selection) - }); - } else { - Biojs.console.log("selection not valid"); - } - }, - - // highlight given region - _getSelectionScript: function(selection){ - var scr = ""; - var selectionText = ""; - var singleRegion = false; - var regionInSelection = false; - var positionInSelection = false; - - if ( selection ){ - scr = 'select all; color translucent 1;'; - //selectionText = (selection instanceof Array)? selection.join(",") : selection.start + "-" + selection.end; - if (selection instanceof Array) { - for (i = 0; i < selection.length; i++) { - if (selection[i] instanceof Object) { - selectionText = selectionText + selection[i].start + "-" + selection[i].end; - regionInSelection = true; - } else { - selectionText = selectionText + selection[i]; - positionInSelection = true; - } - if (i != (selection.length-1)) { - selectionText = selectionText + ","; - } - } - } else { - selectionText = selection.start + "-" + selection.end; - singleRegion = true; - } - - if ( !this._display.halos ) { - scr += 'select not ' + selectionText + '; color translucent 0.8; selectionHalos off;'; - } else { - scr += 'select ' + selectionText + '; selectionHalos on;'; - } - } else { - scr = "select none"; - } - Biojs.console.log("Selection script: " + scr); - if (singleRegion == true) { - this._selectionType = "region"; - } else if ((regionInSelection == true) && (positionInSelection == true)) { - this._selectionType = "mixed"; - } else if ((regionInSelection == true) && (positionInSelection == false)) { - this._selectionType = "multipleRegion"; - } else if ((regionInSelection == false) && (positionInSelection == true)) { - this._selectionType = "positions"; - } else { - this._selectionType = "region"; - } - Biojs.console.log("Selection type: " + this._selectionType); - return scr; - }, - - _drawSelection: function(){ - if ( this._selection !== undefined ) { - result = jmolScriptWait( this._getSelectionScript(this._selection), this.getId() ); - Biojs.console.log("Selection done, result: "+result); - } - }, - - /** - * Apply antialias rendering filter. - * - * @param {boolean} flag If true, smooth rendering will be applied. - * - * @example - * instance.displayAntialias(true); - */ - displayAntialias: function ( flag ) { - // Update the checkbox control - this._getControl('antialiasCheck').attr("checked", flag ); - // Apply the antialiasing - this.applyJmolCommand('set antialiasDisplay '+ flag ); - }, - - /** - * Apply rotation. - - * @example - * instance.rotate(true); - * - */ - rotate: function ( flag ) { - // Update the checkbox control - this._getControl('rotationCheck').attr("checked", flag ); - // Apply the rotation - this.applyJmolCommand('spin '+ flag ); - }, - - /** - * Draws a translucent surface surrounding the protein. - * - * @param {string} name Type of surface wanted. Use one of these: Biojs.Protein3D.SURFACE_NONE, - * Biojs.Protein3D.SURFACE_ACCESSIBLE, Biojs.Protein3D.SURFACE_EXCLUDED, Biojs.Protein3D.SURFACE_CAVITIES - * - * @example - * instance.displaySurface( Biojs.Protein3D.SURFACE_CAVITIES ); - * - */ - displaySurface: function ( name ) { - - var surfaceCmd = this._getDisplaySurface( name ); - - if ( surfaceCmd === undefined ) { - Biojs.console.log("Unknown surface name " + name ); - return; - } - - // Update select control - this._getControl('surfaceSelect').val(name); - this.applyJmolCommand( surfaceCmd + this._getSelectionScript(this._selection) ); - }, - - /** - * Undo the action of method displaySurface. - * - * @example - * // - * instance.hideSurface(); - * - */ - hideSurface: function(){ - this.displaySurface( Biojs.Protein3D.SURFACE_NONE ); - }, - - /** - * Selects the acidic atoms and do coloring. - * - * @param {string} [color="red"] Refer to the Jmol documentation for availables coloring schemes. - * - * @example - * // - * instance.displayNegative("red"); - * - */ - displayNegative: function (color, flag) { - - color = ( color !== undefined )? color : this.opt.positiveColor; - flag = ( flag !== undefined )? flag : true; - - // Update the checkbox control - this._getControl('negativeCheck').attr("checked", flag ); - - // Update the Jmol applet - (flag) ? this.display('acidic', color) : this.undisplay('acidic'); - this._display.property.negative = flag; - - }, - /** - * Undo the action of method displayNegative. - * - * @example - * // - * instance.hideNegative(); - * - */ - hideNegative: function () { - this.displayNegative(undefined, false); - }, - - /** - * Selects the basic atoms and do coloring. - * - * @param {string} [color="blue"] Refer to the Jmol documentation for availables coloring schemes. - * - * @example - * // - * instance.displayPositive(); - * - */ - displayPositive: function ( color, flag ) { - - color = ( color !== undefined )? color : this.opt.positiveColor; - flag = ( flag !== undefined )? flag : true; - - // Update the checkbox control - this._getControl('positiveCheck').attr("checked", flag ); - - // Update the Jmol applet - (flag) ? this.display('basic', color) : this.undisplay('basic'); - this._display.property.positive = flag; - }, - - /** - * Undo the action of method displayPositive. - * - * @example - * // - * instance.hidePositive(); - * - */ - hidePositive: function () { - this.displayPositive(undefined, false); - }, - - /** - * Selects the polar atoms and do coloring. - * - * @param {string} [color="yellow"] Refer to the Jmol documentation for availables coloring schemes. - * - * @example - * // - * instance.displayPolar(); - * - */ - displayPolar: function ( color, flag ) { - - polarColor = ( color !== undefined )? color : this.opt.polarColor; - flag = ( flag !== undefined )? flag : true; - - // Update the checkbox control - this._getControl('polarCheck').attr("checked", flag ); - - // Update the Jmol applet - (flag) ? this.display('polar', polarColor) : this.undisplay('polar'); - this._display.property.polar = flag; - - }, - - _getControl: function ( name ) { - return jQuery ( jQuery( "#"+this.opt.target ).find( '#'+name )[0] ); - }, - - /** - * Undo the action of method displayPolar. - * - * @example - * // - * instance.hidePolar(); - * - */ - hidePolar: function () { - this.displayPolar( undefined, false ); - }, - - /** - * Selects the polar atoms and do coloring. - * - * @param {string} [color="salmon"] Refer to the Jmol documentation for availables coloring schemes. - * - * @example - * // - * instance.displayUnPolar(); - * - */ - // colors the structure depending on the checked check boxes - displayUnPolar: function ( color, flag ) { - - color = ( color !== undefined )? color : this.opt.unpolarColor; - flag = ( flag !== undefined )? flag : true; - - // Update the checkbox control - this._getControl('unpolarCheck').attr("checked", flag ); - - // Update the Jmol applet - (flag) ? this.display('hydrophobic', color) : this.undisplay('hydrophobic'); - this._display.property.unpolar = flag; - }, - - - /** - * Selects the color scheme for the current structure. - * - * @param {string} colorScheme Color scheme to be applied to the current structure. - * Use one of these values: Biojs.Protein3D.COLOR_BY_CHAIN, Biojs.Protein3D.COLOR_SECONDARY_STRUCTURE, - * Biojs.Protein3D.COLOR_RAINBOW, Biojs.Protein3D.COLOR_BY_ELEMENT, Biojs.Protein3D.COLOR_BY_AMINO_ACID, - * Biojs.Protein3D.COLOR_BY_TEMPERATURE, Biojs.Protein3D.COLOR_HIDROPHOBICITY - * - * @example - * instance.displayColorScheme(Biojs.Protein3D.COLOR_RAINBOW); - * - */ - displayColorScheme: function ( colorScheme ) { - - colorCmd = this._getDisplayColor( colorScheme ); - - if ( colorCmd === undefined ) { - Biojs.console.log("Unknown color scheme " + colorScheme ); - return; - } - - this._getControl("colorSelect").val( colorScheme ); - this.applyJmolCommand( colorCmd + this._getSelectionScript( this._selection ) ); - }, - /** - * Selects the style for the current structure. - * - * @param {string} style Style of structure to be applied to the current structure. - * Use one of these values: Biojs.Protein3D.STYLE_CARTOON, Biojs.Protein3D.STYLE_BACKBONE, Biojs.Protein3D.STYLE_CPK, - * Biojs.Protein3D.STYLE_BALL_STICK, Biojs.Protein3D.STYLE_LIGANDS, Biojs.Protein3D.STYLE_LIGANDS_POCKET - * - * @example - * instance.displayStyle( Biojs.Protein3D.STYLE_CPK ); - * - */ - displayStyle: function ( style ) { - - var styleCmd = this._getDisplayStyle( style ); - - if ( styleCmd === undefined ) { - Biojs.console.log("Unknown style name " + style ); - return; - } - - this._getControl("styleSelect").val( style ); - this.applyJmolCommand( styleCmd + this._getSelectionScript(this._selection) ); - }, - - /** - * Undo the action of method displayUnPolar. - * - * @example - * // - * instance.hideUnPolar(); - * - */ - hideUnPolar: function () { - this.displayUnPolar( undefined, false ); - }, - - /** - * Enable/disable the visibility of halos for showing up the current selection. - * On halos off, all not selected atoms will be translucent. - * - * @param {boolean} value 'true' for halos on, 'false' for halos off. - * - * @example - * // Sets the halos off - * instance.setHalosVisible(false); - * - */ - setHalosVisible: function (value) { - this._display.halos = value; - if (value) { - if ( ! jQuery("#"+this.opt.target).find('#halosRadio:checked').val() ) { - jQuery("#"+this.opt.target).find('#halosRadio').attr("checked","halosRadio"); - jQuery("#"+this.opt.target).find('#translucentRadio').removeAttr("checked"); - } - } else { - if ( jQuery("#"+this.opt.target).find('#halosRadio:checked').val() ) { - jQuery("#"+this.opt.target).find('#halosRadio').removeAttr("checked"); - jQuery("#"+this.opt.target).find('#translucentRadio').attr("checked","translucentRadio"); - } - } - - this._drawSelection(); - }, - - /** - * Apply a script to the Jmol applet that currently are displayed - * - * @example - * // Rotate one time in X-axis. - * instance.applyJmolCommand('select all; cartoon off; meshribbons on;'); - * - * @param {string} The Jmol script. - */ - applyJmolCommand: function(cmd){ - jmolScriptWait(cmd, this.getId()); - }, - - /** - * Select and coloring atoms. - * - * @example - * // Select hetero atoms and coloring with the RGB triplet code [xFF0088]. - * instance.display("hetero","[xFF0088]"); - * - * @param {string} The color. Refer to the Jmol documentation for availables coloring schemes. - */ - display: function(property, color) { - scr = (this._isAnyDisplayed())? '' : 'select all; color lightgrey;'; - scr += 'select '+property+';color '+color+'; select none'; - - jmolScriptWait(scr, this.getId()); - Biojs.console.log("applied: "+scr); - - this._drawSelection(); - }, - - /** - * Select and coloring atoms. - * - * @example - * // Select hetero atoms and coloring with the RGB triplet code [xFF0088]. - * instance.changeBackgroundColor("[xFF0088]"); - * - * @param {string} color Refer to the Jmol documentation for availables coloring schemes. - */ - changeBackgroundColor: function ( color ) { - this.applyJmolCommand('background '+ ( ( color !== undefined )? color : this.opt.backgroundColor) ); - }, - - /** - * Select and remove the coloring atoms. - * - * @example - * // Select hetero atoms and remove the coloring . - * instance.undisplay("hetero"); - * - * @param {string} The Jmol script. - */ - undisplay: function( property ) { - scr = 'select '+property+';color lightgrey; select none;' - scr += (this._isAnyDisplayed())? '' : 'select all; color chain; select none;'; - - jmolScriptWait(scr, this.getId()); - Biojs.console.log("applied: "+scr); - - this._drawSelection(); - }, - - _isAnyDisplayed: function(){ - for ( var key in this._display.property ){ - if ( this._display.property[key] ) { - return true; - } - } - return false; - }, - - _buildTabPanel: function( container, onVisibilityChangeCb ) { - - container.html(''); - - var content = jQuery('
            ').appendTo(container); - content.expand = jQuery('').appendTo(container); - content.collapse = jQuery('
            ').appendTo(container); - - var contentWidth = container.width() - content.expand.outerWidth(); - - container.css( 'left', 0 ) - .find('.toggle.collapse') - .click( function(){ - // Animate show/hide this tab - container.animate({ - left: ( content.expand.width() - container.outerWidth() ) + "px" - }, - // to call once the animation is complete - function() { - - container.find('.toggle').toggle(); - - // apply callback function if defined - if ( "function" == typeof onVisibilityChangeCb ) { - onVisibilityChangeCb.call( content, false, content.expand.outerWidth() ); - } - - content.hide(); - container.css( {left: '0px', width: 'auto'}); - - } - ); - }) - .css({ - 'float':'right', - 'position':'relative' - }); - - container - .find('.toggle.expand') - .click( function(){ - - container.css({ left: ( -contentWidth ) + "px" }); - content.show(); - - container.animate({ - left: '0px' - }, - function() { - container.find('.toggle').toggle(); - - // apply callback function if defined - if ( "function" == typeof onVisibilityChangeCb ) { - onVisibilityChangeCb.call( content, true, container.outerWidth() ); - } - } - ); - }); - - Biojs.console.log('content width '+ contentWidth); - - content.css({ - 'width': contentWidth + "px", - 'height': container.height() + "px", - 'word-wrap': 'break-word' - }); - - return content; - }, - - _buildControls : function () { - Biojs.console.log("_buildControls()"); - - if ( this._controlsReady ) { - Biojs.console.log("exiting _buildControls(): controls has been built already."); - return; - } - - var self = this; - - jmolResizeApplet([ self._container.width() - self._controlsContainer.outerWidth(), self._container.height()], self.getId()); - - this._controlsDiv = this._buildTabPanel( - this._controlsContainer, - function ( isVisible, visibleWidth ) { - jmolResizeApplet([ self._container.width() - visibleWidth, self._container.height()], self.getId()); - self._appletContainer.css("width", self._container.width() - visibleWidth ); - } - ); - - var controlDiv = this._controlsDiv.append( - '

            Display:

            ' + - ' Hydrophylic residues
            ' + - ' Hydrophobic residues
            ' + - ' Basic(+) residues
            ' + - ' Acidic(-) residues
            ' + - ' Antialias
            '+ - ' Black background
            '+ - ' Rotation'+ - - '

            Style:

            '+ - - '

            Color:

            '+ - - '

            Surface:

            '+ - - '

            Show selection using:

            ' + - ' Translucent ' + - ' Halos') - - .change( function ( e ) { - - var targetId = jQuery(e.target).attr('id'); - - switch ( targetId ) { - case "polarCheck": - self.displayPolar( undefined, e.target.checked ); - break; - case "unpolarCheck": - self.displayUnPolar( undefined, e.target.checked ); - break; - case "positiveCheck": - self.displayPositive( undefined, e.target.checked ); - break; - case "negativeCheck": - self.displayNegative( undefined, e.target.checked ); - break; - case "antialiasCheck": - self.displayAntialias( event.target.checked ); - break; - case "rotationCheck": - self.rotate( event.target.checked ); - break; - case "backgroundCheck": - self.changeBackgroundColor( "black", e.target ); - break; - case "styleSelect": - self.displayStyle( e.target.value ); - break; - case "colorSelect": - self.displayColorScheme( e.target.value ); - break; - case "surfaceSelect": - self.displaySurface( e.target.value ); - break; - case "translucentRadio": - self.setHalosVisible(false); - break; - case "halosRadio": - self.setHalosVisible(true); - break; - default: - ; - } - - }); - - this._controlsReady = true; - - Biojs.console.log("_buildControls done"); - }, - - _controlsAreVisible: function () { - return this._controlsContainer.find('.toggle.collapse').is(':visible'); - }, - - _toggleControls: function(){ - - if ( this._controlsAreVisible() ) { - this._controlsContainer.find('.toggle.collapse').click(); - } else { - this._controlsContainer.find('.toggle.expand').click(); - } - }, - - _addControl: function(html){ - this._controlsDiv.append( html ); - }, - - _getDisplayStyle: function ( text ) { - if (text == Biojs.Protein3D.STYLE_CARTOON ) { - - return "hide null; select all; spacefill off; wireframe off; backbone off;" + - " cartoon on; " + - " select ligand; wireframe 0.16;spacefill 0.5; color cpk; " + - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - } - else if (text == Biojs.Protein3D.STYLE_BACKBONE ) { - - return "hide null; select all; spacefill off; wireframe off; backbone 0.4;" + - " cartoon off; " + - " select ligand; wireframe 0.16;spacefill 0.5; color cpk; " + - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - - } else if (text == Biojs.Protein3D.STYLE_CPK ) { - - return "hide null; select all; spacefill off; wireframe off; backbone off;" + - " cartoon off; cpk on;" + - " select ligand; wireframe 0.16;spacefill 0.5; color cpk; " + - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - - } - else if (text == Biojs.Protein3D.STYLE_LIGANDS ) { - return "restrict ligand; cartoon off; wireframe on; display selected;"+ - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - } - - else if (text == Biojs.Protein3D.STYLE_LIGANDS_POCKET ) { - return " select within (6.0, true, ligand); cartoon off; wireframe on; backbone off; display selected; " + - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - } - else if (text == Biojs.Protein3D.STYLE_BALL_STICK ) { - - return "hide null; restrict not water; wireframe 0.2; spacefill 25%;" + - " cartoon off; backbone off; " + - " select ligand; wireframe 0.16; spacefill 0.5; color cpk; " + - " select *.FE; spacefill 0.7; color cpk ; " + - " select *.CU; spacefill 0.7; color cpk ; " + - " select *.ZN; spacefill 0.7; color cpk ; " + - " select all; "; - - } else { - return undefined; - } - }, - - _getDisplayColor: function ( text ) { - if ( text == Biojs.Protein3D.COLOR_BY_CHAIN ) { - return "hide null; select all; cartoon on; wireframe off; spacefill off; color chain; select ligand; wireframe 0.16; spacefill 0.5; color chain ; select all; "; - } - else if ( text == Biojs.Protein3D.COLOR_BY_TEMPERATURE ) { - return "hide null; select all;spacefill off; wireframe off; backbone 0.4; cartoon off; set defaultColors Jmol; color relativeTemperature; color cartoon relateiveTemperature select ligand;wireframe 0.16;spacefill 0.5; color cpk ;; select all; " ; - } - else if ( text == Biojs.Protein3D.COLOR_RAINBOW ){ - return "hide null; select all; set defaultColors Jmol; color group; color cartoon group; select ligand;wireframe 0.16;spacefill 0.5; color cpk ; select all; " ; - } - else if ( text == Biojs.Protein3D.COLOR_SECONDARY_STRUCTURE ){ - return "hide null; select all; set defaultColors Jmol; color structure; color cartoon structure;select ligand;wireframe 0.16;spacefill 0.5; color cpk ;; select all; " ; - } - else if ( text == Biojs.Protein3D.COLOR_BY_ELEMENT ){ - return "hide null; select all; set defaultColors Jmol; color cpk; color cartoon cpk; select ligand;wireframe 0.16; spacefill 0.5; color cpk ; select all; " ; - } - else if ( text == Biojs.Protein3D.COLOR_BY_AMINO_ACID ){ - return "hide null; select all; set defaultColors Jmol; color amino; color cartoon amino; select ligand;wireframe 0.16;spacefill 0.5; color cpk ;; select all; " ; - } - else if ( text == Biojs.Protein3D.COLOR_HIDROPHOBICITY ){ - return "hide null; set defaultColors Jmol; select hydrophobic; color red; color cartoon red; select not hydrophobic ; color blue ; color cartoon blue; select ligand;wireframe 0.16;spacefill 0.5; color cpk ;; select all; " ; - } else { - return undefined; - } - }, - - _getDisplaySurface: function ( text ) { - if ( text == Biojs.Protein3D.SURFACE_NONE ){ - return "select all; isosurface off; select none;"; - } - else if ( text == Biojs.Protein3D.SURFACE_ACCESSIBLE ){ - return "select all; isosurface sasurface 1.2; color isoSurface translucent 0.8; select none;"; - } - else if ( text == Biojs.Protein3D.SURFACE_EXCLUDED ){ - return "select all; isosurface solvent 1.2; color isoSurface translucent 0.8; select none;"; - } - else if ( text == Biojs.Protein3D.SURFACE_CAVITIES ){ - return "select all; isosurface cavity 1.2 10; color isoSurface translucent 0.8; select none;"; - } else { - return undefined; - } - }, - - toString: function() { - return "Biojs.Protein3D"; - }, - /* - * Function: Biojs.Protein3D._functionCbName - * Purpose: enable controls an triggers the loading pdb file event. - * It is invoked by JmolApplet. - * Returns: - - * Inputs: - * appletId -> {string} Applet identifier. - * url -> {string} URL of the loaded file (full path+filename). - * file -> {string} the filename of the loaded file (without the path). - * title -> {string} the internal title of the model in the loaded file. - * message -> {string} any error messages generated. - * code -> {int} A numeric code: - * 3 when the file loaded successfully, - * 0 when the model was zapped, - * -1 when the loading failed. - * formerFrame -> {string} a text string with the frame - * number prior to loading the current model, in file.model syntax - * (for example, "3.1" or "1.1 - 3.31" if a whole range of models was framed). - * frame -> {string} A text string with the last frame number after loading the current model, - * in file.model syntax. - */ - _loadStructCallback: function ( appletId, url, file, title, message, code, formerFrame, frame ) { - - Biojs.console.log("executing _loadStructCallback for " + appletId); - - switch (code) { - case 3 : result = 'success'; break; - case 0 : result = 'zapped'; break; - case -1 : result = 'failure'; break; - default : result = 'undefined'; break; - } - - // Ignore the execution of the callback on replacing pdb file. - if ( "zapped" != result ) { - var instanceId = parseInt( appletId.replace("jmolApplet",'') ); - var instance = Biojs.getInstance(instanceId); - - if ( "success" == result ) { - instance.showControls(); - instance.displayAntialias(instance.opt.antialias); - instance.rotate(instance.opt.rotate); - } - - instance.raiseEvent(Biojs.Protein3D.EVT_ON_PDB_LOADED, { - "file": title, - "result": result, - "message": message - }); - - } - - } - - -},{ - // - // Coloring Schemes - // - COLOR_BY_CHAIN: "By Chain", - COLOR_SECONDARY_STRUCTURE: "Secondary Structure", - COLOR_RAINBOW: "Rainbow", - COLOR_BY_ELEMENT: "By Element", - COLOR_BY_AMINO_ACID: "By Amino Acid", - COLOR_BY_TEMPERATURE: "By Temperature", - COLOR_HIDROPHOBICITY: "Hidrophobicity", - // - // Surfaces - // - SURFACE_NONE: "None", - SURFACE_ACCESSIBLE: "Solvent Accessible", - SURFACE_EXCLUDED: "Solvent Excluded", - SURFACE_CAVITIES: "Cavities", - // - // Drawing Style - // - STYLE_CARTOON: "Cartoon", - STYLE_BACKBONE: "Backbone", - STYLE_CPK: "CPK", - STYLE_BALL_STICK: "Ball and Stick", - STYLE_LIGANDS: "Ligands", - STYLE_LIGANDS_POCKET: "Ligands and Pocket", - // - // Events - // - EVT_ON_PDB_LOADED: "onPdbLoaded", - EVT_ON_SELECTION: "onSelection" -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DCanvas.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DCanvas.js deleted file mode 100755 index 0a2b4ac465..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DCanvas.js +++ /dev/null @@ -1,289 +0,0 @@ -/** - * Pdb file 3D viewer component using JSMol and Canvas HTML5 technology if available (downgrade to Applet technology otherwise). - * - * - * @class - * @extends Biojs.Protein3D - * - * @author Francesco Talo - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.8.2 (not necessaty if you import the JSmol.min.js) - * @dependency - * - * @requires jsMol 14.0.2 - * @dependency - * - * @requires jsMol 14.0.2 (use this if you import separately jQuery) - * @dependency - - * - * - * @requires jsMol 14.0.2 (use this if you don't import already jQuery in your application) - * @dependency - * - * - * - * @requires Protein3D CSS - * @dependency - * - * @param {Object} options An object with the options for Biojs.Protein3DCanvas component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {int} [width=597] - * Width in pixels. - * - * @option {int} [height=400] - * Height in pixels. - * - * @option {string} [jsmolFolder="{BIOJS_HOME}/dependencies/jmol-12.0.48"] - * Relative path of the jSMol library. - - * @option {string} [use="HTML5 JAVA"] - * This string determines the various options to be tried (HTML5, Java Applet and surrogates) and the order in which to try them. - * The default setting is HTML5 CANVAS and then Java if Canvas is not available. - * - * @option {string} [urlProxy="{BIOJS_HOME}/dependencies/jsmol-14.0.2/jsmol/proxy/jsmol.jsp"] - * Path of the proxy to use for transformation of the gzip file in base64 files for MSIE and CHROME. - * - * @option {string} [loadingStatusImage="{BIOJS_HOME}/css/images/ajax-loader-1.gif"] - * Relative path of the image to be displayed on loading status. - * - * @option {string} [unpolarColor="salmon"] - * This value is used by displayUnpolar() method for coloring hydrophobic residues. - * - * @option {string} [negativeColor="red"] - * This value is used by displayNegative() method for coloring acidic(-) residues. - * - * @option {string} [positiveColor="blue"] - * This value is used by displayNegative() method for coloring basic(+) residues. - * - * @option {string} [polarColor="yellow"] - * This value is used by displayNegative() method for coloring hydrophylic residues. - * - * @option {string} [backgroundColor="white"] - * Background color of the jMol applet - * - * @option {bool} [enableControls=true] - * Enable for showing the control panel. If value is 'false', it disables both methods showControls and hideControls. - - @option {bool} [viewControls=true] - * Show/Hide controls panel after the loading of the PDB structure. - * - * - * @example - * // Example of loading a pdb file by means of an HTTP request to get the zip file - * // 'http://www.rcsb.org/pdb/files/"+pdb+".pdb.gz' containing the structure of the protein. - * //The file id downloaded form the server as a zipped file and then it's unzipped on the client - * var instance = new Biojs.Protein3DCanvas({ - * target: "YourOwnDivId", - * jsmolFolder: '/bioJs/dependencies/jsmol-14.0.2/jsmol', - * height: 440, - * width: 440, - * style: Biojs.Protein3D.STYLE_CARTOON, - * use:"HTML5 JAVA", - * urlProxy:"/bioJs/dependencies/jsmol-14.0.2/jsmol/proxy/jsmol.jsp", - * viewControls: true - * }); - * instance.onPdbLoaded( - * function( objEvent ) { - * alert('PDB LOADED'); - * } - * ); - * //trigger to download the zip file containing the pdb structure from the server and unzip the file on the client - * instance.setPdb('2al6'); - * - * - */ -Biojs.Protein3DCanvas = Biojs.Protein3D.extend( -/** @lends Biojs.Protein3DCanvas# */ -{ - constructor: function (options) { - - this.opt.jmolFolder= this.opt.jsmolFolder; - Biojs.Protein3D.call(this, options); - - //JMol configuraion - if ( this.opt.use == undefined ) { - Jmol.Info["use"] = "HTML5 JAVA"; - - }else{ - Jmol.Info["use"] = this.opt.use; - } - - - if ( this.opt.proxyUrl != undefined ) { - Jmol.Info["serverURL"] = this.opt.proxyUrl; - } - - Jmol.Info["jarPath"] = this.opt.jsmolFolder+"/java", - Jmol.Info["jarFile"] = this.opt.jsmolFolder+"/java/JmolApplet0.jar", - Jmol.Info["j2sPath"] = this.opt.jsmolFolder+"/j2s"; - - Jmol.Info["addSelectionOptions"]= false; - Jmol.Info["color"]= "#ffffff"; - Jmol.Info["debug"]= false; - Jmol.Info["memoryLimit"]= 512; // Java only - Jmol.Info["readyFunction"]= null; - Jmol.Info["src"]= null; - Jmol.Info["disableInitialConsole"]=true; - Jmol.Info["disableJ2SLoadMonitor"]= true; - Jmol.Info["deferUncover"]=true; - Jmol.Info["deferApplet"]= false; - }, - - /** - * Default options (and its values) for the Protein3DCanvas component. - * @name Biojs.Protein3DCanvas-opt - * @type Object - */ - opt: - { - use: "HTML5 JAVA", - jsmolFolder: "../biojs/dependencies/jsmol-14.0.2/jsmol", - viewControls: true - }, - - /** - * Array containing the supported event names - * @name Biojs.Protein3DCanvas-eventTypes - */ - eventTypes : [], - - /** - * Sets the pdb file to be displayed. - * Also triggers the event whenever a new pdb file is loaded. - * It demands entirely to JSMol the download from the server and unzip of of the PDB file on the browser - * - * @param The pdb id to use to download the gz file from the server http://www.rcsb.org/pdb/files/"+pdb+".pdb.gz. - * - * @example - * var instance = new Biojs.Protein3DCanvas({ - * target: "YourOwnDivId", - * jsmolFolder: '/bioJs/dependencies/jsmol-14.0.2/jsmol', - * height: 440, - * width: 440, - * style: Biojs.Protein3D.STYLE_CARTOON, - * use:"HTML5 JAVA", - urlProxy:"/bioJs/dependencies/jsmol-14.0.2/jsmol/proxy/jsmol.jsp", - viewControls: true - * }); - * - * instance.onPdbLoaded( - * function( objEvent ) { - * alert('PDB LOADED'); - * } - * ); - * - * //trigger the downloading of the zip containing the pdb file from the server and unzip the file on the client - * instance.setPdb('2al6'); - * - * - */ - setPdb: function( pdb ){ - Biojs.console.log("LOADING pdb content"); - - var self = this; - - var surfaceCmd = this._getDisplaySurface( this.opt.surface ); - var styleCmd = this._getDisplayStyle( this.opt.style ); - var colorSchemeCmd = this._getDisplayColor( this.opt.colorScheme ); - - var scr = colorSchemeCmd + styleCmd + surfaceCmd + this._getSelectionScript( this._selection ); - - this.showLoadingImage(true); - - if ( this._jmolAppletInitialized ) { - this.reset(); - } - Jmol.setDocument(0); - htmlContent = jmolApplet([self._appletContainer.width(), self._appletContainer.height()], " load 'http://www.rcsb.org/pdb/files/"+pdb+".pdb.gz';"+ scr, self.getId()); - - this._appletContainer.html(Jmol.getAppletHtml(eval(htmlContent._id))); - - this._jmolAppletInitialized = true; - - Biojs.console.log("setPdb() ending"); - }, - - toString: function() { - return "Biojs.Protein3DCanvas"; - }, - - /* - * Function: Biojs.Protein3D._functionCbName - * Purpose: enable controls an triggers the loading pdb file event. - * It is invoked by JmolApplet. - * Returns: - - * Inputs: - * appletId -> {string} Applet identifier. - * url -> {string} URL of the loaded file (full path+filename). - * file -> {string} the filename of the loaded file (without the path). - * title -> {string} the internal title of the model in the loaded file. - * message -> {string} any error messages generated. - * code -> {int} A numeric code: - * 3 when the file loaded successfully, - * 0 when the model was zapped, - * -1 when the loading failed. - * formerFrame -> {string} a text string with the frame - * number prior to loading the current model, in file.model syntax - * (for example, "3.1" or "1.1 - 3.31" if a whole range of models was framed). - * frame -> {string} A text string with the last frame number after loading the current model, - * in file.model syntax. - */ - - _loadStructCallback: function ( appletId, url, file, title, message, code, formerFrame, frame ) { - -Biojs.console.log("executing _loadStructCallback for " + appletId); - - switch (code) { - case 3 : result = 'success'; break; - case 0 : result = 'zapped'; break; - case -1 : result = 'failure'; break; - default : result = 'undefined'; break; - } - - // Ignore the execution of the callback on replacing pdb file. - - if ( "zapped" != result ) { - //uncover the loading image - var instanceId = parseInt( appletId.replace("jmolApplet",'') ); - var instance = Biojs.getInstance(instanceId); - - if ( "success" == result ) { - instance.displayAntialias(instance.opt.antialias); - instance.rotate(instance.opt.rotate); - } - - instance.showLoadingImage(false); - if (instance.opt.viewControls){ - instance.showControls(); - instance._controlsContainer.css('display','block'); - jmolResizeApplet([ instance._container.width() - instance._controlsContainer.outerWidth(), instance._container.height()], instance.getId()); - instance._appletContainer.css('float','right'); - - }else{ - instance.hideControls(); - instance._controlsContainer.css('display','none'); - jmolResizeApplet([ instance._container.width(), instance._container.height()], instance.getId()); - instance._appletContainer.css('float','left'); - } - - instance.raiseEvent(Biojs.Protein3D.EVT_ON_PDB_LOADED, { - "file": title, - "result": result, - "message": message - }); - - instance._appletContainer.css('display','block'); - - - } - - - } - -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DUniprot.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DUniprot.js deleted file mode 100755 index 5a261c5035..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DUniprot.js +++ /dev/null @@ -1,582 +0,0 @@ -/** - * - * Protein viewer to show the pdb files aligned to an Uniprot Accession - * - * @class - * @extends Biojs.Protein3DWS - * - * @author John Gomez - * @version 1.0.0 - * @category 2 - * - * @param {Object} options An object with the options for the component. - * - * @option {string} [proteinId] - * Uniprot identifier of the protein. - * - * @option {string} [mapping=Biojs.Protein3DUniprot.ALIGNMENTS_UNIPROT_MAPPING] - * Mapping function to obtain the protein's alignments: - *
              - *
            • Biojs.Protein3DUniprot.ALIGNMENTS_UNIPROT_MAPPING
            • - *
            • Biojs.Protein3DUniprot.ALIGNMENTS_PDBe_MAPPING
            • - *
            - * - * @example - * - * var instance = new Biojs.Protein3DUniprot({ - * target: 'YourOwnDivId', - * proteinId: 'P07148' - * }); - * - */ -Biojs.Protein3DUniprot = Biojs.Protein3DWS.extend( -/** @lends Biojs.Protein3DUniprot# */ -{ - constructor: function(options) { - this.base(options); - var self = this; - - this.onPdbLoaded(function(e) { - Biojs.console.log(e.result + " loading the pdb file " + e.file); - Biojs.console.log("self._aligmentsJustArrived= " + self._alignmentsJustArrived); - if (self._alignmentsJustArrived) { - Biojs.console.log("Initialising the alignments selection list"); - self.reset(); - var alignments = self._filterAligmentsBySelection(self._selection); - var pdbOptions = self._createOptions(alignments); - if (jQuery('#' + self.opt.target).find('div#pdbStructures').length == 0) { - self._addControl('
            '); - } - jQuery('#' + self.opt.target).find('div#pdbStructures').html('

            Structures for ' + self.opt.proteinId + '


            ' + ''); - jQuery('#' + self.opt.target + ' #pdbFile_select').val(pdb); - jQuery('#' + self.opt.target + ' #pdbFile_select').change(function() { - self._onAlignmentSelectionChange(); - }); - jQuery('#' + self.opt.target).find('#pdbStructures').show(); - var alignmentId = pdb; - var pdbId = alignmentId.substring(0, pdb.indexOf('.')).toLowerCase(); - var alignment = self.getAlignmentsByPdb(alignmentId); - if (alignment.hasOwnProperty(alignmentId)) { - var start = alignment[alignmentId][1].start; - var end = alignment[alignmentId][1].end; - self.raiseEvent('onPdbSelected', {"pdbId": pdbId,"alignmentId": alignmentId,"start": start,"end": end}); - } - self._alignmentsJustArrived = false; - } - }); - - if (this.opt.proteinId != undefined) { - var proteinId = this.opt.proteinId; - this.opt.proteinId = ''; - this.setProtein(proteinId); - } - }, - - opt: { - proteinId: undefined, - mapping: 'http://www.ebi.ac.uk/pdbe-apps/widgets/unipdb?uniprot=', - proxyUrl: '../biojs/dependencies/proxy/proxy.php' - }, - - eventTypes : [ - /** - * @name Biojs.Protein3DUniprot#onPdbSelected - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} pdbId The name of the loaded file. - * @eventData {string} alignmentId Alignment identifier. - * @eventData {string} start Starting base index. - * @eventData {string} end Ending base index. - * - * @example - * instance.onPdbSelected( - * function( e ) { - * alert( "Alignment " + e.alignmentId + " selected. Start: " + e.start + " End: " + e.end ); - * } - * ); - * - * */ - "onPdbSelected" - ], - - _aligments: undefined, - - - /** - * Get all pdb files for a given uniprot id. - * Also triggers the event that a new pdb file was loaded. - * - * @option {string} proteinId Uniprot identifier of the protein. - * - * @example - * instance.setProtein("P99999"); - * - */ - setProtein: function(proteinId){ - if (proteinId != this.opt.proteinId) { - this.opt.proteinId = proteinId; - this._selection = undefined; - this._minStart = Number.MAX_VALUE; - this._maxEnd = 0; - this._alignments = undefined; - - if ( this.opt.mapping == Biojs.Protein3DUniprot.ALIGNMENTS_UNIPROT_MAPPING ) { - this._requestAligmentsFromUniprot(); - } else if ( this.opt.mapping == Biojs.Protein3DUniprot.ALIGNMENTS_PDBe_MAPPING ) { - this._requestAligmentsFromPdbe(); - } else { - throw "Error in mapping function. this.opt.mapping="+this.opt.mapping; - } - } - }, - - // makes an ajax request to get the pdb files for the given uniprot id - _requestAligmentsFromUniprot: function(){ - var self = this; - jQuery.ajax({ - url: self.opt.mapping + self.opt.proteinId, - data: {biojsmapping:'1', varname:'pdbmappings'}, - dataType: "script", - crossDomain: true, - success: function(){ - Biojs.console.log("SUCCESS: data received"); - self._alignments = pdbmappings; - //change proteinId to the one retrieved from pdbmappings (in case it is a protein id rather than an accession) - //Warning: Here we suppose that position [0] always give the info for the pdb and position [1] always give the info for the accession - for (obj in pdbmappings) { - if ( pdbmappings[obj][1].intObjectId != self.opt.proteinId ) { - self.opt.proteinId = pdbmappings[obj][1].intObjectId; - } - break; - } - self._aligmentsArrived(); - }, - async: false, - error: function(qXHR, textStatus, errorThrown){ - Biojs.console.log("ERROR: requesting "+this.data); - self.raiseEvent('onRequestError', {message: textStatus}); - } - }); - }, - - // makes an ajax request to get the pdb files for the given uniprot id - _requestAligmentsFromPdbe: function(){ - var self = this; - - jQuery.ajax({ - url: self.opt.proxyUrl, - dataType: "text", - data: { url: self.opt.mapping + self.opt.proteinId + '/'}, - success: function(data){ - Biojs.console.log("SUCCESS: data received"); - self._parseResponse(data); - }, - async: false, - error: function(qXHR, textStatus, errorThrown){ - Biojs.console.log("ERROR: requesting "+this.data); - self.raiseEvent('onRequestError', { message: textStatus}); - } - }); - }, - - // parses the xml file from the request and stores the information in an easy to access way - _parseResponse: function (text) { - this._alignments = {}; - var i = 0; - var self = this; - var data; - - Biojs.console.log("Decoding " + text); - - if ( !Biojs.Utils.isEmpty(text) ) { - - try { - data = jQuery.parseJSON(text); - - } catch (e) { - Biojs.console.log("Error decoding response: " + e.message ); - } - - for ( var i in data ) { - - try { - var segments = []; - - segments.push({ - "start": data[i].pdb_range[0], - "end": data[i].pdb_range[1], - "intObjectId": data[i].pdbid + '.' + data[i].chain } ); - - segments.push({ - "start": data[i].uniprot_range[0], - "end": data[i].uniprot_range[1], - "intObjectId": data[i].uniprot_acc } ); - - self._alignments[ segments[0].intObjectId ] = segments; - - if (self._minStart > segment[1].start) { - self._minStart = segment[1].start; - } - - if (self._maxEnd < segment[1].end) { - self._maxEnd = segment[1].end; - } - - } catch (e) { - Biojs.console.log("Error decoding alignment: " + e.message ); - } - } - } - - Biojs.console.log("Alignments decoded:"); - Biojs.console.log(self._alignments); - this._aligmentsArrived(); - }, - - // adds all available pdb files to a dropdown box - // or displays the fact that there are no pdb files for the given id - _aligmentsArrived: function(){ - - this._alignmentsJustArrived = true; - - var alignments = this._filterAligmentsBySelection(this._selection); - - if (!Biojs.Utils.isEmpty(alignments)) { - var pdb = undefined; - for (pdb in alignments) { - break; - } - - Biojs.console.log("Requesting pdb " + pdb); - this.requestPdb(pdb.substring(0, pdb.indexOf('.')).toLowerCase()); - - } else { - this._container.html("No structural information for " + this.opt.proteinId ); - this.raiseEvent('onRequestError', { message: "No structural information available for " + this.opt.proteinId }); - } - }, - - _onAlignmentSelectionChange: function(){ - var pdb = jQuery('#pdbFile_select').val(); - - if ( pdb != undefined ) { - - var alignmentId = pdb.substring(0, pdb.indexOf(' ')); - var pdbId = alignmentId.substring(0, pdb.indexOf('.')).toLowerCase(); - - var alignment = this.getAlignmentsByPdb(alignmentId); - - if ( alignment.hasOwnProperty( alignmentId ) ) { - var start = alignment[alignmentId][1].start; - var end = alignment[alignmentId][1].end; - - this.raiseEvent('onPdbSelected', { - "pdbId": pdbId, - "alignmentId": alignmentId, - "start": start, - "end": end - }); - } - - this.requestPdb(pdbId); - - } else { - Biojs.console.log("No structural information available for "+this.opt.proteinId); - } - }, - - /** - * Request and display a pdb file by means of its identifier. - * - * @param {string} pdbId Pdb file identifier. - * - * @example - * instance.requestPdb('3t6f'); - * - */ - requestPdb: function(pdbId) { - var self = this; - - self.showLoadingImage(); - self.opt.id = pdbId; - - jQuery.ajax({ - url: self.opt.proxyUrl, - data: 'url='+self.opt.pdbUrl+'/pdb'+pdbId+'.ent', - dataType: 'text', - success: function (pdbContent) { - Biojs.console.log("DATA ARRIVED"); - //reset the PDB selected area if a uniprot selection has been made already - if (self._uniprotSelection != undefined) { - self._selection = self._translateSelection(self._uniprotSelection); - } - self.setPdb(pdbContent); - }, - error: function(qXHR, textStatus, errorThrown){ - self.raiseEvent('onRequestError', {message: textStatus}); - } - }); - }, - - - /** - * Get the available alignments for the current protein filtered by selection (PDB files containing a part of the requested region). - * - * @example - * // Selection of the region in the interval [100,150]. - * instance.setSelection({start: 120, end: 150}); - * - * @example - * // Get the alignments matching with bases 4, 8 and 100. - * alert ( instance.filterAlignments([4,8,100]) ); - * - * @param {Object|Array} selection Can be either a plain object or an array. - * If object, it must have the fields start and end; Where "start" is greater than or equal to "end". - * If array, it must contain numbers representing the positions to be selected. - */ - getAlignmentsBySelection: function ( selection ) { - - var alignments = this._alignments; - - if ( selection != undefined ) { - this._filterAligmentsBySelection(selection); - } - - return alignments; - }, - - /** - * Get the available alignments for the current protein filtered by selection (PDB files containing a part of the requested region). - * - * @example - * // Get the alignments matching with bases 4, 8 and 100. - * alert ( instance.getAlignmentsByPdb("2F73") ); - * - * @param {string} pdb identifier. - * @returns {Object} . - * - */ - getAlignmentsByPdb: function ( pdbId ) { - - var alignments = {}; - - for (al in this._alignments) { - if ( this._alignments[al][0].intObjectId.indexOf( pdbId ) != -1 ) { - alignments[this._alignments[al][0].intObjectId] = this._alignments[al]; - } - } - - Biojs.console.log("Alignments for pdb " + pdbId ); - Biojs.console.log(alignments); - - return alignments; - }, - - /** - * Filters the alignments available for the current protein: Only PDB files containing a part of the requested region - * are selectable. The specified region is highlighted in the displayed PDB file. - * - * @example - * // Selection of the region in the interval [100,150]. - * instance.filterAlignments({start: 120, end: 150}); - * - * @param {Object|Array} selection Can be either a plain object or an array. - * If object, it must have the fields start and end; Where "start" is greater than or equal to "end". - * If array, it must contain numbers representing the positions to be selected. - */ - filterAlignments: function ( selection ) { - - var alignments = this._filterAligmentsBySelection(selection); - var selectedAlignment = jQuery('#pdbFile_select').val(); - - // Update the drop-down box showing the filtered alignments - jQuery('#pdbFile_select').html(this._createOptions(alignments)); - - // Select an alignment - if ( alignments.hasOwnProperty( selectedAlignment.slice(0,selectedAlignment.indexOf(' '))) ) { - // Select current alignment if it belongs to filtered alignments - jQuery('#pdbFile_select').val(selectedAlignment); - - } else { - // Select any alignment - for ( a in alignments ){ - jQuery('#pdbFile_select').val(a); - break; - } - this._onAlignmentSelectionChange(); - } - - // invoke setSelection on the parent - this.base(selection); - }, - - _createOptions: function(alignments) { - var pdbOptions = ""; - for (pdb in alignments) { - text = pdb + " (" + alignments[pdb][1].start + ".." + alignments[pdb][1].end + ")"; - pdbOptions += ''; - } - Biojs.console.log("_createOptions: " + pdbOptions); - return pdbOptions; - }, - - _filterAligmentsBySelection: function(selection) { - var alignments = undefined; - if (selection instanceof Array) { - alignments = {}; - for (al in this._alignments) { - var uniprot = this._alignments[al][1]; - for (i in selection) { - if (selection[i] >= uniprot.start && selection[i] <= uniprot.end) { - alignments[this._alignments[al][0].intObjectId] = this._alignments[al]; - break; - } - } - } - } else if (selection instanceof Object) { - alignments = {}; - var i = 0; - for (al in this._alignments) { - var uniprot = this._alignments[al][1]; - if ((selection.start >= uniprot.start && selection.start <= uniprot.end) || (selection.end >= uniprot.start && selection.end <= uniprot.end) || (selection.start < uniprot.start && selection.end > uniprot.end)) { - alignments[this._alignments[al][0].intObjectId] = this._alignments[al]; - i++; - } - } - } else { - alignments = this._alignments; - } - Biojs.console.log("Filtered alignments:"); - Biojs.console.log(alignments); - return alignments; - }, - - /** - * Selection of a region using the uniprot positions. - * - * @example - * // Selection of the region in the interval [100,150]. - * instance.setSelection({start: 100, end: 150}); - * - * @example - * // Selection of the positions 4, 8 and 100. - * instance.setSelection([4,8,100]); - * - * @param {Object|Array} selection Can be either a plain object or an array. - * If object, it must have the fields start and end; Where "start" is greater than or equal to "end". - * If array, it must contain numbers representing the positions to be selected. - */ - setSelection: function ( s ) { - this._uniprotSelection = Biojs.Utils.clone(s); - var selection = this._translateSelection(s); - this.base(selection); - }, - - _translateSelection: function (s) { - //Selection in Uniprot regions needs to be translated into PDB regions - var selection = Biojs.Utils.clone(s); - var alignmentId = this.getCurrentAlignmentId(); - var proteinId = this.getCurrentProteinId(); - var segment = this.getAlignmentsByPdb(alignmentId)[alignmentId]; - var offset = 0; - for ( i in segment ) { - if ( segment[i].intObjectId == alignmentId ) { - pdbSegment = segment[i]; - } else if ( segment[i].intObjectId == proteinId ) { - uniprotSegment = segment[i]; - } - } - offset = uniprotSegment.start - pdbSegment.start; - if ( selection instanceof Array ) { - var toDelete = new Array(selection.length); - for ( i in selection ) { - if (selection[i] instanceof Object) {//a range - if ( (selection[i].start > uniprotSegment.end) || (selection[i].end < uniprotSegment.start) ){ - //we first check whether it is completely out of the range - selection[i].start = 0; - selection[i].end = 0; - toDelete[i] = true; - } else if ( (selection[i].start >= uniprotSegment.start) && (selection[i].end <= uniprotSegment.end) ){ - selection.start -= offset; - selection.end -= offset; - toDelete[i] = false; - } else if ( (selection[i].start < uniprotSegment.start) && (selection[i].end <= uniprotSegment.end) ){ - selection[i].start = pdbSegment.start - 0; - selection[i].end -= offset; - toDelete[i] = false; - } else if ( (selection[i].start >= uniprotSegment.start) && (selection[i].end > uniprotSegment.end) ){ - selection[i].start -= offset; - selection[i].end = pdbSegment.end - 0; - toDelete[i] = false; - } else if ( (selection[i].start < uniprotSegment.start) && (selection[i].end > uniprotSegment.end) ){ - selection[i].start = pdbSegment.start - 0 - selection[i].end = pdbSegment.end - 0; - toDelete[i] = false; - } - } else { //a position - if ( (uniprotSegment.start <= selection[i]) && (selection[i] <= uniprotSegment.end) ) { - selection[i] -= offset; - toDelete[i] = false; - } else { - toDelete[i] = true; - } - } - } - var deleted = 0; - for (j in toDelete) { - if (toDelete[j] == true) { - selection.splice(j-deleted,j-deleted); - deleted += 1; - } - } - } else if ( selection instanceof Object && selection.start <= selection.end ){ - if ( (selection.start > uniprotSegment.end) || (selection.end < uniprotSegment.start) ){ - //we first check whether it is completely out of the range - selection.start = 0; - selection.end = 0; - this.removeSelection(); - } else if ( (selection.start >= uniprotSegment.start) && (selection.end <= uniprotSegment.end) ){ - selection.start -= offset; - selection.end -= offset; - } else if ( (selection.start < uniprotSegment.start) && (selection.end <= uniprotSegment.end) ){ - selection.start = pdbSegment.start - 0; - selection.end -= offset; - } else if ( (selection.start >= uniprotSegment.start) && (selection.end > uniprotSegment.end) ){ - selection.start -= offset; - selection.end = pdbSegment.end - 0; - } else if ( (selection.start < uniprotSegment.start) && (selection.end > uniprotSegment.end) ){ - selection.start = pdbSegment.start - 0 - selection.end = pdbSegment.end - 0; - } - } - return (selection); - }, - - getCurrentAlignmentId: function () { - var selectedValue = jQuery('#pdbFile_select').val(); - var alignmentId = selectedValue.substring(0, selectedValue.indexOf(' ')); - //var pdbId = alignmentId.substring(0, pdb.indexOf('.')).toLowerCase(); - return alignmentId; - }, - - getCurrentProteinId: function () { - return this.opt.proteinId; - }, - - /** - * Removes selection in the current displayed structure. - * - * @example - * instance.removeSelection(); - */ - removeSelection: function() { - this.base(); - } -}, { - - // Mapping services - ALIGNMENTS_UNIPROT_MAPPING: 'http://www.ebi.ac.uk/pdbe-apps/widgets/unipdb?uniprot=', - ALIGNMENTS_PDBe_MAPPING: 'http://wwwdev.ebi.ac.uk/pdbe-apps/jsonizer/mappings/best/all/' - -}); diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DWS.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DWS.js deleted file mode 100755 index 48746b433c..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Protein3DWS.js +++ /dev/null @@ -1,106 +0,0 @@ -/** - * - * Extension of the pdb file viewer getting data from a web service - * - * @class - * @extends Biojs.Protein3D - * - * @author John Gomez - * @version 1.0.0 - * @category 2 - * - * @requires Server side proxy - * - * @param {Object} options An object with the options for the component. - * - * @option {string} [pdbUrl="http://www.ebi.ac.uk/pdbe/entry-files"] - * Url of the web service in order to require the pdb file. - * - * @option {string} [id] - * Identifier of the pdb to be displayed (i.e. '3nuc' to require 3nuc.pdb file). You can load another pbd by using requestPdb method. - * - * @option {string} [proxyUrl="../biojs/dependencies/proxy/proxy.php"] - * Server side proxy server. - * - * @example - * - * var instance = new Biojs.Protein3DWS({ - * target: 'YourOwnDivId', - * id: '3nuc' - * }); - * - * - */ -Biojs.Protein3DWS = Biojs.Protein3D.extend( -/** @lends Biojs.Protein3DWS# */ -{ - constructor: function(options){ - this.base(options); - //constructor of Biojs.Protein3DWS - if (this.opt.id !== undefined) { - this.requestPdb(this.opt.id); - } - }, - - opt: { - id: undefined, - pdbUrl: 'http://www.ebi.ac.uk/pdbe/entry-files', - proxyUrl: '../biojs/dependencies/proxy/proxy.php' - }, - - eventTypes : [ - /** - * @name Biojs.Protein3DWS#onRequestError - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} file The name of the loaded file. - * @eventData {string} result A string with either value 'success' or 'failure'. - * @eventData {string} message Error message in case of result be 'failure'. - * - * @example - * instance.onRequestError( - * function( e ) { - * alert( e.message ); - * } - * ); - * - * */ - "onRequestError" - ], - - /** - * Request and display a pdb file by means of its identifier. - * - * @param {string} pdbId Pdb file identifier. - * - * @example - * instance.requestPdb('3t6f'); - * - */ - requestPdb: function(pdbId) { - var self = this; - - self.showLoadingImage(); - self.opt.id = pdbId; - - jQuery.ajax({ - url: self.opt.proxyUrl, - data: 'url='+self.opt.pdbUrl+'/pdb'+pdbId+'.ent', - dataType: 'text', - success: function (pdbContent) { - Biojs.console.log("DATA ARRIVED"); - self.setPdb(pdbContent); - }, - error: function(qXHR, textStatus, errorThrown){ - self.raiseEvent('onRequestError', {message: textStatus}); - } - }); - }, - - getPdbId: function(pdb) { - return opt.id; - } - - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.ProteinPortafolio.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.ProteinPortafolio.js deleted file mode 100755 index 1d7e978ff9..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.ProteinPortafolio.js +++ /dev/null @@ -1,522 +0,0 @@ -/** - * ProteinPortafolio component shows the description of a protein as well as its PDB alignments if there is any. - * Component shows the PDBLogos of the selected alignment and ables to play with the sequence and - * the 3D draw of the alignment. - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires Raphael 2.1.0 - * @dependency - * - * @requires PDBLogos - * @dependency - * - * @requires Sequence - * @dependency - * - * @requires Protein3DWS - * @dependency - * @dependency - * - * @requires jMol 12.0.48 - * @dependency - * - * @requires Protein3D CSS - * @dependency - * - * @requires ProteinPortafolio CSS - * @dependency - * - * @param {Object} options An object with the options for ProteinPortafolio component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} [fontFamily='"Andale mono", courier, monospace'] - * Font list to be applied to the component content. - * - * @option {string} [fontColor="white"] - * HTML color code for the font. - * - * @option {string} [backgroundColor="#7BBFE9"] - * Background color for the entire div content. - * - * @option {Object} [selectionFontColor="white"] - * This color will be used to change the font color of selected text. - * - * @option {Object} [ selectionBackgroundColor="yellow"] - * This color will be used to change the background of selected text. - * - * @option {string} [pdb3DIcon='../biojs/css/images/3d.png'] - * The only PDB icon is able to defines the 3D structure. - * Set source URL for 3D icon - * - * @example - * var instance = new Biojs.ProteinPortafolio({ - * target : "YourOwnDivId", - * accession : 'P99999' - * }); - * - */ -Biojs.ProteinPortafolio = Biojs.extend ( -/** @lends Biojs.ProteinPortafolio# */ -{ - constructor: function (options) { - // In JavaScript "this" always refers to the owner of the function we're executing (http://www.quirksmode.org/js/this.html) - // Let's preserve the reference to 'this' through the variable self. In this way, we can invoke/execute - // our component instead of the object where 'this' is being invoked/executed. - var self = this; - - Biojs.console.enable(); - - // For practical use, create an object with the main DIV container - // to be used in all of the code of our component - this._container = jQuery("#"+self.opt.target); - - this._initialize(); - - if ( !Biojs.Utils.isEmpty( options.accession ) ) { - this.setProtein(options.accession); - } - - }, - - /** - * Default values for the options - * @name Biojs.ProteinPortafolio-opt - */ - opt: { - target: "YourOwnDivId", - accession: "", - mappingUrl: 'http://www.ebi.ac.uk/pdbe-apps/widgets/unipdb?uniprot=', - featuresUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot-summary/features', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - jmolFolder: '../biojs/dependencies/jmol-12.0.48', - pdb3DIcon: '../biojs/css/images/3d.png', - pdbIconSize: 40 - }, - - /** - * Array containing the supported event names - * @name Biojs.ProteinPortafolio-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.ProteinPortafolio#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} selected Selected character. - * @example - * instance.onClick( - * function( objEvent ) { - * alert("The character " + objEvent.selected + " was clicked."); - * } - * ); - * - * */ - "onClick", - - /** - * @name Biojs.ProteinPortafolio#onPdbSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} alignmentId Identifier . - * @eventData {string} pdbId Selected pdb entry. - * @eventData {int} start Start position of the alignment. - * @eventData {int} end End position of the alignment. - * @example - * instance.onPdbSelected( - * function( e ) { - * alert("Selected " + e.alignmentId + " alignment."); - * } - * ); - * - * */ - "onPdbSelected" - ], - - /** - * Change the font size. Do nothing it no value is provided. - * - * @param {string} [size] The new font size in pixels. - * - * @example - * instance.setSize("72px"); - */ - setSize: function(size) { - - }, - - _initialize: function() { - - this._alpha = jQuery('
            ').appendTo( this._container ); - this._beta = jQuery('
            ').appendTo( this._container ); - - this._header = jQuery('
            ').appendTo( this._alpha ); - this._toolbar = jQuery('
            ').appendTo( this._alpha ); - this._content = jQuery('
            ').appendTo( this._alpha ); - - this._content.attr('id', 'ProteinPortafolio_content_' + this.getId() ); - - this._container.addClass('ProteinPortafolio'); - }, - - _clearAll: function () { - this._header.children().remove(); - this._toolbar.children().remove(); - this._content.children().remove(); - }, - - /** - * Sets the protein accession which changes everything to reflect the new protein information - * - * @param {string} accession The new protein identifier - * - * @example - * instance.setProtein("P07148"); - * - * @example - * instance.setProtein("P12345"); - */ - setProtein: function( accession ) { - - this.opt.accession = accession; - - this._requestAligments(accession, function(alignments){ - - this._alignments = alignments; - - this._container.removeClass('loading'); - - if (!Biojs.Utils.isEmpty(alignments)) { - // Alignments found - this._setHeader( this.opt.accession, this._createPDBSelect(alignments) ); - - } else { - // none alignment found - this._setHeader( this.opt.accession ); - } - }); - - this._showFeatures(accession); - }, - - _requestAligments: function( accession, action ){ - var self = this; - - this._clearAll(); - this._container.addClass('loading'); - - var xhr = jQuery.ajax({ - url: self.opt.mappingUrl + accession, - data: {biojsmapping:'1', varname:'pdbmappings'}, - dataType: "script", - crossDomain: true, - timeout: 5000, - success: function(){ - Biojs.console.log("SUCCESS: data received"); - self._alignments = pdbmappings; - action.call(self,pdbmappings); - }, - async: true, - error: function(qXHR, textStatus, errorThrown){ - Biojs.console.log("ERROR: " + textStatus ); - self.raiseEvent('onRequestError', {message: textStatus}); - action.call(self,{}); - } - }); - }, - - _createPDBSelect: function(alignments) { - var pdbOptions = ""; - for (pdb in alignments) { - text = pdb + " (" + alignments[pdb][1].start + ".." + alignments[pdb][1].end + ")"; - pdbOptions += ''; - } - Biojs.console.log("_createOptions: " + pdbOptions); - return pdbOptions; - }, - - _setHeader: function( accession, mappingsSelector ) { - var self = this; - - if ( mappingsSelector !== undefined ) { - this._header.html("Accession: "+ accession + ", PDB Alignments: " ); - this._onAlignmentSelectionChange(); - this._header.children('select').change( function(){ self._onAlignmentSelectionChange() }); - } else { - this._header.html("Accession: "+ accession + ", No PDB alignments found." ); - } - - this._adjustContentSize(); - - }, - - _onAlignmentSelectionChange: function(){ - - var alignment = this.getCurrentAlignment(); - - if ( !Biojs.Utils.isEmpty(alignment) ) { - - this.raiseEvent('onPdbSelected', { - "pdbId": alignment.pdbId, - "alignmentId": alignment.alignmentId, - "start": alignment.start, - "end": alignment.end - }); - - this._showPDBPrints(alignment.pdbId); - this._showImage(alignment.pdbId); - this._showFeatures(this.opt.accession); - - } else { - Biojs.console.log("No structural information available for " + this.opt.accession ); - } - }, - - _showPDBPrints: function(pdbId) { - - var self = this; - this._toolbar.children().remove(); - this._toolbar.attr('id', 'PDBLogos_toolbar_' + this.getId() ); - - var myprints = new Biojs.PDBLogos({ - target: this._toolbar.attr('id'), - identifier: pdbId, - size: self.opt.pdbIconSize, - pdb3DIcon: self.opt.pdb3DIcon - }); - - myprints.onClick( function(e) { - if ( e.category == "PDBStructure" ) { - self._showProtein3D(); - } else { - window.open( e.printsURL ); - } - }); - - this._adjustContentSize(); - }, - - /** - * Get the available alignments for the current protein filtered by selection (PDB files containing a part of the requested region). - * - * @example - * // Get the alignments matching with bases 4, 8 and 100. - * alert ( instance.getAlignmentsByPdb("2F73") ); - * - * @param {string} pdb identifier. - * @returns {Object} . - * - */ - getAlignmentsByPdb: function ( pdbId ) { - - var alignments = {}; - - for (al in this._alignments) { - if ( this._alignments[al][0].intObjectId.indexOf( pdbId ) != -1 ) { - alignments[this._alignments[al][0].intObjectId] = this._alignments[al]; - } - } - - Biojs.console.log("Alignments for pdb " + pdbId ); - Biojs.console.log(alignments); - - return alignments; - }, - - getCurrentAlignment: function(){ - - var result = {}; - var pdbSelectedValue = this._header.find('select').val(); - - if ( pdbSelectedValue != undefined ) { - - result.accession = this.opt.accession; - result.alignmentId = pdbSelectedValue.substring(0, pdbSelectedValue.indexOf(' ')); - result.pdbId = pdbSelectedValue.substring(0, pdbSelectedValue.indexOf('.')).toLowerCase(); - - - var alignment = this.getAlignmentsByPdb(result.alignmentId); - - result.start = alignment[result.alignmentId][1].start; - result.end = alignment[result.alignmentId][1].end; - result.offset = 0; - - if ( alignment.hasOwnProperty( result.alignmentId ) ) { - result.offset = result.start - alignment[result.alignmentId][0].start; - } - - result.alignment = alignment; - } - - Biojs.console.log("Current alignment"); - Biojs.console.log(result); - - return result; - }, - - _showProtein3D: function( ){ - - var self = this; - var alignment = this.getCurrentAlignment(); - var height = this._container.height() - this._header.height() - this._toolbar.height(); - - self._content.children().remove(); - self._beta.children().remove(); - - self._beta.attr('id','biojs_protein3D_' + self._content.attr('id') ); - - // Calculate character width - var test = jQuery("X").appendTo(self._content); - var columns = Math.round( self._content.width() * (1/test.width()) ); - test.remove(); - - var sequence = new Biojs.Sequence({ - target : self._content.attr('id'), - format : 'FASTA', - id : alignment.accession, - formatSelectorVisible: false, - columns: { size: columns, spacedEach: 10 } - }); - - var proteinStructure = new Biojs.Protein3DWS({ - id: alignment.pdbId, - target: self._beta.attr('id'), - width: Math.round( self._beta.width() ), - height: self._container.height(), - proxyUrl: self.opt.proxyUrl, - jmolFolder: self.opt.jmolFolder - }); - - sequence.onSelectionChange( function (e) { - // [e.start, e.end] from the event data corresponds to the protein sequence positions - // which need to be aligned with PDB structure - var selection = {start: e.start, end: e.end}; - - selection.start -= alignment.offset; - selection.end -= alignment.offset; - - proteinStructure.setSelection( selection ); - }); - - }, - - _showSequence: function( accession ){ - - var self = this; - - this._content.children().remove(); - - var sequence = new Biojs.Sequence({ - target : this._content.attr('id'), - format : 'FASTA', - id : accession, - formatSelectorVisible: false, - columns: { size: Math.round( self._content.width()/20 ), spacedEach: 10 } - }); - }, - - _showImage: function( pdbId ){ - - this._beta.children().remove(); - - var img = jQuery('') - .appendTo(this._beta) - .addClass('crop'); - - }, - - _showFeatures: function( accession ) { - - var self = this; - - this._content.children().remove(); - this._adjustContentSize(); - - this._requestFeatures( accession, function(xml){ - - Biojs.console.log("Features received " + xml ); - - var xmlDoc = ""; - - try { - xmlDoc = jQuery.parseXML( xml ); - } catch (e) { - Biojs.console.log("XML parser error" + e); - } - - var features = jQuery('
              ').appendTo(self._content); - var label="", value=""; - - jQuery(xmlDoc).find('FEATURE') - .each( function(){ - //features.push( self._decodeFeature(this) ); - label = '' + jQuery(this).attr('label') + ''; - value = '' + jQuery(this).children('NOTE:first').text() + ''; - - features.append('
            • ' + label + value + '
            • '); - }); - }); - }, - - /* - * Function: Biojs.ProteinPortafolio._requestFeatures - * Purpose: Request data to the server - * Returns: - - * Inputs: opt -> {Object} options object. - */ - _requestFeatures: function( accession, action ){ - - var self = this; - - Biojs.console.log("Requesting features for '" + accession + "'" ); - - var httpRequest = { - url: self.opt.proxyUrl, - data: [{ name: "url", value: self.opt.featuresUrl + "?segment=" + accession }], - method: "GET", - dataType: "text", - success: action, - error: function(e) { - Biojs.console.log("Error requesting features for " + accession ); - } - }; - - jQuery.ajax(httpRequest); - - }, - - _adjustContentSize: function() { - - if ( this._beta.children().length > 0 ) { - this._alpha.addClass('alpha'); - this._beta.addClass('beta'); - this._content.height(this._container.height() - this._header.height() - this._toolbar.height()); - - } else { - this._alpha.removeClass('alpha'); - this._beta.removeClass('beta'); - this._content.height('auto'); - } - } - -}); - - - - - - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.PsicquicGraph.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.PsicquicGraph.js deleted file mode 100755 index d9be353de4..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.PsicquicGraph.js +++ /dev/null @@ -1,217 +0,0 @@ -/** - * - * Graph display of molecular interactions using PSICQUIC. - * - * @class - * @extends Biojs - * - * @author JosĂ© Villaveces - * @version 1.0.0_beta - * @category 2 - * - * @requires jQuery 1.7.2 - * @dependency - * - * @requires Cytoscape.js (latest version strongly suggested) - * @dependency - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * id of the div where the component should be displayed - * - * @option {string} psicquicUrl - * url of the PSICQUIC server to query. - * - * @option {string} proxyUrl - * url of the proxy to use. - * - * @option {string} query - * MIQL query. - * - * @option {Object} cyoptions - * cytoscapejs inititlization options more info here - * - * @example - * var instance = new Biojs.PsicquicGraph({ - * target: "YourOwnDivId", - * psicquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query', - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * query: 'species:human?firstResult=0&maxResults=100', - * cyoptions: { - * style: cytoscape.stylesheet().selector('node').css({ - * 'content': 'data(id)', - * 'font-family': 'helvetica', - * 'font-size': 14, - * 'text-outline-width': 3, - * 'text-outline-color': '#888', - * 'text-valign': 'center', - * 'color': '#fff', - * 'width': 'mapData(weight, 30, 80, 20, 50)', - * 'height': 'mapData(height, 0, 200, 10, 45)', - * 'border-color': '#fff' - * }).selector(':selected').css({ - * 'background-color': '#000', - * 'line-color': '#000', - * 'target-arrow-color': '#000', - * 'text-outline-color': '#000' - * }).selector('edge').css({ - * 'width': 2 - * }), - * layout: { - * name: 'circle', - * fit: true, // whether to fit the viewport to the graph - * ready: undefined, // callback on layoutready - * stop: undefined, // callback on layoutstop - * rStepSize: 10, // the step size for increasing the radius if the nodes don't fit on screen - * padding: 30, // the padding on fit - * startAngle: 3/2 * Math.PI, // the position of the first node - * counterclockwise: false // whether the layout should go counterclockwise (true) or clockwise (false) - * }, - * ready:function(){ - * var cy = this; - * cy.nodes().click(function(e){ - * console.log(e.cyTarget.id()); - * }); - * } - * } - * }); - */ - -Biojs.PsicquicGraph = Biojs.extend( -/** @lends Biojs.PsicquicGraph# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - this._query(this.opt); - }, - /** - * Default values for the options - * @name Biojs.PsicquicGraph-opt - */ - opt: { - target: "YourOwnDivId", - psicquicUrl: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - query: 'species:human?firstResult=0&maxResults=100', - cyoptions: { - //see cytoscapejs inititlization options - style: cytoscape.stylesheet().selector('node').css({ - 'content': 'data(id)', - 'font-family': 'helvetica', - 'font-size': 14, - 'text-outline-width': 3, - 'text-outline-color': '#888', - 'text-valign': 'center', - 'color': '#fff', - 'width': 'mapData(weight, 30, 80, 20, 50)', - 'height': 'mapData(height, 0, 200, 10, 45)', - 'border-color': '#fff' - }).selector(':selected').css({ - 'background-color': '#000', - 'line-color': '#000', - 'target-arrow-color': '#000', - 'text-outline-color': '#000' - }).selector('edge').css({ - 'width': 2 - }), - layout: { - name: 'circle', - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - rStepSize: 10, // the step size for increasing the radius if the nodes don't fit on screen - padding: 30, // the padding on fit - startAngle: 3/2 * Math.PI, // the position of the first node - counterclockwise: false // whether the layout should go counterclockwise (true) or clockwise (false) - }, - ready:function(){ - var cy = this; - cy.nodes().click(function(e){ - console.log(e.cyTarget.id()); - }); - } - } - }, - /** - * Array containing the supported event names - * @name Biojs.PsicquicGraph-eventTypes - */ - eventTypes: [], - /* - * Function: Biojs.PsicquicGraph._query - * Purpose: Queries PSIQUIC using the provided query in MIQL. - * Inputs: dataSet -> {Object} Settings of the data set. - */ - _query: function(dataSet){ - - dataSet.url = dataSet.psicquicUrl + '/' + dataSet.query; - - var instance = this; - jQuery.ajax({ - url: dataSet.proxyUrl, - dataType: "text", - data: [{ name: "url", value: dataSet.url }], - success: function ( data ) { - instance._decodeToJSON(data, instance); - } - }); - }, - /* - * Function: Biojs.PsicquicGraph._decodeToJSON - * Purpose: Transforms MiTab data into JSON and renders the graph. - * Inputs: miTabData -> {Object} interactions in MiTab format. - * instance -> {Object} a reference to this widget instance. - */ - _decodeToJSON: function(miTabData, instance){ - var nodes = [], edges = [], map = {}; - - var lines = miTabData.split('\n'); - for(var i=0; i 13){ - - var idSource = line[0].split('|')[0].split(':')[1]; - - if(map[idSource] === undefined){ - map[idSource] = { - data:{ - id: idSource, - organism: line[9].split('|') - } - } - nodes.push(map[idSource]); - } - - var idTarget = line[1].split('|')[0].split(':')[1]; - - if(map[idTarget] === undefined){ - map[idTarget] = { - data:{ - id: idTarget, - organism: line[10].split('|') - } - } - nodes.push(map[idTarget]); - } - - edges.push({ - data:{ - source: idSource, - target: idTarget, - type: line[11].split('|'), - score: line[14].split('|') - } - }); - } - } - - instance.opt.cyoptions.elements = { - nodes: nodes, - edges: edges - }; - - jQuery('
              ').appendTo('#'+instance.opt.target).cytoscape(instance.opt.cyoptions); - } -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.RaphaelCanvas.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.RaphaelCanvas.js deleted file mode 100755 index f63adbf3b4..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.RaphaelCanvas.js +++ /dev/null @@ -1,175 +0,0 @@ -/** - * This is the description of the RaphaelCanvas component. This component provides pan/zoom functionality over Raphael's paper object, - * and saves repitition of development effort involved in pan/zoom in other components. - * - * @class - * @extends Biojs - * - * @author Swanand Gore - * @version 1.0.0 - * @category 0 - * - * @requires Raphael 2.1.0 - * @dependency - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @param {Object} options An object with the options for RaphaelCanvas component. - * - * @option {String} divid - * the div in which the canvas should be created. - * - * @option {Number} dimension - * the side of the square canvas - * - * @example - * var instance = new Biojs.RaphaelCanvas({ - * divid:"YourOwnDivId", dimension:500 - * }); - * instance.testSetup(); - * - */ -Biojs.RaphaelCanvas = Biojs.extend ( -/** @lends Biojs.RaphaelCanvas# */ -{ - /** - * Default values for the options - * @name Biojs.RaphaelCanvas-opt - */ - opt: { divid:"YourOwnDivId", dimension:500 }, - - constructor: function (options) { - var self = this; - self.dim = options.dimension; - self.divid = options.divid; - self.jq = jQuery('#'+self.divid); - self.mousedownEvent = null; - self.init(); - }, - init: function() { - var self = this; - self.rapha = Raphael(self.divid, self.dim, self.dim); - self.fullbox = self.rapha.rect(0,0,self.dim,self.dim).attr({fill:'green',stroke:'black', opacity:0.01}); - self.jq.mousedown( function(e) { self.recordMousedown(e); } ); - self.makeZoomPannable(); - self.setVbox(0,0,self.dim); - }, - testSetup: function() { - var self = this; - for(var x=0; x < self.dim; x+=self.dim/10) { - for(var y=0; y < self.dim; y+=self.dim/10) { - self.rapha.text(x, y, x+","+y).attr({'text-anchor':'start'}); - self.rapha.circle(x, y, self.dim/50); - } - } - }, - makeZoomPannable: function() { - var self = this; - self.jq.mouseup( function(e) { self.zoompan(e); self.zoompanstarted = null; } ); - self.jq.mousemove( function(e) { self.zoompan(e) ;} ); - }, - setVbox: function(x,y,dim) { - var self = this; - self.rapha.setViewBox(x,y,dim,dim,true); - self.curVbox = [x,y,dim]; - }, - zoompan: function(e) { - var self = this; - e.preventDefault(); - if(!self.zoompanMouseactivity(e)) return; - if(self.zoompanstarted != 1) return; - console.log("zoompan event", e.button, e.buttons, e.which); - var pxy = self.event2paperxy(e); - var pxy1 = self.event2paperxy(self.mousedownEvent); - var dx = e.clientX - self.mousedownEvent.clientX; - var pdx = pxy[0] - pxy1[0]; - var dy = e.clientY - self.mousedownEvent.clientY; - var pdy = pxy[1] - pxy1[1]; - console.log("zoompan", pdx.toFixed(1), dx.toFixed(1), self.zoom); - if(Math.abs(dx) < 5 && Math.abs(dy) < 5) return; - if(e.shiftKey) { // zoom i.e. enlarge viewbox when zoomed in, and make it small when when zoomed out - dd = self.curVbox[2] - pdx; - decr = (dd-self.curVbox[2])/2; - console.log("viewbox", pxy1, dd); - self.setVbox(self.curVbox[0]-decr, self.curVbox[1]-decr, dd); - } - else if(e.ctrlKey) { // pan i.e. change viewbox in such a way that pxy1 goes onto pxy - console.log("viewbox", pxy1, self.curVbox[2]); - dx = pxy1[0]-pxy[0]; - dy = pxy1[1]-pxy[1]; - self.setVbox(self.curVbox[0]+dx, self.curVbox[1]+dy, self.curVbox[2]); - } - self.mousedownEvent = e; - }, - zoompanMouseactivity: function(e) { - var self = this; - if(!e.shiftKey && !e.ctrlKey) return false; - if(e.which != 1) return false; - return true; - }, - recordMousedown: function(e) { - var self = this; - if(!self.zoompanMouseactivity(e)) return; - //console.log("mousedown", e); - e.preventDefault(); - self.mousedownEvent = e; - self.zoompanstarted = 1; - }, - event2paperxy: function(e) { - var self = this; - // gratefully copied from a http://stackoverflow.com/questions/15257059/how-do-i-get-an-event-in-raphaels-paper-coordinates - var rect = self.fullbox; - var bnds = self.jq[0].getBoundingClientRect(); - // adjust mouse x/y - var mx = e.clientX - bnds.left; - var my = e.clientY - bnds.top; - // divide x/y by the bounding w/h to get location %s and apply factor by actual paper w/h - var fx = mx/bnds.width * rect.attrs.width; - var fy = my/bnds.height * rect.attrs.height; - console.log("event2paper", mx.toFixed(1), my.toFixed(1), fx.toFixed(1), fy.toFixed(1)); - return [fx,fy]; - // TODO make this work even when clicked outside raphael in the divid - }, - - /** - * Array containing the supported event names - * @name Biojs.RaphaelCanvas-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.RaphaelCanvas#onClick - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} selected Selected character. - * @example - * instance.onClick( - * function( objEvent ) { - * alert("The character " + objEvent.selected + " was clicked."); - * } - * ); - * - * */ - "onClick", - - /** - * @name Biojs.RaphaelCanvas#onHelloSelected - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} textSelected Selected text, will be 'Hello' obviously. - * @example - * instance.onHelloSelected( - * function( objEvent ) { - * alert("The word " + objEvent.textSelected + " was selected."); - * } - * ); - * - * */ - "onHelloSelected" - ] -}); - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Rheaction.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Rheaction.js deleted file mode 100755 index b613936b54..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Rheaction.js +++ /dev/null @@ -1,221 +0,0 @@ -/** - * BioJS component to display Rhea reactions. - * @class - * @extends Biojs - * - * @author Rafael Alcántara - * @version 1.0.0 - * @category 3 - * - * @requires Server side proxy - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires Rheaction.css - * @dependency - * - * @param {Object} options An object with the options for the component. - * - * @option {string} target - * The ID of the DIV tag where the component should be displayed. - * - * @option {string} id - * The Rhea ID, with or without 'RHEA:' prefix. - * - * @option {string} [dimensions='200'] - * The dimensions of compound structure images (side of the square) in pixels. - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * This component needs to request data from a web service. To bypass the same origin policy - * (http://en.wikipedia.org/wiki/Same_origin_policy) this component needs a proxy. - * You could use your own proxy by modifying this value or one of the BioJS proxies: - * '../biojs/dependencies/proxy/proxy.php' or '../biojs/dependencies/proxy/proxy.jsp' - * - * - * @example - * var instance = new Biojs.Rheaction({ - * target: 'YourOwnDivId', - * id: '21881' - * }); - */ -Biojs.Rheaction = Biojs.extend ( -/** @lends Biojs.Rheaction# */ -{ - constructor: function (options){ - //Biojs.console.enable(); - this.setId(this.opt.id); - }, - /** - * Sets and displays data for a new identifier. - * @param {string} id The identifier. - * - * @example - * instance.setId("RHEA:10280"); - * - * @example - * instance.setId("10735"); - * - * @example - * instance.setId("RHEA:18476"); - * - * @example - * instance.setId("XXXXX"); - * - */ - setId: function(id){ - this._clearContent(); - var self = this; - var rheaId = id.replace('RHEA:', ''); - this._rheaIdLabel = 'RHEA_' + rheaId; - if ( "string" == (typeof this.opt.target) ) { - this._container = jQuery( "#" + this.opt.target ); - } else { - this.opt.target = "biojs_Rheaction_" + rheaId; - this._container = jQuery('
              '); - } - this._container.addClass('scrollpane'); - this._reactionRow = jQuery('
              ',{"class":'reactionRow'}); - this._container.append(this._reactionRow); - this._getCml(rheaId); - }, - - /** - * Default values for the options. - * @name Biojs.Rheaction-opt - */ - opt: { - target: undefined, - id: undefined, - dimensions: '200', - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - rheaWsUrl: 'http://www.ebi.ac.uk/rhea/rest/1.0/ws/reaction/cmlreact/', - chebiUrl: 'http://www.ebi.ac.uk/chebi/searchId.do?chebiId=', - chebiImgUrl: 'http://www.ebi.ac.uk/chebi/displayImage.do?defaultImage=true&scaleMolecule=true&chebiId=' - }, - - _clearContent: function(){ - jQuery("#" + this.opt.target).html(""); - }, - - _displayNoDataMessage: function(){ - jQuery('#'+this.opt.target+'').html(Biojs.Rheaction.MESSAGE_NODATA); - }, - - _getCml: function(rheaId){ - var self = this; - var reactionUrl = this.opt.rheaWsUrl + rheaId; - var httpRequest = { - url: reactionUrl, - method: 'GET', - /** @ignore No need to document this object */ - success: function(xml){ - self._dataReceived(xml); - }, - error: function(qXHR, textStatus, errorThrown){ - Biojs.console.log("ERROR requesting reaction. Response: " + textStatus); - } - }; - - // Using proxy? - // Redirect using the proxy and encode all params as url data - if ( this.opt.proxyUrl != undefined ) { - // Redirect to proxy url - httpRequest.url = this.opt.proxyUrl; - // Encode both url and parameters under the param url - httpRequest.data = [{ name: "url", value: reactionUrl }]; - // Data type - httpRequest.dataType = "text"; - } - - jQuery.ajax(httpRequest); - }, - - _dataReceived: function(xml){ - var self = this; - var data = {}; - var xmlDoc = ""; - if (xml.length > 0){ - try { - xmlDoc = jQuery.parseXML(xml); - xmlResult = jQuery(xmlDoc).find('reaction'); - var reactants = xmlResult.find('reactant'); - for (var i = 0; i < reactants.length; i++){ - if (i > 0) self._addPlus(); - self._addParticipant(reactants[i]); - } - self._addDirection(xmlResult.attr('convention')); - var products = xmlResult.find('product'); - for (var i = 0; i < products.length; i++){ - if (i > 0) self._addPlus(); - self._addParticipant(products[i]); - } - } catch (e) { - Biojs.console.log("ERROR decoding "); - Biojs.console.log(e); - this._displayNoDataMessage(); - } - } - }, - - - _addPlus: function(){ - jQuery('
              ', { "class": 'direction', html: '+' }) - .appendTo(this._reactionRow); - }, - - _addDirection: function(convention){ - var direction = convention.replace('rhea:direction.', ''); - var dirLabel = undefined; - switch (direction){ - case 'UN': - dirLabel = '<?>'; - break; - case 'BI': - dirLabel = '<=>'; - break; - default: - dirLabel = '=>'; - break; - } - jQuery('
              ', { "class": 'direction', html: dirLabel }) - .appendTo(this._reactionRow); - }, - - _addParticipant: function(participant){ - var coef = parseInt(participant.attributes['count'].value); - var molecule = jQuery(participant).find('molecule')[0]; - var compoundName = molecule.attributes['title'].value; - var chebiId = molecule.attributes['id'].value.replace('CHEBI:', ''); - var compDivId = this._rheaIdLabel + '_CHEBI_' + chebiId; - - jQuery('
              ', { - id: compDivId, - "class": 'compound', - css: { width: this.opt.dimensions } - }).appendTo(this._reactionRow); - if (coef > 1){ - $('#'+compDivId).append(jQuery('', { - "class": 'stoichCoef', - html: coef - })); - } - $('#'+compDivId).append(jQuery('', { - "class": 'compoundName', - html: compoundName, - href: this.opt.chebiUrl + chebiId, - title: 'CHEBI:' + chebiId - })); - $('#'+compDivId).append(jQuery('
              ')); - var imgUrl = this.opt.chebiImgUrl + chebiId - + '&dimensions=' + this.opt.dimensions; - $('#'+compDivId).append(jQuery('', { - src: imgUrl, - "class": 'compoundStructure', - title: 'CHEBI:' + chebiId - })); - } -},{ - MESSAGE_NODATA: "Sorry, no results for your request", -}); - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Ruler.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Ruler.js deleted file mode 100755 index 2150238141..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Ruler.js +++ /dev/null @@ -1,657 +0,0 @@ -/** - * - * Ruler is a component to deal with the definition and interaction of rules that follow the structure: - * In [LOCATION] [ACTION] the [TARGET] with [CONDITION] [PARAMETERS] - * The component receives a JSON structure defining the values of the different parts of the rule and it - * generates forms and lists. - * The component generates events when rules are created, removed or reordered. - * - * - * @class - * @extends Biojs - * - * @author
              Gustavo A. Salazar - * @version 1.0.1 - * @category 1 - * - * - * @requires jQuery Core 1.7.2 - * @dependency - * - * @requires jQuery UI 1.8.2 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires Selector CSS - * @dependency - * - * @requires Color Selector CSS - * @dependency - * - * @requires Color Selector - * @dependency - * - * - * - * - * @param {Object} options An object with the options for the Ruler component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {boolean} [allowOrdering=true] - * The list of created rules can be reordered by drag&drop, it requires the jquery ui dependencies - * - * @option {Object} rules - * A json stucture defining, the rules, possible values, conditions, etc. An example of the structure here: - *
              {
              - "location": [ "Some part of the page" ],
              - "action": ["Action 1", "Action 2", "Action 3" ],
              - "target": [ {
              -  "name": "First Target",
              -  "conditions": [ {
              -   "name": "Select from",
              -   "type": "selects",
              -   "amount": 1,
              -   "values": ["An Option","another option"  ]
              -  }, {
              -   "name": "number",
              -   "type": "numeric_comparison"
              -  }, {
              -   "name": "some text",
              -   "type": "text_comparison"
              -  } ]
              - } ]
              -} 
              - * - * @example - * var instance = new Biojs.Ruler({ - * target: "YourOwnDivId", - * allowOrdering:true, - * rules:{ - * "location": [ - * "all proteins", - * "protein1", - * "protein2", - * "protein3", - * "protein4" - * ], - * "target": [ - * { - * "name": "Proteins", - * "action": [ - * {name:"Show",type:"single"}, - * {name:"Hide",type:"single"}, - * {name:"Highlight",type:"single"}, - * {name:"Color",type:"color"}, - * {name:"Color Range",type:"colorRange"}, - * {name:"Show Label",type:"select",options:["ID","Functional Class","Organism","Gene Name"]} - * ], - * "conditions": [ - * { - * "name": "interactions with", - * "type": "selects", - * "amount": 1, - * "values": [ - * "protein1", - * "protein2", - * "protein3", - * "protein4" - * ] - * }, - * { - * "name": "number of interactions", - * "type": "numeric_comparison" - * }, - * { - * "name": "accession number", - * "type": "text_comparison" - * } - * ] - * }, - * { - * "name": "Interactions", - * "action": [ - * {name:"Show",type:"single"}, - * {name:"Hide",type:"single"}, - * {name:"Highlight",type:"single"}, - * {name:"Color",type:"color"}, - * ], - * "conditions": [ - * { - * "name": "protein", - * "type": "selects", - * "amount": 1, - * "values": [ - * "protein1", - * "protein2", - * "protein3", - * "protein4" - * ] - * }, - * { - * "name": "proteins", - * "type": "selects", - * "amount": 2, - * "values": [ - * "protein1", - * "protein2", - * "protein3", - * "protein4" - * ] - * }, - * { - * "name": "score", - * "type": "numeric_comparison" - * } - * ] - * } - * ] - * } - * }); - * - */ -Biojs.Ruler = Biojs.extend ( -/** @lends Biojs.Ruler# */ -{ - _number: 1, - constructor: function (options) { - var self=this; - var target =self.opt.target; - var innerCode = '
              '; - innerCode +='
              '; - innerCode +='
              Created Rules
              '; - innerCode +='
                '; - innerCode +='
              '; - innerCode +='
              '; - innerCode +='
              '; - innerCode +='
              New Rule
              '; - innerCode +=' '; - innerCode +='
                '; - innerCode +='
              '; - innerCode +='
              '; - innerCode +='
              '; - $("#"+target).append(innerCode); - if (self.opt.allowOrdering==true){ - $( ".sortable" ).sortable({ - stop: function(event,ui) { - self.raiseEvent('onOrderChanged', { - rules : self.getActiveRules() - }); - } - }); - $( ".sortable" ).disableSelection(); - }else - $( ".sortable" ).removeClass("sortable"); - - $( "#"+target+"_add_rule a" ).click(function(){ - self.addRule(); - }); - }, - - /** - * Default values for the options - * @name Biojs.Ruler-opt - */ - opt: { - target: "YourOwnDivId", - rules: null, - allowOrdering:true - }, - - /** - * Array containing the supported event names - * @name Biojs.Ruler-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.Ruler#onRuleCreated - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {Object} new_rule The rule that has been created. The rule Object contain the fields: location, action, target, condition, parameters(array), id, color - * @eventData {Array} rules Array with all the active rules. Each rule is an Object that contain the fields: location, action, target, condition, parameters, id, color - * @example - * instance.onRuleCreated( - * function( objEvent ) { - * alert("New rule: In "+objEvent.new_rule.location+" "+objEvent.new_rule.action+" the "+objEvent.new_rule.target+" with "+objEvent.new_rule.condition+" "+objEvent.new_rule.parameters.join()+""); - * } - * ); - */ - "onRuleCreated", - /** - * @name Biojs.Ruler#onRuleRemoved - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {Object} removed The rule that has been removed. The rule Object contain the fields: location, action, target, condition, parameters(array), id, color - * @eventData {Array} rules Array with all the active rules. Each rule is an Object that contain the fields: location, action, target, condition, parameters, id, color - * @example - * instance.onRuleRemoved( - * function( objEvent ) { - * alert("Rule removed: In "+objEvent.removed.location+" "+objEvent.removed.action+" the "+objEvent.removed.target+" with "+objEvent.removed.condition+" "+objEvent.removed.parameters.join()+""); - * } - * ); - */ - "onRuleRemoved", - /** - * @name Biojs.Ruler#onOrderChanged - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {Array} rules Array with all the active rules. Each rule is an Object that contain the fields: location, action, target, condition, parameters, id, color - * @example - * instance.onOrderChanged( - * function( objEvent ) { - * alert("Order has changed"); - * } - * ); - */ - "onOrderChanged", - /** - * @name Biojs.Ruler#onRuleEditing - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} - * object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {Object} editing The rule that has been selected to be edited. The rule Object contain the fields: location, action, target, condition, parameters(array), id, color - * @eventData {Array} rules Array with all the active rules. Each rule is an Object that contain the fields: location, action, target, condition, parameters, id, color - * @example - * instance.onRuleEditing( - * function( objEvent ) { - * alert("Editing Rule: In "+objEvent.editing.location+" "+objEvent.editing.action+" the "+objEvent.editing.target+" with "+objEvent.editing.condition+" "+objEvent.editing.parameters.join()+""); - * } - * ); - */ - "onRuleEditing" - ], - - /** - * Get an array with the active rules - * - * @example - * instance.getActiveRules(); - */ - getActiveRules:function(){ - var self=this; - var rules= new Array(); - $("#"+self.opt.target+'_list > li').each(function () { - rules.push($(this).data("rule")) - }); - return rules; - }, - /** - * Set the number of affected values by a given rule - * - * @param {string} id The id of the rule wich affecte value is going to be set. - * @param {integer} number The amount of entities affected by the rule. - * - * @example - * instance.setAffectedByRule('YourOwnDivId_rule_1',58); - */ - setAffectedByRule:function(ruleId,affected){ - var self=this; - $("#"+ruleId+" .affected").html(affected); - }, - - /** - * Change the Rules' model. Warning: this method does not take care of rules that have been defined with a previous model. - * - * @param {object} rules A json stucture defining, the rules, possible values, conditions, etc. See the example for the the constructor. - * - * @example - * instance.changeRules({ - "location": [ "Some part of the page" ], - "action": ["Action 1", "Action 2", "Action 3" ], - "target": [ { - "name": "First Target", - "conditions": [ { - "name": "Select from", - "type": "selects", - "amount": 1, - "values": ["An Option","another option" ] - }, { - "name": "number", - "type": "numeric_comparison" - }, { - "name": "some text", - "type": "text_comparison" - } ] - } ] - }); - */ - changeRules: function (rules){ - var self=this; - self.opt.rules=rules; - }, - - /** - * Add a rule to the new rule panel. this method can be invoked from an external script, be careful when using to - * create rules that follow the rules' model. - * - * @param {object} [rule] A rule with predefined values as an Object that contain the fields: location, action, target, condition, parameters, color - * - * @example - * instance.addRule({location:"protein1", action:"Color", target:"Proteins", condition:"number of interactions", parameters:["==","2"], color:"#F00"}); - */ - addRule: function (rule){ - var self = this; - var target =self.opt.target; - var number = self._number; - var code_rule = '
            • '; - code_rule+= ' '; - code_rule+= '
              '; - var gotRule =!(typeof rule=="undefined"); - var selectedTarget=0; - - if (typeof self.opt.rules.location !='undefined' && self.opt.rules.location.length>0){ - code_rule+= "In"; - code_rule+= self._getSelect('location_'+number,self.opt.rules.location,"", - gotRule?rule.location:rule - ); - } - - if (gotRule) - for (var i in self.opt.rules.target) - if (self.opt.rules.target[i].name==rule.target) - selectedTarget=i; - - code_rule+= ' '+ self._getActionSpan(number,selectedTarget,rule)+''; - code_rule+= ' the '; - code_rule+= self._getSelect('target_'+number,self.opt.rules.target,"name", - gotRule?rule.target:rule - ); - code_rule+= ' with '; - - var visible=gotRule?"none":"inline"; - for (var i in self.opt.rules.target){ - visible=gotRule? - ((self.opt.rules.target[i].name==rule.target)?"inline":"none"): - visible; - code_rule+= self._getConditionsSpan(number,self.opt.rules.target[i],visible,rule); - visible="none"; - } - code_rule+= ' APPLY
            • '; - $("#"+target+'_list_to_add').append(code_rule); - - - $( "#"+target+"_apply_rule_"+number ).click(function(){ - self._applyRule($(this)); - }); - - - //Visualizing the right inputs for the selected target - $( "#target_"+number ).change(function(){ - var n= $(this)[0].id.substr($(this)[0].id.lastIndexOf("_")+1); - for (var i in self.opt.rules.target){ - var target_name =self.opt.rules.target[i].name; - var target_id = target_name.replace(/ /g,""); - $("#conditions_"+n+"_"+target_id).css("display","none"); - } - $("#target_"+n+" option:selected").each(function () { - $("#conditions_"+n+"_"+$(this).text()).css("display","inline"); - $("#condition_params_"+n+"_"+$(this).text()+"_"+($("#condition_"+n+"_"+$(this).text()).val().replace(/ /g,""))).css("display","inline"); - $('#action_span_'+n).html(self._getActionSpan(n,$(this).parent()[0].selectedIndex)); - self._enableAction(n); - - }); - }); - - self._enableAction(number,rule); - - //Visualizing the right attributes for the selected condition - for (var i in self.opt.rules.target){ - var target_name =self.opt.rules.target[i].name; - var target_id = target_name.replace(/ /g,""); - $( "#condition_"+number+"_"+target_id ).change(function(){ - var parts= $(this)[0].id.split("_"); - $("#condition_"+parts[1]+"_"+parts[2]+" option").each(function () { - $("#condition_params_"+parts[1]+"_"+parts[2]+"_"+($(this).text().replace(/ /g,""))).css("display","none"); - }); - $("#condition_"+parts[1]+"_"+parts[2]+" option:selected").each(function () { - $("#condition_params_"+parts[1]+"_"+parts[2]+"_"+($(this).text().replace(/ /g,""))).css("display","inline"); - }); - }); - } - self._number++; - }, - /** - * Add a rule to the active rules' set. this method can be invoked from an external script, be careful when using by - * following the rules' model. - * - * @param {object} [rule] A rule with predefined values as an Object that contain the fields: location, action, target, condition, parameters, color - * - * @example - * instance.addActiveRule({location:"protein1", action:"Color", target:"Proteins", condition:"number of interactions", parameters:["==","2"], color:"#F00"}); - */ - addActiveRule: function(rule,n){ - var self =this; - var target =self.opt.target; - if (typeof n == "undefined"){ - n=self._number++; - rule.id =target+'_rule_'+n; - } - - var parameter_span=""; - switch (rule.action.type){ - case "color": - parameter_span = '_'; - break; - case "colorRange": - parameter_span = '_'; - parameter_span += '_'; - break; - case "select": - parameter_span = ''+rule.actionParameters[0]+''; - break; - } - - var locText = (typeof rule.location == 'undefined')?'':'In '+rule.location+' '; - $("#"+target+'_list').append('
            • '+rule.action.name+' '+parameter_span+' the '+rule.target+' with '+rule.condition+' '+rule.parameters.join(" ")+' remove edit 0
            • '); - - $('#'+target+'_rule_'+n).data("rule",rule);//{location:location,action:action,target:target1,condition:condition,parameters:parameters,id:target+'_rule_'+n, color:color}) - $('#'+target+'_rule_'+n+' span.remove').click(function(){ - var removed = $(this).parent().parent().parent().parent().parent().data("rule"); - $(this).parent().parent().parent().parent().parent().remove(); - self.raiseEvent('onRuleRemoved', { - rules : self.getActiveRules(), - removed: removed - }); - }); - $('#'+target+'_rule_'+n+' span.edit').click(function(){ - var editing = $(this).parent().parent().parent().parent().parent().data("rule"); - $(this).parent().parent().parent().parent().parent().remove(); - self.addRule(editing); - self.raiseEvent('onRuleEditing', { - rules : self.getActiveRules(), - editing: editing - }); - }); - self.raiseEvent('onRuleCreated', { - rules : self.getActiveRules(), - new_rule: $('#'+target+'_rule_'+n).data("rule") - }); - - }, - _applyRule: function(clicked){ - var self =this; - var target =self.opt.target; - var n= clicked[0].id.substr(clicked[0].id.lastIndexOf("_")+1); - var location = $('#location_'+n).val(); - var actionName= $('#action_'+n).val(); - var target1= $('#target_'+n).val(); - var action=self._getAction(target1,actionName); - var condition= $('#condition_'+n+'_'+target1.replace(/ /g,"")).val(); - var parameters= new Array(); - var par=0; - while (typeof $('#condition_params_'+n+'_'+target1+'_'+condition.replace(/ /g,"")+'_'+par).val() != "undefined"){ - parameters.push($('#condition_params_'+n+'_'+target1+'_'+condition.replace(/ /g,"")+'_'+par).val()); - par++; - } - var actionPar=[]; - switch (action.type){ - case "color": - actionPar.push($("#action_parameters_0_"+n).val()); - break; - case "colorRange": - actionPar.push($("#action_parameters_0_"+n).val()); - actionPar.push($("#action_parameters_1_"+n).val()); - break; - case "select": - actionPar.push($("#action_parameters_0_"+n).val()); - break - } - var rule = {location:location,action:action,actionParameters:actionPar,target:target1,condition:condition,parameters:parameters,id:target+'_rule_'+n}; - self.addActiveRule(rule,n); - clicked.parent().parent().parent().parent().parent().remove(); - - }, - _getConditionsSpan: function(n,target,visible,rule){ - var self= this; - var target_name =target.name; - var target_id = target_name.replace(/ /g,""); - var code_rule = ' '; - var gotRule =!(typeof rule=="undefined"); - - code_rule+= self._getSelect('condition_'+n+'_'+target_id,target.conditions,"name", - gotRule?rule.condition:rule - ); - - var visible_p=gotRule?"none":"inline"; - for (var j in target.conditions){ - visible_p=gotRule? - ((target.conditions[j].name==rule.condition)?"inline":"none"): - visible_p; - code_rule += self._getConditionSpan(n,target_id,target.conditions[j],visible_p,rule); - visible_p="none"; - } - code_rule+= ' '; - return code_rule; - - }, - _getConditionSpan: function(n,target_id,condition,visible_p,rule){ - var self =this; - var condition_name=condition.name; - var condition_id = condition_name.replace(/ /g,""); - var gotRule =!(typeof rule=="undefined"); - - var code_rule = ' '; - switch (condition.type){ - case "selects": - for (var i=0;i<1*condition.amount;i++) - code_rule+=self._getSelect('condition_params_'+n+'_'+target_id+'_'+condition_id+'_'+i,condition.values,"", - gotRule?rule.parameters[i]:rule - ); - break; - - case "numeric_comparison": - code_rule+=self._getSelect('condition_params_'+n+'_'+target_id+'_'+condition_id+'_0',["==",">","<",">=","<="],"", - gotRule?rule.parameters[0]:rule - ); - var value = gotRule?rule.parameters[1]:""; - code_rule += ' '; - break; - - case "text_comparison": - code_rule+=self._getSelect('condition_params_'+n+'_'+target_id+'_'+condition_id+'_0',["equals","contains","different","not contains"],"", - gotRule?rule.parameters[0]:rule - ); - var value = gotRule?rule.parameters[1]:""; - code_rule += ' '; - break; - case "feature_comparison": - code_rule+=self._getSelect('condition_params_'+n+'_'+target_id+'_'+condition_id+'_0',condition.values,"", - gotRule?rule.parameters[0]:rule - ); - code_rule+=self._getSelect('condition_params_'+n+'_'+target_id+'_'+condition_id+'_1',["equals","contains","different","not contains"],"", - gotRule?rule.parameters[1]:rule - ); - var value = gotRule?rule.parameters[2]:""; - code_rule += ' '; - break; - case "all": - break; - } - code_rule += ' '; - return code_rule; - }, - _getSelect: function(id, options,field,selected){ - var code = ' '; - return code; - }, - _getActionSpan: function(number,selectedTarget,rule){ - var self=this; - var gotRule =!(typeof rule=="undefined"); - var code = self._getSelect('action_'+number,self.opt.rules.target[selectedTarget].action,"name", - gotRule?rule.action.name:rule - ); - code+= ' '; - return code; - }, - _enableAction: function(number,rule){ - var self=this; - var gotRule =!(typeof rule=="undefined"); - //Visualizing the right inputs for the selected action - $( "#action_"+number ).change(function(){ - var n= $(this)[0].id.substr($(this)[0].id.lastIndexOf("_")+1); - self._enableActionParameters(n); - }); - self._enableActionParameters(number, rule); - - }, - _enableActionParameters: function(number,rule){ - var self=this; - var gotRule =!(typeof rule=="undefined"); - var action = (gotRule)?self._getAction(rule.target,rule.action.name):self._getAction($('#target_'+number).val(),$('#action_'+number).val()); - $("#action_parameters_"+number).html(''); - switch (action.type){ - case "color": - self._addColorSelector(number,0,(gotRule)?rule.actionParameters[0]:rule); - break; - case "colorRange": - self._addColorSelector(number,1,(gotRule)?rule.actionParameters[0]:"#F00"); - self._addColorSelector(number,0,(gotRule)?rule.actionParameters[1]:"#0F0"); - break; - case "select": - $("#action_parameters_"+number).html(self._getSelect('action_parameters_0_'+number,action.options,"", - gotRule?rule.actionParameters[0]:rule - )); - break - case "single": default: - $("#action_parameters_"+number).html(''); - } - }, - _addColorSelector: function(n,parameter,color){ - color = (typeof color!="undefined")?color:'#56992F'; - $("#action_parameters_"+n).append('') - $("#action_parameters_"+parameter+"_"+n).miniColors({ - letterCase: 'uppercase' - }).miniColors('value',color); - }, - _getAction: function(targetName,actionName){ - var self=this; - for (var i=0; i< self.opt.rules.target.length; i++){ - var target = self.opt.rules.target[i]; - if (target.name==targetName){ - for (var j=0; j< target.action.length; j++){ - var action=target.action[j]; - if (action.name==actionName) - return action; - } - } - } - } - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Sequence.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Sequence.js deleted file mode 100755 index ad36ffb31e..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Sequence.js +++ /dev/null @@ -1,1404 +0,0 @@ -/** - * Sequence component - * - * @class - * @extends Biojs - * - * @author John Gomez, Jose Villaveces - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires jQuery UI 1.8.16 - * @dependency - * - * @requires Biojs.Tooltip - * @dependency - * - * @param {Object} options An object with the options for Sequence component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} sequence - * The sequence to be displayed. - * - * @option {string} [id] - * Sequence identifier if apply. - * - * @option {string} [format="FASTA"] - * The display format for the sequence representation. - * - * @option {Object[]} [highlights] - * For highlighting multiple regions. - *
               
              - *    [
              - *    	// Highlight aminoacids from 'start' to 'end' of the current strand using the specified 'color' (optional) and 'background' (optional).
              - *    	{ start: <startVal1>, end: <endVal1> [, id:<idVal1>] [, color: <HTMLColor>] [, background: <HTMLColor>]}, 
              - *    	//
              - *    	// Any others highlights
              - *    	...,  
              - *    	// 
              - *    	{ start: <startValN>, end: <endValN> [, id:<idValN>] [, color: <HTMLColor>] [, background: <HTMLColor>]}
              - *    ]
              - * - *
               
              - * highlights : [
              - * 		{ start:30, end:42, color:"white", background:"green", id:"spin1" },
              - *		{ start:139, end:140 }, 
              - *		{ start:631, end:633, color:"white", background:"blue" }
              - *	]
              - * 
              - * - * @option {Object} [columns={size:40,spacedEach:10}] - * Options for displaying the columns. Syntax: { size: <numCols>, spacedEach: <numCols>} - * - * @option {Object} [selection] - * Positions for the current selected region. Syntax: { start: <startValue>, end: <endValue>} - * - * @option {Object[]} [annotations] - * Set of overlapping annotations. Must be an array of objects following the syntax: - *
              - *            [ 
              - *              // An annotation:
              - *              { name: <name>, 
              - *                html: <message>, 
              - *                color: <color_code>, 
              - *                regions: [{ start: <startVal1>, end: <endVal1> color: <HTMLColor>}, ...,{ start: <startValN>, end: <endValN>, color: <HTMLColor>}] 
              - *              }, 
              - *              
              - *              // ...
              - *              // more annotations here 
              - *              // ...
              - *            ]
              - *    		 
              - * where: - *
                - *
              • name is the unique name for the annotation
              • - *
              • html is the message (can be HTML) to be displayed in the tool tip.
              • - *
              • color is the default HTML color code for all the regions.
              • - *
              • regions array of objects defining the intervals which belongs to the annotation.
              • - *
              • regions[i].start is the starting character for the i-th interval.
              • - *
              • regions[i].end is the ending character for the i-th interval.
              • - *
              • regions[i].color is an optional color for the i-th interval. - *
              - * - * @option {Object} [formatOptions={title:true, footer:true}] - * Options for displaying the title. by now just affecting the CODATA format. - *
               
              - * 		formatOptions : {
              - * 			title:false,
              - * 			footer:false
              - * 		}
              - *    
              - * - * @example - * var theSequence = "METLCQRLNVCQDKILTHYENDSTDLRDHIDYWKHMRLECAIYYKAREMGFKHINHQVVPTLAVSKNKALQAIELQLTLETIYNSQYSNEKWTLQDVSLEVYLTAPTGCIKKHGYTVEVQFDGDICNTMHYTNWTHIYICEEAojs SVTVVEGQVDYYGLYYVHEGIRTYFVQFKDDAEKYSKNKVWEVHAGGQVILCPTSVFSSNEVSSPEIIRQHLANHPAATHTKAVALGTEETQTTIQRPRSEPDTGNPCHTTKLLHRDSVDSAPILTAFNSSHKGRINCNSNTTPIVHLKGDANTLKCLRYRFKKHCTLYTAVSSTWHWTGHNVKHKSAIVTLTYDSEWQRDQFLSQVKIPKTITVSTGFMSI"; - * var mySequence = new Biojs.Sequence({ - * sequence : theSequence, - * target : "YourOwnDivId", - * format : 'CODATA', - * id : 'P918283', - * annotations: [ - * { name:"CATH", - * color:"#F0F020", - * html: "Using color code #F0F020 ", - * regions: [{start: 122, end: 135}] - * }, - * { name:"TEST", - * html:"<br> Example of <b>HTML</b>", - * color:"green", - * regions: [ - * {start: 285, end: 292}, - * {start: 293, end: 314, color: "#2E4988"}] - * } - * ], - * highlights : [ - * { start:30, end:42, color:"white", background:"green", id:"spin1" }, - * { start:139, end:140 }, - * { start:631, end:633, color:"white", background:"blue" } - * ] - * }); - * - */ - -Biojs.Sequence = Biojs.extend( -/** @lends Biojs.Sequence# */ -{ - constructor: function (options) { - var self = this; - - this._container = jQuery( "#" + this.opt.target ); - - // Lazy initialization - this._container.ready(function() { - self._initialize(); - }); - }, - - /** - * Default values for the options - * @name Biojs.Sequence-opt - */ - opt : { - - sequence : "", - id : "", - target : "", - format : "FASTA", - selection: { start: 0, end: 0 }, - columns: { size: 35, spacedEach: 10 }, - highlights : [], - annotations: [], - sequenceUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/sequence', - - // Styles - selectionColor : 'Yellow', - selectionFontColor : 'black', - highlightFontColor : 'red', - highlightBackgroundColor : 'white', - fontFamily: '"Andale mono", courier, monospace', - fontSize: '12px', - fontColor : 'inherit', - backgroundColor : 'inherit', - width: undefined, - height: undefined, - formatSelectorVisible: true - }, - - /** - * Array containing the supported event names - * @name Biojs.Sequence-eventTypes - */ - eventTypes : [ - /** - * @name Biojs.Sequence#onSelectionChanged - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} start A number indicating the start of the selection. - * @eventData {int} end A number indicating the ending of selection. - * @example - * mySequence.onSelectionChanged( - * function( objEvent ) { - * alert("Selected: " + objEvent.start + ", " + objEvent.end ); - * } - * ); - * - * */ - "onSelectionChanged", - - /** - * @name Biojs.Sequence#onSelectionChange - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {int} start A number indicating the start of the selection. - * @eventData {int} end A number indicating the ending of selection. - * @example - * mySequence.onSelectionChange( - * function( objEvent ) { - * alert("Selection in progress: " + objEvent.start + ", " + objEvent.end ); - * } - * ); - * - * - * */ - "onSelectionChange", - - /** - * @name Biojs.Sequence#onAnnotationClicked - * @event - * @param {function} actionPerformed An function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} name The name of the selected annotation. - * @eventData {int} pos A number indicating the position of the selected amino acid. - * @example - * mySequence.onAnnotationClicked( - * function( objEvent ) { - * alert("Clicked " + objEvent.name + " on position " + objEvent.pos ); - * } - * ); - * - * */ - "onAnnotationClicked" - ], - - // internal members - _headerDiv : null, - _contentDiv : null, - - // Methods - - _initialize: function () { - - if ( this.opt.width !== undefined ) { - this._container.width( this.opt.width ); - } - - if ( this.opt.height !== undefined ) { - this._container.height( this.opt.height ); - } - - // Disable text selection - - this._container.css({ - '-moz-user-select':'none', - '-webkit-user-select':'none', - 'user-select':'none' - }); - - // DIV for the format selector - this._buildFormatSelector(); - - // DIV for the sequence - this._contentDiv = jQuery('
              ').appendTo(this._container); - this._contentDiv.css({ - 'font-family': this.opt.fontFamily, - 'font-size': this.opt.fontSize, - 'text-align': 'left' - }); - - // Initialize highlighting - this._highlights = this.opt.highlights; - - // Initialize annotations - this._annotations = this.opt.annotations; - - //Initialize tooltip - jQuery('
              ') - .css({ - 'position': "absolute", - 'z-index': "999999", - 'color': "#fff", - 'font-size': "12px", - 'width': "auto", - 'display': 'none' - }) - .addClass("tooltip") - .appendTo("body") - .hide(); - - if ( ! Biojs.Utils.isEmpty(this.opt.sequence) ) { - this._redraw(); - - } else if ( ! Biojs.Utils.isEmpty(this.opt.id) ) { - this._requestSequence( this.opt.id ); - - } else { - this.clearSequence("No sequence available", "../biojs/css/images/warning_icon.png"); - } - - }, - - - /** - * Shows the columns indicated by the indexes array. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * mySequence.setSequence("P99999"); - * - */ - setSequence: function ( seq, identifier ) { - - if ( seq.match(/^([A-N,R-Z][0-9][A-Z][A-Z, 0-9][A-Z, 0-9][0-9])|([O,P,Q][0-9][A-Z, 0-9][A-Z, 0-9][A-Z, 0-9][0-9])(\.\d+)?$/i) ) { - this._requestSequence( arguments[0] ); - - } else { - this.opt.sequence = seq; - this.opt.id = identifier; - this._highlights = []; - this._highlightsCount = 0; - this.opt.selection = { start: 0, end: 0 }; - this._annotations = []; - - this._contentDiv.children().remove(); - this._redraw(); - } - }, - - _requestSequence: function ( accession ) { - var self = this; - - Biojs.console.log("Requesting sequence for: " + accession ); - - jQuery.ajax({ - url: self.opt.sequenceUrl, - dataType: "xml", - data: { segment: accession }, - success: function ( xml ) { - try { - - var sequenceNode = jQuery(xml).find('SEQUENCE:first'); - self.setSequence( sequenceNode.text(), sequenceNode.attr("id"), sequenceNode.attr("label") ); - - } catch (e) { - Biojs.console.log("Error decoding response data: " + e.message ); - self.clearSequence("No sequence available", "../biojs/css/images/warning_icon.png"); - } - - }, - error: function (jqXHR, textStatus, errorThrown) { - Biojs.console.log("Error decoding response data: " + textStatus ); - self.clearSequence("Error requesting the sequence to the server " + this.url , "../biojs/css/images/warning_icon.png"); - } - }); - }, - - /** - * Shows the columns indicated by the indexes array. - * @param {string} [showMessage] Message to be showed. - * @param {string} [icon] Icon to be showed a side of the message - * - * @example - * mySequence.clearSequence("No sequence available", "../biojs/css/images/warning_icon.png"); - * - */ - clearSequence: function ( showMessage, icon ) { - - var message = undefined; - - this.opt.sequence = ""; - this.opt.id = ""; - this._highlights = []; - this._highlightsCount = 0; - this.opt.selection = { start: 0, end: 0 }; - this._annotations = []; - this._contentDiv.children().remove(); - - this._headerDiv.hide(); - - if ( undefined !== showMessage ) { - message = jQuery('
              ' + showMessage + '
              ') - .appendTo(this._contentDiv) - .addClass("message"); - - if ( undefined !== icon ) { - message.css({ - 'background': 'transparent url("' + icon + '") no-repeat center left', - 'padding-left': '20px' - }); - } - } - }, - - /** - * Set the current selection in the sequence causing the event {@link Biojs.Sequence#onSelectionChanged} - * - * @example - * // set selection from the position 100 to 150 - * mySequence.setSelection(100, 150); - * - * @param {int} start The starting character of the selection. - * @param {int} end The ending character of the selection - */ - setSelection : function(start, end) { - if(start > end) { - var aux = end; - end = start; - start = aux; - - } - - if(start != this.opt.selection.start || end != this.opt.selection.end) { - this._setSelection(start, end); - this.raiseEvent( - Biojs.Sequence.EVT_ON_SELECTION_CHANGED, - { "start" : start, "end" : end } - ); - } - }, - - _buildFormatSelector: function () { - var self = this; - - this._headerDiv = jQuery('
              ').appendTo(this._container); - this._headerDiv.css({ - 'font-family': '"Heveltica Neue", Arial, "sans serif"', - 'font-size': '14px' - }).append('Format: '); - - this._formatSelector = jQuery('').appendTo(self._headerDiv); - - this._formatSelector.change(function(e) { - self.opt.format = jQuery(this).val(); - self._redraw(); - }); - - this._formatSelector.val(self.opt.format); - - this.formatSelectorVisible( this.opt.formatSelectorVisible ); - }, - - /** - * Highlights a region using the font color defined in {Biojs.Protein3D#highlightFontColor} by default is red. - * - * @deprecated use addHighlight instead. - * - * @param {int} start The starting character of the highlighting. - * @param {int} end The ending character of the highlighting. - * @param {string} [color] HTML color code. - * @param {string} [background] HTML color code. - * @param {string} [id] Custom identifier. - * - * @return {int} representing the id of the highlight on the internal array. Returns -1 on failure - */ - highlight : function (start, end, color, background, id ) { - return this.addHighlight({ "start": start, "end": end, "color": color, "background": background, "id": id }); - }, - - /** - * Highlights a region using the font color defined in {Biojs.Sequence#highlightFontColor} by default is red. - * - * @example - * // highlight the characters within the position 100 to 150, included. - * mySequence.addHighlight( { "start": 100, "end": 150, "color": "white", "background": "red", "id": "aaa" } ); - * - * @param {Object} h The highlight defined as follows: - * - * - * @return {int} representing the id of the highlight on the internal array. Returns -1 on failure - */ - addHighlight : function ( h ) { - var id = '-1'; - var color = ""; - var background = ""; - var highlight = {}; - - if ( h instanceof Object && h.start <= h.end ) { - - color = ( "string" == typeof h.color )? h.color : this.opt.highlightFontColor; - background = ( "string" == typeof h.background )? h.background : this.opt.highlightBackgroundColor; - id = ( "string" == typeof h.id )? h.id : (new Number(this._highlightsCount++)).toString(); - - highlight = { "start": h.start, "end": h.end, "color": color, "background": background, "id": id }; - - this._highlights.push(highlight); - this._applyHighlight(highlight); - this._restoreSelection(h.start,h.end); - } - - return id; - }, - /* - * Function: Biojs.Sequence._applyHighlight - * Purpose: Apply the specified color and background to a region between 'start' and 'end'. - * Returns: - - * Inputs: highlight -> {Object} An object containing the fields start (int), end (int), - * color (HTML color string) and background (HTML color string). - */ - _applyHighlight: function ( highlight ) { - var seq = this._contentDiv.find('.sequence'); - for ( var i = highlight.start - 1; i < highlight.end; i++ ){ - zindex = jQuery(seq[i]).css("z-index"); - if (zindex=="auto"){ - z = 1; - o = 1; - } - else{ - z = 0; - o = 0.5; - } - jQuery(seq[i]) - .css({ - "color": highlight.color, - "background-color": highlight.background, - "z-index": z, - "opacity": o - }) - .addClass("highlighted"); - } - }, - /* - * Function: Biojs.Sequence._applyHighlights - * Purpose: Apply the specified highlights. - * Returns: - - * Inputs: highlights -> {Object[]} An array containing the highlights to be applied. - */ - _applyHighlights: function ( highlights ) { - for ( var i in highlights ) { - this._applyHighlight(highlights[i]); - } - }, - /* - * Function: Biojs.Sequence._restoreHighlights - * Purpose: Repaint the highlights in the specified region. - * Returns: - - * Inputs: start -> {int} Start of the region to be restored. - * end -> {int} End of the region to be restored. - */ - _restoreHighlights: function ( start, end ) { - var h = this._highlights; - // paint the region using default blank settings - this._applyHighlight({ - "start": start, - "end": end, - "color": this.opt.fontColor, - "background": this.opt.backgroundColor - }); - // restore highlights in that region - for ( var i in h ) { - // interval intersects with highlight i ? - if ( !( h[i].start > end || h[i].end < start ) ) { - a = ( h[i].start < start ) ? start : h[i].start; - b = ( h[i].end > end ) ? end : h[i].end; - this._applyHighlight({ - "start": a, - "end": b, - "color": h[i].color, - "background": h[i].background - }); - } - } - }, - /* - * Function: Biojs.Sequence._restoreSelection - * Purpose: Repaint the current selection in the specified region. - * It is used in the case of any highlight do overriding of the current selection. - * Returns: - - * Inputs: start -> {int} Start of the region to be restored. - * end -> {int} End of the region to be restored. - */ - _restoreSelection: function ( start, end ) { - var sel = this.opt.selection; - // interval intersects with current selection ? - // restore selection - if ( !( start > sel.end || end < sel.start ) ) { - a = ( start < sel.start ) ? sel.start : start; - b = ( end > sel.end ) ? sel.end : end; - - this._applyHighlight({ - "start": a, - "end": b, - "color": this.opt.selectionFontColor, - "background": this.opt.selectionColor, - }); - } - }, - - /** - * Clear a highlighted region using. - * - * @deprecated use removeHighlight instead. - * - * @param {int} id The id of the highlight on the internal array. This value is returned by method highlight. - */ - unHighlight : function (id) { - this.removeHighlight(id); - }, - - /** - * Remove a highlight. - * - * @example - * // Clear the highlighted characters within the position 100 to 150, included. - * mySequence.removeHighlight("spin1"); - * - * @param {string} id The id of the highlight on the internal array. This value is returned by method highlight. - */ - removeHighlight : function (id) { - var h = this._highlights; - for ( i in h ) { - if ( h[i].id == id ) { - start = h[i].start; - end = h[i].end; - h.splice(i,1); - - this._restoreHighlights(start,end); - this._restoreSelection(start,end); - - break; - } - } - }, - - /** - * Clear the highlights of whole sequence. - * @deprecated use removeAllHighlights instead. - */ - unHighlightAll : function () { - this.removeAllHighlights(); - }, - - /** - * Remove all the highlights of whole sequence. - * - * @example - * mySequence.removeAllHighlights(); - */ - removeAllHighlights : function () { - this._highlights = []; - this._restoreHighlights(1,this.opt.sequence.length); - this._restoreSelection(1,this.opt.sequence.length); - }, - - /** - * Changes the current displaying format of the sequence. - * - * @example - * // Set format to 'FASTA'. - * mySequence.setFormat('FASTA'); - * - * @param {string} format The format for the sequence to be displayed. - */ - setFormat : function(format) { - if ( this.opt.format != format.toUpperCase() ) { - this.opt.format = format.toUpperCase(); - this._redraw(); - } - - var self = this; - // Changes the option in the combo box - this._headerDiv.find('option').each(function() { - if(jQuery(this).val() == self.opt.format.toUpperCase()) { - jQuery(this).attr('selected', 'selected'); - } - }); - }, - - /** - * Changes the current number of columns in the displayed sequence. - * - * @example - * // Set the number of columns to 70. - * mySequence.setNumCols(70); - * - * @param {int} numCols The number of columns. - */ - setNumCols : function(numCols) { - this.opt.columns.size = numCols; - this._redraw(); - }, - - /** - * Set the visibility of the drop-down list of formats. - * - * @param {boolean} visible true: show; false: hide. - */ - formatSelectorVisible : function (visible){ - if (visible) { - this._headerDiv.show(); - } else { - this._headerDiv.hide(); - } - }, - - /** - * This is similar to a {Biojs.Protein3D#formatSelectorVisible} with the 'true' argument. - * - * @example - * // Shows the format selector. - * mySequence.showFormatSelector(); - * - */ - showFormatSelector : function() { - this._headerDiv.show(); - }, - - /** - * This is similar to a {Biojs.Protein3D#formatSelectorVisible} with the 'false' argument. - * - * @example - * // Hides the format selector. - * mySequence.hideFormatSelector(); - * - */ - hideFormatSelector : function() { - this._headerDiv.hide(); - }, - - /** - * Hides the whole component. - * - */ - hide : function () { - this._headerDiv.hide(); - this._contentDiv.hide(); - }, - - /** - * Shows the whole component. - * - */ - show : function () { - this._headerDiv.show(); - this._contentDiv.show(); - }, - /* - * Function: Biojs.Sequence._setSelection - * Purpose: Update the current selection. - * Returns: - - * Inputs: start -> {int} Start of the region to be selected. - * end -> {int} End of the region to be selected. - */ - _setSelection : function(start, end) { - //alert("adsas"); - - var current = this.opt.selection; - var change = {}; - - // Which is the change on selection? - if ( current.start == start ) { - // forward? - if ( current.end < end ) { - change.start = current.end; - change.end = end; - } else { - this._restoreHighlights(end+1, current.end); - } - } else if ( current.end == end ) { - // forward? - if ( current.start > start ) { - change.start = start; - change.end = current.start; - } else { - this._restoreHighlights(current.start, start-1); - } - } else { - this._restoreHighlights(current.start, current.end); - change.start = start; - change.end = end; - } - - current.start = start; - current.end = end; - - if ( change.start != undefined ) { - this._applyHighlight({ - "start": change.start, - "end": change.end, - "color": this.opt.selectionFontColor, - "background": this.opt.selectionColor - }); - } - - }, - - /* - * Function: Biojs.Sequence._repaintSelection - * Purpose: Repaint the whole current selection. - * Returns: - - * Inputs: - - */ - _repaintSelection: function(){ - var s = Biojs.Utils.clone(this.opt.selection); - this._setSelection(0,0); - this._setSelection(s.start,s.end); - }, - - /* - * Function: Biojs.Sequence._redraw - * Purpose: Repaint the current sequence. - * Returns: - - * Inputs: - - */ - _redraw : function() { - var i = 0; - var self = this; - - // Reset the content - //this._contentDiv.text(''); - this._contentDiv.children().remove(); - - // Rebuild the spans of the sequence - // according to format - if(this.opt.format == 'RAW') { - this._drawRaw(); - } else if(this.opt.format == 'CODATA') { - this._drawCodata(); - } else if (this.opt.format == 'FASTA'){ - this._drawFasta(); - } else { - this.opt.format = 'PRIDE'; - this._drawPride(); - } - - // Restore the highlighted regions - this._applyHighlights(this._highlights); - this._repaintSelection(); - this._addSpanEvents(); - }, - /* - * Function: Biojs.Sequence._drawFasta - * Purpose: Repaint the current sequence using FASTA format. - * Returns: - - * Inputs: - - */ - _drawFasta : function() { - var self = this; - var a = this.opt.sequence.toUpperCase().split(''); - var pre = jQuery('
              ').appendTo(this._contentDiv);
              -
              -		var i = 1;
              -		var arr = [];
              -	    var str = '>' + this.opt.id + ' ' + a.length + ' bp
              '; - - /* Correct column size in case the sequence is as small peptide */ - var numCols = this.opt.columns.size; - if ( this.opt.sequence.length < this.opt.columns.size ) { - numCols = this.opt.sequence.length; - } - - var opt = { - numCols: numCols, - numColsForSpace: 0 - }; - - str += this._drawSequence(a, opt); - pre.html(str); - - this._drawAnnotations(opt); - }, - /* - * Function: Biojs.Sequence._drawCodata - * Purpose: Repaint the current sequence using CODATA format. - * Returns: - - * Inputs: - - */ - _drawCodata : function() { - - var self = this; - var a = this.opt.sequence.toUpperCase().split(''); - var pre = jQuery('
              ').appendTo(this._contentDiv);
              -
              -		var i = 0;
              -		var str = 'ENTRY           ' + this.opt.id + '
              '; - str += 'SEQUENCE
              '; - if ( this.opt.formatOptions !== undefined ){ - if(this.opt.formatOptions.title !== undefined ){ - if (this.opt.formatOptions.title == false) { - str = ''; - } - } - } - - /* Correct column size in case the sequence is as small peptide */ - var numCols = this.opt.columns.size; - if ( this.opt.sequence.length < this.opt.columns.size ) { - numCols = this.opt.sequence.length; - } - - var opt = { - numLeft: true, - numLeftSize: 7, - numLeftPad:' ', - numTop: true, - numTopEach: 5, - numCols: numCols, - numColsForSpace: 0, - spaceBetweenChars: true - }; - - str += this._drawSequence(a, opt); - - var footer = '
              ///'; - if (this.opt.formatOptions !== undefined) { - if (this.opt.formatOptions.footer !== undefined) { - if (this.opt.formatOptions.footer == false) { - footer = ''; - } - } - } - str += footer; - pre.html(str); - - this._drawAnnotations(opt); - }, - /* - * Function: Biojs.Sequence._drawAnnotations - * Purpose: Paint the annotations on the sequence. - * Returns: - - * Inputs: settings -> {object} - */ - _drawAnnotations: function ( settings ){ - - var self = this; - var a = this.opt.sequence.toLowerCase().split(''); - var annotations = this._annotations; - var leftSpaces = ''; - var row = ''; - var annot = ''; - - // Index at the left? - if ( settings.numLeft ) { - leftSpaces += this._formatIndex(' ', settings.numLeftSize+2, ' '); - } - - for ( var i = 0; i < a.length; i += settings.numCols ){ - row = ''; - for ( var key in annotations ){ - annotations[key].id = this.getId() + "_" + key; - annot = this._getHTMLRowAnnot(i+1, annotations[key], settings); - if (annot.length > 0) { - row += '
              '; - row += leftSpaces; - row += annot; - row += '
              '; - } - } - - var numCols = settings.numCols; - var charRemaining = a.length-i; - if(charRemaining < numCols){ - numCols = charRemaining; - } - - if ( settings.numRight ) { - jQuery(row).insertAfter('div#'+self.opt.target+' div pre span#numRight_' + this.getId() + '_' + (i + numCols) ); - } else { - jQuery(row).insertAfter('div#'+self.opt.target+' div pre span#'+ this.getId() + '_' + (i + numCols) ); - } - } - - // add tool tips and background' coloring effect - jQuery(this._contentDiv).find('.annotation').each( function(){ - self._addToolTip( this, function() { - return self._getAnnotationString( jQuery(this).attr("id") ); - }); - - jQuery(this).mouseover(function(e) { - jQuery('.annotation.'+jQuery(e.target).attr("id")).each(function(){ - jQuery(this).css("background-color", jQuery(this).attr("color") ); - }); - }).mouseout(function() { - jQuery('.annotation').css("background-color", "transparent"); - - }).click(function(e) { - self.raiseEvent( Biojs.Sequence.EVT_ON_ANNOTATION_CLICKED, { - "name": self._annotations[ jQuery(e.target).attr("id") ].name, - "pos": parseInt( jQuery(e.target).attr("pos") ) - }); - }); - - }); - - }, - /* - * Function: Biojs.Sequence._getAnnotationString - * Purpose: Get the annotation text message for the tooltip - * Returns: {string} Annotation text for the annotation - * Inputs: id -> {int} index of the internal annotation array - */ - _getAnnotationString: function ( id ) { - var annotation = this._annotations[id.substr(id.indexOf("_") + 1)]; - return annotation.name + "
              " + ((annotation.html)? annotation.html : ''); - }, - - /* - * Function: Biojs.Sequence._getHTMLRowAnnot - * Purpose: Build an annotation - * Returns: HTML of the annotation - * Inputs: currentPos -> {int} - * annotation -> {Object} - * settings -> {Object} - */ - _getHTMLRowAnnot : function (currentPos, annotation, settings) { - var styleBegin = 'border-left:1px solid; border-bottom:1px solid; border-color:'; - var styleOn = 'border-bottom:1px solid; border-color:'; - var styleEnd = 'border-bottom:1px solid; border-right:1px solid; border-color:'; - var styleBeginAndEnd = 'border-left:1px solid; border-right:1px solid; border-bottom:1px solid; border-color:'; - - var row = []; - var end = (currentPos + settings.numCols); - var spaceBetweenChars = (settings.spaceBetweenChars)? ' ' : ''; - var defaultColor = annotation.color; - var id = annotation.id; - for ( var pos=currentPos; pos < end ; pos++ ) { - // regions - for ( var r in annotation.regions ) { - region = annotation.regions[r]; - - spaceAfter = ''; - spaceAfter += (pos % settings.numColsForSpace == 0 )? ' ' : ''; - spaceAfter += spaceBetweenChars; - - color = ((region.color)? region.color : defaultColor); - data = 'class="annotation '+id+'" id="'+id+'" color="'+color+'" pos="'+pos+'"'; - - if ( pos == region.start && pos == region.end) { - row[pos] = ' '; - row[pos] += spaceAfter; - row[pos] += ''; - } else if ( pos == region.start ) { - row[pos] = ' '; - row[pos] += spaceAfter; - row[pos] += ''; - } else if ( pos == region.end ) { - row[pos] = ' '; - //row[pos] += spaceAfter; - row[pos] += ''; - } else if ( pos > region.start && pos < region.end ) { - row[pos] = ' '; - row[pos] += spaceAfter; - row[pos] += ''; - } else if (!row[pos]) { - row[pos] = ' '; - row[pos] += spaceAfter; - } - } - } - - var str = row.join(""); - - return ( str.indexOf("span") == -1 )? "" : str; - }, - /* - * Function: Biojs.Sequence._drawRaw - * Purpose: Repaint the current sequence using RAW format. - * Returns: - - * Inputs: - - */ - _drawRaw : function() { - var self = this; - var a = this.opt.sequence.toLowerCase().split(''); - var i = 0; - var arr = []; - var pre = jQuery('
              ').appendTo(this._contentDiv);
              -		
              -		/* Correct column size in case the sequence is as small peptide */
              -		var numCols = this.opt.columns.size;
              -		if ( this.opt.sequence.length < this.opt.columns.size ) {
              -			numCols = this.opt.sequence.length;	
              -		}
              -
              -		var opt = {
              -			numCols: numCols
              -		};
              -		
              -		pre.html(
              -			this._drawSequence(a, opt)
              -		);
              -		
              -		this._drawAnnotations(opt);
              -	},
              -	/* 
              -     * Function: Biojs.Sequence._drawPride
              -     * Purpose:  Repaint the current sequence using PRIDE format.  
              -     * Returns:  -
              -     * Inputs: -
              -     */
              -	_drawPride : function() {
              -		var self = this;
              -		var a = this.opt.sequence.toUpperCase().split('');
              -		var pre = jQuery('
              ').appendTo(this._contentDiv);
              -		
              -		/* Correct column size in case the sequence is as small peptide */
              -		var numCols = this.opt.columns.size;
              -		if ( this.opt.sequence.length < this.opt.columns.size ) {
              -			numCols = this.opt.sequence.length;	
              -		}
              -	
              -		opt = {
              -			numLeft: true,
              -			numLeftSize: 5,
              -			numLeftPad:'0',
              -			numRight: true,
              -			numRightSize: 5,
              -			numRightPad: '0',
              -			numCols: numCols,
              -		    numColsForSpace: self.opt.columns.spacedEach
              -		};
              -		
              -		pre.html(
              -			this._drawSequence(a, opt)
              -		);
              -		
              -		this._drawAnnotations(opt);
              -	},
              -	/* 
              -     * Function: Biojs.Sequence._drawSequence
              -     * Purpose:  Repaint the current sequence using CUSTOM format.  
              -     * Returns:  -
              -     * Inputs:   a -> {char[]} a The sequence strand.
              -     * 			 opt -> {Object} opt The CUSTOM format.
              -     */
              -	_drawSequence : function(a, opt) {
              -		var str = '';
              -
              -		var spaceStyle =  "white-space: pre;";
              -		
              -		// Index at top?
              -		if( opt.numTop )
              -		{
              -			str += ''
              -			var size = (opt.spaceBetweenChars)? opt.numTopEach*2: opt.numTopEach;
              -			
              -			if (opt.numLeft) {
              -				str += this._formatIndex(' ', opt.numLeftSize, ' ');
              -			}
              -			
              -			str += this._formatIndex(' ', size, ' ');
              -			
              -			for(var x = opt.numTopEach; x < opt.numCols; x += opt.numTopEach) {
              -				str += this._formatIndex(x, size, ' ', true);
              -			}
              -			str += '
              ' - } - - - // Index at the left? - if (opt.numLeft) { - str += this._formatIndex(1, opt.numLeftSize, opt.numLeftPad); - str += ' '; - } - - var j=1; - for (var i=1; i <= a.length; i++) { - - if( i % opt.numCols == 0) { - str += '' + a[i-1] + ''; - - if (opt.numRight) { - str += ''; - str += ' '; - str += this._formatIndex(i, opt.numRightSize, opt.numRightPad); - str += ''; - } - - str += '
              '; - - var aaRemaining = a.length - i; - if (opt.numLeft && aaRemaining > 0) { - str += ''; - str += this._formatIndex(i+1, opt.numLeftSize, opt.numLeftPad); - str += ' '; - str += ''; - } - - j = 1; - - } else { - str += '' + a[i-1]; - str += ( j % opt.numColsForSpace == 0)? ' ' : ''; - str += (opt.spaceBetweenChars)? ' ' : ''; - str += ''; - j++; - } - } - - str += '
              ' - - if (jQuery.browser.msie) { - str = "
              " + str + "
              "; - } - - return str; - }, - /* - * Function: Biojs.Sequence._formatIndex - * Purpose: Build the HTML corresponding to counting numbers (top, left, right) in the strand. - * Returns: - - * Inputs: number -> {int} The number - * size -> {int} Number of bins to suit the number. - * fillingChar -> {char} Character to be used for filling out blank bins. - * alignLeft -> {bool} Tell if aligned to the left. - */ - _formatIndex : function( number, size, fillingChar, alignLeft) { - var str = number.toString(); - var filling = ''; - var padding = size - str.length; - if ( padding > 0 ) { - while ( padding-- > 0 ) { - filling += (""+fillingChar+""); - } - if (alignLeft){ - str = number+filling; - } else { - str = filling+number; - } - } - return str; - }, - /* - * Function: Biojs.Sequence._addSpanEvents - * Purpose: Add the event handlers to the strand. - * Returns: - - * Inputs: - - */ - _addSpanEvents : function() { - var self = this; - var isMouseDown = false; - var currentPos; - - self._contentDiv.find('.sequence').each( function () { - - // Register the starting position - jQuery(this).mousedown(function() { - var id = jQuery(this).attr('id'); - currentPos = parseInt(id.substr(id.indexOf("_") + 1)); - clickPos = currentPos; - self._setSelection(clickPos,currentPos); - isMouseDown = true; - - // Selection is happening, raise an event - self.raiseEvent( - Biojs.Sequence.EVT_ON_SELECTION_CHANGE, - { - "start" : self.opt.selection.start, - "end" : self.opt.selection.end - } - ); - - }).mouseover(function() { - // Update selection - // Show tooltip containing the position - var id = jQuery(this).attr('id'); - currentPos = parseInt(id.substr(id.indexOf("_") + 1)); - - if(isMouseDown) { - if( currentPos > clickPos ) { - self._setSelection(clickPos, currentPos); - } else { - self._setSelection(currentPos, clickPos); - } - - // Selection is happening, raise an event - self.raiseEvent( Biojs.Sequence.EVT_ON_SELECTION_CHANGE, { - "start" : self.opt.selection.start, - "end" : self.opt.selection.end - }); - } - - }).mouseup(function() { - isMouseDown = false; - // Selection is done, raise an event - self.raiseEvent( Biojs.Sequence.EVT_ON_SELECTION_CHANGED, { - "start" : self.opt.selection.start, - "end" : self.opt.selection.end - }); - }); - - // Add a tooltip for this sequence base. - self._addToolTip.call( self, this, function( ) { - if (isMouseDown) { - return "[" + self.opt.selection.start +", " + self.opt.selection.end + "]"; - } else { - return currentPos; - } - }); - - }) - .css('cursor', 'pointer'); - }, - /* - * Function: Biojs.Sequence._addTooltip - * Purpose: Add a tooltip around the target DOM element provided as argument - * Returns: - - * Inputs: target -> {Element} DOM element wich is the targeted focus for the tooltip. - * cbGetMessageFunction -> {function} A callback function wich returns the message to be displayed in the tip. - */ - _addToolTip : function ( target, cbGetMessageFunction ) { - - var tipId = '#sequenceTip' + this.getId(); - - jQuery(target).mouseover(function(e) { - - var offset = jQuery(e.target).offset(); - - if ( ! jQuery( tipId ).is(':visible') ) { - jQuery( tipId ) - .css({ - 'background-color': "#000", - 'padding': "3px 10px 3px 10px", - 'top': offset.top + jQuery(e.target).height() + "px", - 'left': offset.left + jQuery(e.target).width() + "px" - }) - .animate( {opacity: '0.85'}, 10) - .html( cbGetMessageFunction.call( target ) ) - .show(); - } - - }).mouseout(function() { - //Remove the appended tooltip template - jQuery( tipId ).hide(); - }); - }, - - /** - * Annotate a set of intervals provided in the argument. - * - * @deprecated Use addAnnotation() instead. - * - * @param {Object} annotation The intervals belonging to the same annotation. - * Syntax: { name: <value>, color: <HTMLColorCode>, html: <HTMLString>, regions: [{ start: <startVal1>, end: <endVal1>}, ..., { start: <startValN>, end: <endValN>}] } - */ - setAnnotation: function ( annotation ) { - this.addAnnotation(annotation); - }, - - /** - * Annotate a set of intervals provided in the argument. - * - * @example - * // Annotations using regions with different colors. - * mySequence.addAnnotation({ - * name:"UNIPROT", - * html:"<br> Example of <b>HTML</b>", - * color:"green", - * regions: [ - * {start: 540, end: 560}, - * {start: 561, end:580, color: "#FFA010"}, - * {start: 581, end:590, color: "red"}, - * {start: 690, end:710}] - * }); - * - * - * @param {Object} annotation The intervals belonging to the same annotation. - * Syntax: { name: <value>, color: <HTMLColorCode>, html: <HTMLString>, regions: [{ start: <startVal1>, end: <endVal1>}, ..., { start: <startValN>, end: <endValN>}] } - */ - addAnnotation: function ( annotation ) { - this._annotations.push(annotation); - this._redraw(); - }, - - /** - * Removes an annotation by means of its name. - * - * @example - * // Remove the UNIPROT annotation. - * mySequence.removeAnnotation('UNIPROT'); - * - * @param {string} name The name of the annotation to be removed. - * - */ - removeAnnotation: function ( name ) { - for (var i=0; i < this._annotations.length ; i++ ){ - if(name != this._annotations[i].name){ - this._annotations.splice(i,1); - this._redraw(); - break; - } - } - }, - /** - * Removes all the current annotations. - * - * @example - * mySequence.removeAllAnnotations(); - * - */ - removeAllAnnotations: function () { - this._annotations = []; - this._redraw(); - } - -}, -{ - EVT_ON_SELECTION_CHANGE: "onSelectionChange", - EVT_ON_SELECTION_CHANGED: "onSelectionChanged", - EVT_ON_ANNOTATION_CLICKED: "onAnnotationClicked" - -}); - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.SimpleFeatureViewer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.SimpleFeatureViewer.js deleted file mode 100755 index d7a03dbf88..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.SimpleFeatureViewer.js +++ /dev/null @@ -1,649 +0,0 @@ -/** - * This component generates the JSON structure used by the FeatureViewer. It is a simplified version as it only - * includes a non-overlapping view. Regions are represented as rectangles while one-base/aa are represented as lines. - * Some few shapes are also supported for one-base/aa features, particularly{"diamond", "triangle", "hexagon", - * "wave", "circle"}. In proteins, we recommend "diamond" for active sites, "triangle" for PTMs, "hexagon" for glycosylation, - * "wave" for lipids, and "circle" for metals. Any other shape will be rendered as a rectangle. Bridges can be specified - * with the type "bridge". - * The legend is generated based on the first feature of each "typeLabel"; thus, if features with the same "typeLabel" - * have different colours, only the first one will be used in the legend. - * - * @class - * @extends Biojs.FeatureViewer - * - * @author Leyla Jael Garcia Castro - * @version 1.0.0 - * @category 2 - * - * - * @param {Object} options An object with the options for SimpleFeatureViewer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {boolean} [showSlider=true] - * Should the slider for zooming be displayed? - * - * @option {boolean} [showPrintButton=true] - * Should the button for printing/exporting to image be displayed? - * - * @option {boolean} [showFeatureTooltipOnMouseOver=true] - * Should the tooltip for features be displayed? - * - * @option {boolean} [highlightFeatureOnMouseOver=true] - * Should the features be highlighted when mouse over? - * - * @option {boolean} [selectFeatureOnMouseClick=true] - * Should the features remain highlighted, i.e. being selected, after a mouse click, - * and deselected after a second click or whenever other feature is selected? - * - * @option {String} [selectionColor=#ff8c00] - * Color in hexa format so the features on mouse-over and click will change to it. - * Make sure you do not use that color for any feature. - * - * @option {string} sequenceId - * Sequence identifier - * - * @option {string} sequenceLength - * Sequence length - * - * @option {Array} features - * A JSON array containing the features to be displayed. type element for a feature is optional and can be either of - * {"rect", "bridge", "diamond", "triangle", "hexagon", "wave", "circle"} - * If you want bridges or one-single-position features to be rendered as rectangles, do not specify any type for the feature - * In proteins, we recommend "diamond" for active sites, "triangle" for PTMs, "hexagon" for glycosylation, - * "wave" for lipids, and "circle" for metals. Any other shape will be rendered as a rectangle - * Colours can be specified in hexa, string, or rgb; if no colour is specified, black will be used. - * features = [ - * { - * featureId:"UNIPROTKB_Q8LAX3_PROPEP_1_73", - * featureStart:1,featureEnd:73, - * typeLabel:"Propeptide", - * featureLabel:"Propeptide", - * typeCategory:"Molecule processing",typeCode:"SO:0001062", - * evidenceText:"UniProt",evidenceCode:"none", - * color: "red" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_PEPTIDE_54_96", - * featureStart:54,featureEnd:96, - * typeLabel:"Peptide", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * color: "blue" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_PEPTIDE_74_96", - * featureStart:74,featureEnd:96, - * typeLabel:"Active Site", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * type: "diamond" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_DISULFID_75_96", - * featureStart:75,featureEnd:96, - * typeLabel:"Active Site", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * color: "#33FF66", - * type: "bridge" - * } - * ]; - * - * @option {int} [imageWidth=700] - * Image width - * - * @example - * var myFT = [ - * { - * featureId:"UNIPROTKB_Q8LAX3_PROPEP_1_73", - * featureStart:1,featureEnd:73, - * typeLabel:"Propeptide", - * featureLabel:"Propeptide", - * typeCategory:"Molecule processing",typeCode:"SO:0001062", - * evidenceText:"UniProt",evidenceCode:"none", - * color: "red" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_PEPTIDE_54_96", - * featureStart:54,featureEnd:96, - * typeLabel:"Peptide", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * color: "blue" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_PEPTIDE_74_96", - * featureStart:74,featureEnd:96, - * typeLabel:"Active Site", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * type: "diamond" - * }, - * { - * featureId:"UNIPROTKB_Q8LAX3_DISULFID_75_96", - * featureStart:75,featureEnd:96, - * typeLabel:"Active Site", - * featureLabel:"Elicitor peptide 3", - * typeCategory:"Molecule processing",typeCode:"SO:0001064", - * evidenceText:"UniProt",evidenceCode:"no ECO", - * color: "#33FF66", - * type: "bridge" - * } - * ]; - * var myPainter = new Biojs.SimpleFeatureViewer({ - * target: "YourOwnDivId", - * sequenceId: "a4_human", - * sequenceLength: 770, - * features: myFT - * }); - * - */ -Biojs.SimpleFeatureViewer = Biojs.FeatureViewer.extend( - /** @lends Biojs.SimpleFeatureViewer */ - { - /** - * Default values for the options - * @name Biojs.SimpleFeatureViewer-constructor - */ - constructor:function (options) { - this.base(options); - //Biojs.console.enable(); - this._generatesJSON(); - this.paintFeatures(this.opt.json); - }, - - /** - * Default values for the options: - * target: "", - * showSlider: true, - * showPrintButton: true, - * showFeatureTooltipOnMouseOver: true, - * highlightFeatureOnMouseOver: true, - * selectFeatureOnMouseClick: true, - * selectionColor: "#ff8c00" - * imageWidth: 700, - * sequenceId: "none" - * sequenceLength: 0 - * features: {} - * - * @name Biojs.SimpleFeatureViewer-opt - */ - opt:{ - //Parent - /* target:"YourOwnDivId", - json: {}, //will be created by this component - showSlider:true, - showPrintButton:true, - showFeatureTooltipOnMouseOver:true, - highlightFeatureOnMouseOver:true, - selectFeatureOnMouseClick:true, - selectionColor:"#ff8c00", - */ - dragSites: false, - imageWidth:700 - }, - - /** - * Array containing the supported event names - * @name Biojs.SimpleFeatureViewer-eventTypes - */ - eventTypes : [], - - /** - * Opens a new window/tab in the browser with the graphical representation as a plain image. - * Note: For IE it does not reflect the drags/drops on sites - * - * @example - * myPainter.exportFeaturesToImage(); - * - */ - exportFeaturesToImage: function() { - var config = this.opt.json.configuration; - var dataURL = ""; - if (jQuery.browser.msie) { //canvas does not work (not even with IE 9) - alert("Operation not supported for IE, please try from a different browser"); - } else { - svg = document.getElementById('uniprotFeaturePainter-holder').innerHTML; - var canvas = document.createElement("canvas"); - canvg(canvas, svg); - dataURL = canvas.toDataURL(); - this.$imageExported = jQuery('
              ') - .html('exported image') - .dialog({ - autoOpen: true, - title: 'Exported image', - modal: true, - width: config.sizeX+20 - }); - } - }, - //Default height for rectangles - _rectangleHeight: 10, - _tracks: 0, - - /* - * Generates a json file with all configuration and raphaël related info from a simple features json - * INPUT (example) - * sequenceId, sequenceLength, - * features = [ - * { - * featureEnd:73, - * evidenceText:"UniProt",typeLabel:"Propeptide", - * featureLabel:"Propeptide",featureStart:1, - * typeCategory:"Molecule processing",typeCode:"SO:0001062",evidenceCode:"none", - * featureId:"UNIPROTKB_Q8LAX3_PROPEP_1_73", - * color: "#7DBAA4" - * } - * ,{ - * featureEnd:96, - * evidenceText:"UniProt",typeLabel:"Peptide", - * featureLabel:"Elicitor peptide 3",featureStart:74, - * typeCategory:"Molecule processing",typeCode:"SO:0001064",evidenceCode:"no ECO", - * featureId:"UNIPROTKB_Q8LAX3_PEPTIDE_74_96", - * color: "#9B7057" - * } - * ]; - * - * OUTPUT (example) - * var json = { - * "featuresArray":[ - * { - * featureEnd:73, - * evidenceText:"UniProt",typeLabel:"Propeptide", - * featureLabel:"Propeptide",featureStart:1, - * typeCategory:"Molecule processing",typeCode:"SO:0001062",evidenceCode:"none, - * featureId:"UNIPROTKB_Q8LAX3_PROPEP_1_73", - * color: "#000000", - * type:"rect",fillOpacity:0.5 - * ,stroke:"#9B7057",height:10,path:"" - * ,strokeWidth:1,text:"" - * ,fill:"#9B7057",width:495 - * ,cy:56,cx:27 - * ,r:10 - * ,y:56,x:27 - * } - * ,{ - * featureEnd":96, - * evidenceText":"UniProt","typeLabel":"Peptide", - * featureLabel":"Elicitor peptide 3",featureStart:74, - * typeCategory":"Molecule processing",typeCode:"SO:0001064",evidenceCode:"no ECO" - * featureId":"UNIPROTKB_Q8LAX3_PEPTIDE_74_96", - * color": "#000000", - * type":"rect",fillOpacity:0.5 - * ,stroke":"#7DBAA4",height:10,path:"" - * ,strokeWidth":1,text:"" - * ,fill":"#7DBAA4",width:151 - * ,cy:56,cx:529 - * ,r:10, - * ,y:56,x:529 - * } - * ] - * ,"segment":"Q8LAx3" //same as sequenceId - * ,"legend":{ - * "segment":{"text":"Q8LAX3","yPos":106,"xPos":15} - * ,"key":[ - * { - * "label":{ - * "total":"1","text":"Peptide","yPos":126,"xPos":50 - * } - * ,"shape":{ - * "text":"" - * ,"width":30,"fill":"#7DBAA4" - * ,"cy":121,"cx":15,"type":"rect","fillOpacity":0.5,"stroke":"#7DBAA4","height":5,"r":10 - * ,"path":"","typeLabel":"Peptide","y":121 - * ,"strokeWidth":1,"x":15 - * } - * } - * ,{ - * "label":{ - * "total":"1","text":"Propeptide","yPos":126,"xPos":205 - * } - * ,"shape":{ - * "text":"" - * ,"width":30,"fill":"#9B7057" - * ,"cy":121,"cx":170,"type":"rect","fillOpacity":0.5,"stroke":"#9B7057","height":5,"r":10 - * ,"path":"","typeLabel":"Propeptide","y":121 - * ,"strokeWidth":1,"x":170 - * } - * } - * ] - * } - * ,"configuration":{ - * "requestedStop":96 //same as sequenceLength - * ,"requestedStart":1 //always 1 - * ,"rightMargin":20 //always 20 - * ,"belowRuler":30 //always 30 - * ,"sequenceLength":96 //same as sequenceLength - * ,"unitSize":6.875 //rulerLength/sequenceLength - * ,"style":"nonOverlapping" //always "nonOverlapping" - * ,"sequenceLineY":54 - * ,"verticalGrid":false //always false - * ,"rulerY":20 //always 20 - * ,"horizontalGrid":false //always false - * ,"pixelsDivision":50 //always 50 - * ,"sizeY":76 - * ,"sizeX":700 //same as imageWidth - * ,"aboveRuler":10 //always 10 - * ,"rulerLength":660 //imageWidth-rightMargin-leftMargin - * ,"sizeYKey":210 - * ,"leftMargin":20 //always 20 - * ,"nonOverlapping":true //always true - * } - * }; - */ - _generatesJSON: function() { - this.opt.json.segment = this.opt.sequenceId; - - this.opt.json = {}; - this.opt.json.configuration = {}; - this.opt.json.configuration.requestedStart = 1; - this.opt.json.configuration.requestedStop = this.opt.sequenceLength; - this.opt.json.configuration.sequenceLength = this.opt.sequenceLength; - this.opt.json.configuration.rightMargin = 20; - this.opt.json.configuration.leftMargin = 20; - this.opt.json.configuration.rulerLength = this.opt.imageWidth - this.opt.json.configuration.rightMargin - this.opt.json.configuration.leftMargin; - this.opt.json.configuration.belowRuler = 30; - this.opt.json.configuration.aboveRuler = 10; - this.opt.json.configuration.rulerY = 20; - this.opt.json.configuration.unitSize = this.opt.json.configuration.rulerLength / this.opt.sequenceLength; - this.opt.json.configuration.style = "nonOverlapping"; - this.opt.json.configuration.nonOverlapping = true; - this.opt.json.configuration.verticalGrid = false; - this.opt.json.configuration.horizontalGrid = false - this.opt.json.configuration.sizeX = this.opt.imageWidth; - this.opt.json.configuration.sequenceLineY = 4 + this.opt.json.configuration.rulerY + this.opt.json.configuration.belowRuler; - this.opt.json.configuration.pixelsDivision = 50; - - this._organizeTracks(this.opt.features); - if (this._trackShapes != 0) { - this.opt.json.configuration.sizeY = this.opt.json.configuration.sequenceLineY + (this._tracks+1)*(this._rectangleHeight+2) + this._rectangleHeight; - this.opt.json.configuration.sequenceLineY = this.opt.json.configuration.sequenceLineY + (this._trackShapes + 1)*this._rectangleHeight; - } else { - this.opt.json.configuration.sizeY = this.opt.json.configuration.sequenceLineY + this._tracks*(this._rectangleHeight+2) + this._rectangleHeight; - } - this._renderFeatures(this.opt.features); - this.opt.json.featuresArray = this.opt.features; - console.log(this.opt.json.featuresArray); - - sizeKey = this._generateLegend(this.opt.features); - this.opt.json.configuration.sizeYKey = sizeKey + this.opt.json.configuration.sizeY; - }, - - /* - * Organizes the features in non-overlapping tracks and defines the shape corresponding to each feature. - */ - _organizeTracks: function (features) { - tracks = new Array(); - trackShapes = new Array(); - //features[0].track = 0; - //tracks[0] = new Array(features[0]); - for (var i = 0; i < features.length; i++) { - //console.log('feature ' + i); - var tryShape = false; - var found = false; - if (features[i].type != undefined) { - if ( (features[i].type != "rect") && (features[i].type != "bridge") && (features[i].type != "circle") - && (features[i].type != "diamond") && (features[i].type != "hexagon") - && (features[i].type != "triangle") && (features[i].type != "wave")) { - features[i].type = "rect"; - } - if ( features[i].featureStart == features[i].featureEnd) { - if ((features[i].type != "rect") && (features[i].type != "bridge")) { - tryShape = true; - } - } - if (features[i].type == "bridge") { - features[i].track = 0; - continue; - } - } else { - features[i].type = "rect"; - } - if (!tryShape) { //rectangles - for (var j = 0; j < tracks.length; j++) { - var overlapping = false; - for (var m = 0; m < tracks[j].length; m++) { - if ( features[i].featureStart == features[i].featureEnd) { - if ( (features[i].featureStart < tracks[j][m].featureStart) - && (features[i].featureEnd < tracks[j][m].featureStart) ) { //starts and ends before - overlapping = false; - } else if (features[i].featureStart > tracks[j][m].featureEnd) { //starts after - overlapping = false; - } else { - overlapping = true; - break; - } - } else { - if ( (features[i].featureStart < tracks[j][m].featureStart) //starts and ends before - && (features[i].featureEnd <= tracks[j][m].featureStart) ){ - overlapping = false; - } else if ( (features[i].featureStart >= tracks[j][m].featureEnd) - && (features[i].featureEnd > tracks[j][m].featureStart )) { - overlapping = false; - } else { - overlapping = true; - break; - } - } - } - if (!overlapping) { - //console.log('tracks j ' + j); - features[i].track = j; - tracks[j][tracks[j].length] = features[i]; - found = true; - break; - } - } - if (!found) { - //console.log('tracks.length ' + tracks.length); - features[i].track = tracks.length; - tracks[tracks.length] = new Array(features[i]); - } - } else { //shapes - for (var j = 0; j < trackShapes.length; j++) { - var overlapping = false; - for (var m = 0; m < trackShapes[j].length; m++) { - if ( features[i].featureStart == features[i].featureEnd) { - if ( ((features[i].featureStart-3) < trackShapes[j][m].featureStart) - && ((features[i].featureEnd+3) < trackShapes[j][m].featureStart) ) { //starts and ends before - overlapping = false; - } else if ((features[i].featureStart-3) > trackShapes[j][m].featureEnd) { //starts after - overlapping = false; - } else { - overlapping = true; - break; - } - } - } - if (!overlapping) { - //console.log('tracks j ' + j); - features[i].track = j; - trackShapes[j][trackShapes[j].length] = features[i]; - found = true; - break; - } - } - if (!found) { - //console.log('tracks.length ' + tracks.length); - features[i].track = trackShapes.length; - trackShapes[trackShapes.length] = new Array(features[i]); - } - } - } - this._tracks = tracks.length + trackShapes.length; - this._trackRects = tracks.length; - this._trackShapes = trackShapes.length; - }, - - /* - * Adds SVG information to the features - * - * OUTPUT (example of one feature with position, shape, and color) - * "featureEnd":73, - * "evidenceText":"UniProt","typeLabel":"Propeptide", - * "featureLabel":"Propeptide","featureStart":1, - * "typeCategory":"Molecule processing","typeCode":"SO:0001062","evidenceCode":"", - * "featureId":"UNIPROTKB_Q8LAX3_PROPEP_1_73", - * "featureTypeLabel":"propeptide", - * "color": "#000000", - * "type":"rect","fillOpacity":0.5 - * ,"stroke":"#9B7057","height":10,"path":"" - * ,"strokeWidth":1,"text":"" - * ,"fill":"#9B7057","width":495 - * ,"cy":56,"cx":27 - * ,"r":10 - * ,"y":56,"x":27 - */ - _renderFeatures: function(features) { - for (i=0; i < features.length; i++) { - if (features[i].type == undefined) { - features[i].type = "rect"; - } - if (features[i].color == undefined) { - features[i].color = "black"; - } - features[i].fillOpacity = 0.5; - features[i].path = ""; - features[i].text = ""; - features[i].fill = features[i].color; - features[i].stroke = features[i].color; - features[i].strokeWidth = 1; - features[i].width = this.opt.json.configuration.unitSize * (features[i].featureEnd - features[i].featureStart + 1); - if (features[i].type == "rect") { - features[i].height = this._rectangleHeight; - features[i].cy = this.opt.json.configuration.sequenceLineY + features[i].track * (this._rectangleHeight) + (features[i].track+1)*2; - } else if (features[i].type == "bridge") { - features[i].height = this._rectangleHeight; - features[i].cy = this.opt.json.configuration.sequenceLineY; - } else { - features[i].cy = this.opt.json.configuration.sequenceLineY - (features[i].track+2) * (this._rectangleHeight)// + (features[i].track+1)*2 -20; - if (features[i].type == "triangle") { - features[i].height = 10; - } else if (features[i].type == "hexagon") { - features[i].height = 7; - } else { - features[i].height = 5; - } - } - features[i].r = features[i].height; - features[i].cx = this.opt.json.configuration.unitSize * (features[i].featureStart-1) + this.opt.json.configuration.leftMargin; - features[i].x = features[i].cx; - features[i].y = features[i].cy; - } - }, - - /* - * Generates the legend. - * { - "segment":{"text":"Q8LAX3","yPos":106,"xPos":15} - ,"key":[ - { - "label":{ - "total":"1","text":"Peptide","yPos":126,"xPos":50 - } - ,"shape":{ - "text":"" - ,"width":30,"fill":"#7DBAA4" - ,"cy":121,"cx":15,"type":"rect","fillOpacity":0.5,"stroke":"#7DBAA4","height":5,"r":10 - ,"path":"","typeLabel":"Peptide","y":121 - ,"strokeWidth":1,"x":15 - } - } - ,{ - "label":{ - "total":"1","text":"Propeptide","yPos":126,"xPos":205 - } - ,"shape":{ - "text":"" - ,"width":30,"fill":"#9B7057" - ,"cy":121,"cx":170,"type":"rect","fillOpacity":0.5,"stroke":"#9B7057","height":5,"r":10 - ,"path":"","typeLabel":"Propeptide","y":121 - ,"strokeWidth":1,"x":170 - } - } - ] - } - */ - _generateLegend: function(features) { - mykey = []; - for (i=0; i < features.length; i++) { - found = false; - for (j=0; j < mykey.length; j++) { - if (features[i].typeLabel == mykey[j].label.text) { - mykey[j].label.total = mykey[j].label.total + 1; - mykey[j].label.text = mykey[j].label.text;// + "(" + mykey[j].label.total + ")"; - found = true; - break; - } - } - if (!found) { - mykey[mykey.length] = {}; - mykey[mykey.length-1].label = {}; //later yPos, xPos - mykey[mykey.length-1].label.total = 1; - mykey[mykey.length-1].label.text = features[i].typeLabel; - mykey[mykey.length-1].shape = {}; //later cy, cx, y, x - mykey[mykey.length-1].shape.text = ""; - mykey[mykey.length-1].shape.width = 30; - mykey[mykey.length-1].shape.fill = features[i].fill; - mykey[mykey.length-1].shape.type = "rect"; - mykey[mykey.length-1].shape.fillOpacity = 0.5; - mykey[mykey.length-1].shape.stroke = features[i].stroke; - mykey[mykey.length-1].shape.height = 5; - mykey[mykey.length-1].shape.r = this._rectangleHeight; - mykey[mykey.length-1].shape.path = ""; - mykey[mykey.length-1].shape.typeLabel = features[i].typeLabel; - mykey[mykey.length-1].shape.strokeWidth = 1; - } - } - - this.opt.json.legend = {}; - yCell = this.opt.json.configuration.sizeY + this.opt.json.configuration.belowRuler; - cellWidth = 200; - cellsByRow = this.opt.json.configuration.sizeX / cellWidth; - cellHeight = 20; - - this.opt.json.legend.segment = {}; - this.opt.json.legend.segment.text = this.opt.sequenceId; - this.opt.json.legend.segment.yPos = yCell; - this.opt.json.legend.segment.xPos = this.opt.json.configuration.leftMargin; - - yCell = yCell + cellHeight; - cell = 0; - totalRows = 1; - for (i=0; i < mykey.length; i++) { - xPos = 0; - if (cell == 0) { - xPos = this.opt.json.configuration.leftMargin; - } else { - xPos = cell * cellWidth; - } - mykey[i].label.yPos = yCell; - mykey[i].label.xPos = xPos + cellHeight + 15; - mykey[i].shape.y = yCell; - mykey[i].shape.cy = yCell; - mykey[i].shape.x = xPos; - mykey[i].shape.cx = xPos; - if (mykey[i].label.text.length > 21) { - cell = Math.min(cell+2, cellsByRow); - } else { - cell = Math.min(cell+1, cellsByRow); - } - if (cell == cellsByRow) { - yCell = yCell + cellHeight; - cell = 0; - totalRows++; - } - } - - this.opt.json.legend.key = mykey; - return ((totalRows+1) * cellHeight); - } - } -); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Table.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Table.js deleted file mode 100755 index 9023d2e696..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Table.js +++ /dev/null @@ -1,899 +0,0 @@ -/** - * Table. - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 1 - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires DataTables Plugin - * @dependency - * - * @requires jQuery UI 1.8.2+ - * @dependency - * - * @requires MultiSelect Plugin - * @dependency - * - * @dependency - * @dependency - * - * @param {Object} options - * An object with the options for HelloWorld component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string[][]|Object} dataSet - * Either 2D string array containing the whole data to be displayed or a plain object defining the data source. - * - *
              - *    {
              - * 		url: <url>,
              - * 		proxyUrl: <proxy>,
              - * 		paramsMap: { "iDisplayStart": <newName1>, "iDisplayLength": <newName2>, ... },
              - * 		filter: <flag>
              - *    }
              - *    
              - * where: - *
                - *
              • url is string containing the url data source.
              • - *
              • paramsMap Customize the name of the following params which will be passed to server: - *
                  - *
                • iDisplayStart: index of the first expected record for paging.
                • - *
                • iDisplayLength: size of the fetched data (page size).
                • - *
                • sSearch: filter string entered by the user in case of filter is enabled.
                • - *
                - *
              • - *
              • filter is a boolean to show/hide the search box on the table top. - * The entered string will be passed to the server by means of 'sSearch' parameter. - * Personalize the parameter name using paramsMap.
              • - *
              • proxyUrl optional string containing the url of the proxy in case of needing access to server through a proxy.
              • - *
              - * - *
              - *    {
              - * 		url: 'http://www.ebi.ac.uk/Tools/webservices/psicquic/intact/webservices/current/search/query/species:human',
              - * 		paramsMap: { "iDisplayStart": "firstResult", "iDisplayLength": "maxResults" },
              - * 		filter: false
              - *    }
              - *    
              - * - *
              - *    [
              - *		[ 1, "chi", "China", 1347350000, "December 31, 2011", "0.1925" ],
              - *		[ 2, "ind", "India", 1210193422, "March 1, 2011", "0.1729" ],
              - *		[ 3, "usa", "United States", 313149000, "March 9, 2012", "0.0447" ],
              - *		[ 4, "ino", "Indonesia", 237641326, "May 1, 2010", "0.034" ],
              - * 		[ 5, "bra", "Brazil", 192376496, "July 1, 2011", "0.0275" ],
              - * 		[ 6, "pak", "Pakistan", 178945000, "March 9, 2012", "0.0256" ],
              - * 		[ 7, "nig", "Nigeria", 162471000, "July 1, 2011", "0.0232" ],
              - * 		[ 8, "rus", "Russia", 143030106, "January 1, 2012", "0.0204" ],
              - * 		[ 9, "ban", "Bangladesh", 142319000, "March 15, 2011", "0.0203" ],
              - * 		[ 10, "jap", "Japan", 127770000, "February 1, 2012", "0.0183" ],
              - * 		[ 11, "mex", "Mexico", 112336538, "June 12, 2010", "0.016" ],
              - * 		[ 12, "phi", "Philippines", 94013200, "July 1, 2010", "0.0134" ],
              - * 		[ 13, "vie", "Vietnam", 87840000, "December 31, 2011", "0.0125" ],
              - * 		[ 14, "eth", "Ethiopia", 84320987,	"July 1, 2012", "0.012" ],
              - * 		[ 15, "ger", "Germany", 81796000, "August 31, 2011", "0.0117" ]
              - *    ]
              - *    
              - * - * @option {(string|Object)[]} columns - *

              Array containing the column descriptors. A descriptor can be either a string or an object. - * Use a string to define column name only. Use an object to define column name, rendering function and fixed width. - *

              - *
              - *    {
              - * 		name: <string>,
              - * 		render: <function>,
              - * 		width: <string>
              - *    }
              - *    
              - * where: - *
                - *
              • name will be used for the column title, and 'render'.
              • - *
              • render is a function to format each row value in that column. - *
                Returns a string containing the new formatted value. - *
                Arguments: - *
                  - *
                • col: index of the column.
                • - *
                • dataRow: 1D array containing whole row.
                • - *
                • value: current value of the cell.
                • - *
                - *
              • - *
                - *       	// Formats a decimal value in a percentage value. 
                - *    		var numberToPercentageFormat = function (col, dataRow, value) {
                - *		  		return ( new Number(value) * 100 ).toFixed(2) + "%";
                - * 			};
                - * 		  
                - *
              • width of the column using either pixels or percentage.
              • - *
              - *
              - *    // Three columns: Identifier, Name and Location. 
              - *    // Custom rendering function will apply bold to Identifier values.
              - *    columns: [
              - *		"Name",
              - * 		"Location",
              - *		{ name: "Population %", render: numberToPercentageFormat }
              - *    ]
              - *    
              - * - * @option {int[]} [hideColumns=[]] - * Indexes (0-based) of the columns to be hided. - * - * @option {array[][int,string]} [orderBy=[]] - * A 2D array to tell how to order the columns. Each 1D array must contains both column index and ordering direction. - * - *
              - *    // order column 0 in ascending direction and column 3 in descending direction
              - *    orderBy: [ [0,'asc'], [3,'desc'] ]
              - *    
              - * - * @option {int} [pageLength=10] - * Number of rows per page. - * - * @option {bool} [rowSelection=true] - * Show/hide the first check boxes column used for selecting rows. - * - * @option {bool} [paginate=true] - * Enable/disable the pagination, so whole the data will be displayed. - * - * @option {int} [width=597] - * Horizontal size of the general container. - * - * @option {int} [height=400] - * Vertical size of the general container. - * - * @example - * // Adds a flag to the cell value. - * var flagRender = function (col, dataRow, value) { - * return ' ' + value; - * }; - * - * // Formats a decimal value in a percentage value. - * var numberToPercentageFormat = function (col, dataRow, value) { - * return ( new Number(value) * 100 ).toFixed(2) + "%"; - * }; - * - * // Example of instantiation of the Table - * var myTable = new Biojs.Table({ - * target: "YourOwnDivId", - * hideColumns: [1], - * orderBy: [ [0,'asc'], [3,'desc'] ], - * columns: [ - * "Rank", - * "Flag", - * { name: "Country", render: flagRender }, - * "Population", - * "Date", - * { name:"% World Population", render: numberToPercentageFormat } - * ], - * dataSet: [ - * [ 1, "chi", "China", 1347350000, "December 31, 2011", "0.1925" ], - * [ 2, "ind", "India", 1210193422, "March 1, 2011", "0.1729" ], - * [ 3, "usa", "United States", 313149000, "March 9, 2012", "0.0447" ], - * [ 4, "ino", "Indonesia", 237641326, "May 1, 2010", "0.034" ], - * [ 5, "bra", "Brazil", 192376496, "July 1, 2011", "0.0275" ], - * [ 6, "pak", "Pakistan", 178945000, "March 9, 2012", "0.0256" ], - * [ 7, "nig", "Nigeria", 162471000, "July 1, 2011", "0.0232" ], - * [ 8, "rus", "Russia", 143030106, "January 1, 2012", "0.0204" ], - * [ 9, "ban", "Bangladesh", 142319000, "March 15, 2011", "0.0203" ], - * [ 10, "jap", "Japan", 127770000, "February 1, 2012", "0.0183" ], - * [ 11, "mex", "Mexico", 112336538, "June 12, 2010", "0.016" ], - * [ 12, "phi", "Philippines", 94013200, "July 1, 2010", "0.0134" ], - * [ 13, "vie", "Vietnam", 87840000, "December 31, 2011", "0.0125" ], - * [ 14, "eth", "Ethiopia", 84320987, "July 1, 2012", "0.012" ], - * [ 15, "ger", "Germany", 81796000, "August 31, 2011", "0.0117" ] - * ] - * - * }); - */ -Biojs.Table = Biojs.extend ( -/** @lends Biojs.Table# */ -{ - constructor: function (options) { - var self = this; - - //Biojs.console.enable(); - - // TODO: validate mandatory values - - self._tableId = 'biojs_Table_'+self.getId(); - self._tableSelector = '#'+self._tableId; - self._topControls = jQuery('
              ').appendTo("#"+self.opt.target); - self._body = jQuery('
              ').appendTo("#"+self.opt.target); - self._table = jQuery('
              ').appendTo(self._body); - self._columnsOffset = (this.opt.rowSelection)? 1 : 0; - - self._settings = {}; - self._settings.opt = this.opt; - - self._initSettings(self._settings); - self.setDataSource(self.opt.dataSet); - self._addEvents(); - - Biojs.console.log("Biojs.Table constructor has finished"); - }, - - /** - * Default values for the options - * @name Biojs.Table-opt - */ - opt: { - target: "YourOwnDivId", - hideColumns: [], - columns: [""], - dataSet: [], - paginate: true, - pageLength: 10, - width: 597, - height: 400, - rowSelection: true, - orderBy: [] - //mapUrlParams: function ( params ) { ; } - }, - - /** - * Array containing the supported event names - * @name Biojs.Table-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.Table#onCellClicked - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {int} rowIndex Row selected (0-based index). - * @eventData {int} colIndex Column number (0-based index). - * @eventData {HTMLTableCellElement} cell Instance of the DOM HTMLTableCellElement selected. - * @example - * myTable.onCellClicked( - * function( e ) { - * alert("Cell selected in row "+ e.rowIndex +", column " + e.colIndex + ". Value: " + e.cell.innerText ); - * } - * ); - * - **/ - "onCellClicked", - - /** - * @name Biojs.Table#onRowSelected - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {int} rowIndex Row selected (0-based index). - * @eventData {HTMLTableRowElement} row Instance of the DOM HTMLTableRowElement selected. - * @example - * myTable.onRowSelected( - * function( e ) { - * alert("Row selected: "+ e.rowIndex ); - * } - * ); - * - **/ - "onRowSelected", - - /** - * @name Biojs.Table#onHeaderClicked - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {string} colName Column name. - * @eventData {int} colIndex Column number (0-based index). - * @example - * myTable.onHeaderClicked( - * function( e ) { - * alert("Header \""+ e.colName +"\" selected. Column index " + e.colIndex + ". " ); - * } - * ); - * - **/ - "onHeaderClicked", - - /** - * @name Biojs.Table#onDataArrived - * @event - * @param {function} actionPerformed A function which receives a {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which triggered the event. - * @eventData {Object} jsonData Data object just arrived. - * @example - * myTable.onDataArrived( - * function( e ) { - * alert( e.jsonData.aaData.length + " new records has arrived." ); - * } - * ); - * - **/ - "onDataArrived"], - - /** - * Rebuild the table - * - * @example - * myTable.setDataSource({ - * url: 'data/tableJSON.js' - * }); - * - */ - setDataSource: function ( dataSet ) { - - this.opt.dataSet = dataSet; - - if ( dataSet instanceof Array ) { - this._initSettingsForLocalData(this._settings); - } else { - this._initSettingsForRemoteData(this._settings); - } - - Biojs.console.log("Drawing.."); - this._settings.bDestroy = true; - this._table.dataTable( this._settings ); - this._setColumnSelector( this._table.fnSettings() ); - }, - - /** - * Shows the columns indicated by the indexes array. - * @param {int[]} columns Column indexes to be showed. - * @param {bool} flag The new value. - * - * @example - * myTable.toggleColumns([0,3],true); - * - */ - toggleColumns: function (columns, flag) { - Biojs.console.log("Toggle columns to :"+ flag ); - Biojs.console.log(columns); - - var checkbox = jQuery('input[name="multiselect_' + this._tableId + '_columns"]'); - - for ( i=0; i < columns.length; i++ ) { - toToggle = jQuery(checkbox[ columns[i] ]); - if ( toToggle.attr("checked") != flag ) { - toToggle.click(); - } - this._table.fnSetColumnVis( columns[i] + this._columnsOffset, flag ); - } - }, - - /** - * Shows the columns indicated by the indexes array. - * @param {int[]} columns Column indexes to be showed. - * - * @example - * myTable.showColumns([0,3]); - * - */ - showColumns: function(columns){ - Biojs.console.log("Showing columns:"); - Biojs.console.log(columns); - - this.toggleColumns(columns,true); - }, - - /** - * Hides the columns indicated by the indexes array. - * @param {int[]} columns Column indexes to be hided. - * - * @example - * myTable.hideColumns([0,3]); - * - */ - hideColumns: function(columns){ - Biojs.console.log("Hiding columns:"); - Biojs.console.log(columns); - - this.toggleColumns(columns,false); - }, - - /** - * Sorts by column. - * @param {int} columnIndex Column indexes to be sorted (0-based index). - * @param {string} direction Sorting direction; 'asc' for ascending, 'desc' for descending. - * - * @example - * myTable.orderBy(1,'desc'); - * - */ - orderBy: function (columnIndex, direction) { - this._table.fnSort( [ [columnIndex + this._columnsOffset, direction] ] ); - }, - - /** - * Gets the current selected data. - * - * @returns {string[][]} data current selection. - * - * @example - * myTable.getSelectedRows(); - * - */ - getSelectedRows: function(){ - var self = this; - var selectedRows = []; - - jQuery(self._tableSelector + ' tr.selected') - .each(function(index, e) { - selectedRows.push(self._table.fnGetData(e)); - }); - - Biojs.console.log(selectedRows) - return selectedRows; - }, - - /* - * Function: Biojs.Table._initSettings - * Purpose: initialize the settings for DataTables plugin in case of using local data - * Returns: - - * Inputs: settings -> {Object} where the configuration settings will be added. - */ - _initSettings: function( settings ) { - Biojs.console.log("initializing settings..."); - - settings.aoColumnDefs = []; - - this._setColumns(this.opt.columns, settings); - //this._setData(this.opt.dataSet, settings); - - // Hide columns - if ( this.opt.hideColumns.length > 0 ) { - settings.aoColumnDefs.push( { "bVisible": false, "aTargets": this.opt.hideColumns } ); - } - - // Order by - if ( this.opt.orderBy.length > 0 ) { - settings.aaSorting = this.opt.orderBy; - } - - // Row selection column (checkboxes column) is enabled? - if (this.opt.rowSelection) { - var columnsToHide = settings.aoColumnDefs[0].aTargets; - - // Shift the index of the columns to hide - for ( i in columnsToHide ) { - columnsToHide[i] += 1; - } - - // Shift the index of the columns to order - for ( i in settings.aaSorting ) { - settings.aaSorting[i][0] += 1; - } - - // Disable the ordering on the column 0 (checkboxes column) - settings.aoColumnDefs.push( { "bSortable": false, "aTargets": [ 0 ] } ); - } - - // pagination - if ( !this.opt.paginate ) { - settings.bScrollInfinite = true; - settings.bScrollCollapse = true; - - } else { - settings.sPaginationType = "full_numbers"; - settings.iDisplayLength = this.opt.pageLength; - settings.oLanguage = { - "oPaginate": { - "sPrevious": "<", - "sNext": ">", - "sFirst": "|", - "sLast": "|" - } - }; - } - settings.bProcessing = true; - settings.bLengthChange = false; - settings.sScrollX = this.opt.height; - settings.sScrollY = "100%"; - }, - - /* - * Function: Biojs.Table._initSettingsForLocalData - * Purpose: initialize the settings for DataTables plugin in case of using local data - * Returns: - - * Inputs: settings -> {Object} where the configuration settings will be added. - */ - _initSettingsForLocalData: function( settings ) { - Biojs.console.log("Using local data"); - this._setData(this.opt.dataSet, settings);; - // Don't use data source provided by a server - settings.bServerSide = false; - // Set URL of the data source - settings.sAjaxSource = null; - // Set the function which manages the Ajax requests - settings.fnServerData = null; - // Enable filtering - settings.bFilter = true; - }, - - /* - * Function: Biojs.Table._initSettingsForRemoteData - * Purpose: initialize the settings for DataTables plugin in case of using remote data - * Returns: - - * Inputs: settings -> {Object} where the configuration settings will be added. - */ - _initSettingsForRemoteData: function(settings) { - - Biojs.console.log("Using data from remote URL: "+ this.opt.dataSet.url); - - // Use data source provided by a server - settings.bServerSide = true; - // Set URL of the data source - settings.sAjaxSource = this.opt.dataSet.url; - // Set the function which manages the Ajax requests - settings.fnServerData = this._fetchData; - // Enable/disable filtering depending on the support by the server - settings.bFilter = this.opt.dataSet.filter; - }, - - /* - * Function: _fetchData - * Purpose: do the Ajax request to get the data from server. Note that 'this' will not refered to the Biojs.Table instance - * due to this function will be linked to the internal DataTables object. - * Returns: - - * Inputs: - * sSource -> {string} HTTP source to obtain the data from (defined in option dataSet.url). - * aoData -> {Object[]} a key/value pair object containing the data to send to the server. - * fnCallback -> {function} to be called on completion of the data get process that will draw the data on the page. - * oSettings -> {object} DataTables settings object. - */ - _fetchData: function ( sSource, aoData, fnCallback, oSettings ) { - - var httpRequest = { url: sSource }; - var params = aoData; - - // Get the Biojs Table instance - var biojsId = oSettings.sTableId.substr( "biojs_Table_".length ); - var instance = Biojs.getInstance(biojsId); - - // Rename param names using those defined in the options instance.opt.dataSet.mapParams - instance._mapUrlParams(aoData); - - // Set callback function on success - //httpRequest.success = fnCallback; - - // Data type expected - httpRequest.dataType = 'json'; - - // Using proxy? - // Redirect using the proxy and encode all params as url data - if ( instance.getProxy() != undefined ) { - - // Redirect to proxy url - httpRequest.url = instance.getProxy(); - - // Encode both url and parameters under the param url - params = [{ name: "url", value: sSource + '?' + jQuery.param(aoData) }]; - - // Data type - httpRequest.dataType = instance.getProxyDataType(); - - } - - // Wrap the callback function - httpRequest.success = - /** - * @ignore - **/ - function ( data ) { - - // Decode data - jsonData = instance._decodeToJSON( data ); - - // Set the echo var - jsonData.sEcho = this.sEcho; - - // Add the column of checkboxes in case of using row selection - instance._setSelectionColumn( jsonData ); - - // Call the datatables cb function - fnCallback( jsonData ); - - // fire event - instance.raiseEvent( Biojs.Table.EVT_ON_DATA_ARRIVED, { - "jsonData": jsonData - }); - } - - httpRequest.type = 'GET'; - httpRequest.data = params; - httpRequest.sEcho = aoData[0].value; - - jQuery.ajax( httpRequest ); - }, - - getProxy: function() { - return this.opt.dataSet.proxyUrl; - }, - - getProxyDataType: function() { - return this.opt.dataSet.dataType | "text"; - }, - - /** - * Returns the total records in the dataset. - * - * @example - * alert("Total records:" + myTable.getTotalRecords()); - * - */ - getTotalRecords: function() { - return this.opt.dataSet.totalRecords; - }, - - _setSelectionColumn: function( jsonData ) { - if ( this.opt.rowSelection && jsonData.aaData instanceof Array ) { - for ( i = 0; i < jsonData.aaData.length; i++ ){ - jsonData.aaData[i].unshift(''); - } - } - }, - - /* - * Function: Biojs.Table._decodeToJSON - * Purpose: Decode the received data to suit it into the expected JSON format. - * Override this method in the Biojs.Table's children to suit any raw data into the expected JSON format. - * Returns: {Object} formatted in the expected JSON format. - * Inputs: data -> {*} raw data received from the server. - */ - _decodeToJSON: function ( data ) { - var jsonData = data; - - if ( Biojs.Utils.isEmpty(data) ) { - Biojs.console.log("Empty data was received"); - - } else if ( !(jsonData instanceof Object) || !(jsonData.aaData instanceof Array) ) { - jsonData = {}; - jsonData.aaData = []; - jsonData.iTotalRecords = 0; - jsonData.iTotalDisplayRecords = 0; - Biojs.console.log("Error: data with unknown format was detected."); - } - - Biojs.console.log(jsonData); - return jsonData; - }, - - /* - * Function: Biojs.Table._mapUrlParams - * Purpose: Rename the param names with the customized names declared in the option dataSet.paramsMap - * Returns: - - * Inputs: {Object[]} a key/value pair object containing the data to send to the server. - */ - _mapUrlParams: function ( params ) { - var map = this.opt.dataSet.paramsMap; - for ( key in map ) { - for ( i = 0; i < params.length; i++) { - // rename the parameter name - if ( params[i].name == key ) { - Biojs.console.log("Renaming param <" + key + "> with <" + map[key] + ">" ); - params[i].name = map[key]; - } - } - } - }, - - /* - * Function: Biojs.Table._setColumnSelector - * Purpose: Build the drop down box to hide/show columns by means of the user selection. - * Returns: - - * Inputs: oSettings -> {Object} DataTables settings object. - */ - _setColumnSelector: function( settings ){ - - var self = this; - var columns = settings.aoColumns; - var select = jQuery(''); - } - this._table.fnAddData(row); - }, - - /** - * Add a single new row or multiple rows of data to the table. - * @param {array} data 1D array of data - add a single row with the data provided - * - * @example - * myTable.removeDataRow(2); - * - */ - removeDataRow: function(i){ - this._table.fnDeleteRow(i) - }, - - /* - * Function: Biojs.Table._setColumns - * Purpose: Map the columns values defined in the option 'columns' to the columns values for DataTables plugin - * Returns: - - * Inputs: - * columns -> {(string|Object)[]} columns in the format defined in the option 'columns'. - * oSettings -> {Object} DataTables settings object. - */ - _setColumns: function ( columns, oSettings ) { - var self = this; - var result = []; - - // Add a column of checkbox for selection - if (this.opt.rowSelection) { - columns.splice(0, 0, { "name": '' } ); - } - - for ( j in columns ) { - if ( typeof columns[j] == "string" ) { - result[j] = { "sTitle": columns[j] }; - } else { - result[j] = { "sTitle": columns[j].name }; - if ( columns[j].render && typeof columns[j].render == "function") { - result[j].fnRender = function ( o, value ) { - return columns[o.iDataColumn].render(o.iDataColumn, o.aData, value); - } - } - if ( columns[j].width && typeof columns[j].width == "string") { - result[j].sWidth = columns[j].width; - } - } - } - oSettings.aoColumns = result; - }, - - /* - * Function: Biojs.Table._setData - * Purpose: Set the data in case of using local data to initialize the Biojs.Table instance. - * Returns: - - * Inputs: - * data -> {string[][]} data to be displayed. - * oSettings -> {Object} DataTables settings object. - */ - _setData: function ( data, oSettings ) { - - // Check if row selection is currently activated. - if (this.opt.rowSelection) { - // Adds a column for a checkbox for each row - for ( r in data ) { - data[r].splice(0, 0, ''); - } - } - // Set the data in DataTables object. - oSettings.aaData = data; - }, - - _showEmptyMessage: function(){ - this._body.html("Empty"); - }, - - /* - * Function: Biojs.Table._addEvents - * Purpose: initialize the event triggers for the clicks on the Biojs.Table - * Returns: - - * Inputs: - - */ - _addEvents: function(){ - var self = this; - - // Cell clicked - jQuery(this._tableSelector) - .click( function (eventData) { - var cell = eventData.target; - - while (cell.tagName != "TD" ) { - cell = cell.parentNode; - } - - var column = new Number(cell.cellIndex); - var row = new Number(cell.parentNode.rowIndex-1); - - if ( self.opt.rowSelection && column == 0 ) { - if( cell.children[0].checked ) { - jQuery(cell).parent().addClass('selected'); - self.raiseEvent( Biojs.Table.EVT_ON_ROW_SELECTED , { - rowIndex: row, - row: jQuery(cell).parent() - }); - } else { - jQuery(cell).parent().removeClass('selected'); - } - } else { - self.raiseEvent( Biojs.Table.EVT_ON_CELL_CLICKED, { - "cell": cell, - "rowIndex": row, - "colIndex": column - }); - } - Biojs.console.log(eventData); - }); - - // Header clicked - jQuery(self._tableSelector+'_wrapper table.dataTable thead tr th') - .click( function (eventData) { - var cell = eventData.currentTarget; - var column = cell.cellIndex; - - if ( self.opt.rowSelection && column == 0 ) { - if( cell.children[0].checked ) { - jQuery(self._tableSelector + ' tr').addClass('selected'); - jQuery(self._tableSelector + ' tr td input').attr('checked',true); - } else { - jQuery(self._tableSelector + ' tr').removeClass('selected'); - jQuery(self._tableSelector + ' tr td input').attr('checked',false); - } - } else { - self.raiseEvent( Biojs.Table.EVT_ON_HEADER_CLICKED, { - "colName": cell.innerHTML, - "colIndex": column - }); - } - - Biojs.console.log(eventData); - }); - } - - - - //TODO: Render functions to format used data types: date, number, ... - -}, -/** @static */ -/** @lends Biojs.Table */ -{ - // Indexes to access the event name in this.eventTypes array - EVT_ON_CELL_CLICKED: "onCellClicked", - EVT_ON_ROW_SELECTED: "onRowSelected", - EVT_ON_HEADER_CLICKED: "onHeaderClicked", - EVT_ON_DATA_ARRIVED: "onDataArrived" -} - - -); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Tooltip.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Tooltip.js deleted file mode 100755 index 194d3469b4..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Tooltip.js +++ /dev/null @@ -1,535 +0,0 @@ -/** - * Tooltip for general purpose. - * - * @class - * @extends Biojs - * - * @author John Gomez - * @version 1.0.0 - * @category 1 - * - * @requires Tooltip CSS - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @param {Object} options - * An object with the options for Article component. - * - * @param {string} targetSelector - * A selector string to match the elements in the document. For more - * information on it, see jQuery selectors. - * - *
              - *       // Select all the links 
              - *       targetSelector: "a"
              - *       
              - *       // Select the element with the id 'target'
              - *       targetSelector: "#target"
              - *       
              - *       // Select all elements whose belong to the class 'here'
              - *       targetSelector: ".here"
              - *       
              - *       // Select all list elements whose belong to the class 'here'
              - *       targetSelector: "li.here"
              - *    
              - * - * @param {function} [cbRender] - * By default, BiojsTooltip uses the 'title' attribute to render the content. - * Set this option to customize the content rendering instead of using the default value. - * - *
              - *      cbRender: function( element ) {
              - *         return "This is my personalized content for element " + element.tagName;
              - *      }
              - *    
              - * - * @param {static} [arrowType=Biojs.Tooltip.ARROW_LEFT_TOP] - * Automatic positioning of the tooltip depends on the arrow direction. - * Possible arrow types are: - *
                - *
              • Biojs.Tooltip.ARROW_LEFT_TOP
              • - *
              • Biojs.Tooltip.ARROW_LEFT_MIDDLE
              • - *
              • Biojs.Tooltip.ARROW_LEFT_BOTTOM
              • - *
              • Biojs.Tooltip.ARROW_TOP_LEFT
              • - *
              • Biojs.Tooltip.ARROW_TOP_MIDDLE
              • - *
              • Biojs.Tooltip.ARROW_TOP_RIGHT
              • - *
              • Biojs.Tooltip.ARROW_RIGHT_TOP
              • - *
              • Biojs.Tooltip.ARROW_RIGHT_MIDDLE
              • - *
              • Biojs.Tooltip.ARROW_RIGHT_BOTTOM
              • - *
              • Biojs.Tooltip.ARROW_BOTTOM_LEFT
              • - *
              • Biojs.Tooltip.ARROW_BOTTOM_MIDDLE
              • - *
              • Biojs.Tooltip.ARROW_BOTTOM_RIGHT
              • - *
                  - * - * @param {static} [position=Biojs.Tooltip.ELEMENT_POSITION] - * Position is calculated through either mouse position or element position. - * Allowed values are: Biojs.Tooltip.ELEMENT_POSITION or Biojs.Tooltip.MOUSE_POSITION - * - * @param {int} [delay=200] - * Time interval in milliseconds starting on mouse exiting from element/Tooltip until the Tooltip hides itself. - * - * @example - * // These examples use the component's example div 'YourOwnDivId' to draw the links only. - * jQuery('#YourOwnDivId') - * .append('Pass the mouse over here.') - * .css({ - * 'display': 'table-cell', - * 'vertical-align': 'middle', - * 'text-align': 'center', - * 'width': '730px', - * 'height': '400px' - * }); - * - * // Tooltip will come out whenever mouse enter to any anchor 'a' with class 'example' - * var simpleTip = new Biojs.Tooltip({ - * targetSelector: "a.example" - * }); - * - * // - * // Another example using rendering function instead of 'title' attribute - * // - * jQuery('#YourOwnDivId') - * .append('



                  This example change the tooltip direction
                  for each mouse entry.
                  '); - * - * // Tooltip will come out whenever mouse enter to any anchor 'a' with class 'example' - * var tipRendered = new Biojs.Tooltip({ - * targetSelector: "a.example.render", - * cbRender: function( element ) { - * return "Tooltip type Biojs.Tooltip.ARROW_" + this.getArrowType().toUpperCase() + " using rendering function to build up content dynamically" - * } - * }); - * - * // Changes the tooltip's direction - * var counter = 0; - * var arrowTypes = [ - * Biojs.Tooltip.ARROW_LEFT_TOP, - * Biojs.Tooltip.ARROW_LEFT_MIDDLE, - * Biojs.Tooltip.ARROW_LEFT_BOTTOM, - * Biojs.Tooltip.ARROW_TOP_LEFT, - * Biojs.Tooltip.ARROW_TOP_MIDDLE, - * Biojs.Tooltip.ARROW_TOP_RIGHT, - * Biojs.Tooltip.ARROW_RIGHT_TOP, - * Biojs.Tooltip.ARROW_RIGHT_MIDDLE, - * Biojs.Tooltip.ARROW_RIGHT_BOTTOM, - * Biojs.Tooltip.ARROW_BOTTOM_LEFT, - * Biojs.Tooltip.ARROW_BOTTOM_MIDDLE, - * Biojs.Tooltip.ARROW_BOTTOM_RIGHT - * ]; - * - * // Changes the Tooltip arrow type dynamically - * jQuery('#YourOwnDivId a.example.render').mouseover( function() { - * var arrowType = arrowTypes[ counter++ % 12 ]; - * tipRendered.setArrowType( arrowType ); - * }); - * - * // - * // Another example using rich content - * // - * jQuery('#YourOwnDivId') - * .append('



                  Rich content'); - * - * var richContent = - * '
                  '+ - * '

                  Santiago de Cali

                  ' + - * ''+ - * '

                  '+ - * 'Simply referred to as Cali, is a city located in western Colombia '+ - * 'It is the capital of the Valle del Cauca Department. With a population of 2.5 million, '+ - * 'Cali is the third largest city in the country, after Bogota and Medellin. The city '+ - * 'was founded on 25 July 1536.

                  '; - * - * var tipRich = new Biojs.Tooltip({ - * targetSelector: "a.example.rich", - * cbRender: function( element ) { - * return richContent; - * }, - * arrowType: Biojs.Tooltip.ARROW_BOTTOM_MIDDLE - * }); - * - * // - * // Last example using mouse position instead of element's - * // - * jQuery('#YourOwnDivId') - * .append('



                  Tooltip changes with mouse positioning.'); - * - * var tipPosition = new Biojs.Tooltip({ - * targetSelector: "a.example.position", - * position: Biojs.Tooltip.MOUSE_POSITION - * }); - * - **/ -Biojs.Tooltip = Biojs.extend ( -/** @lends Biojs.Tooltip# */ -{ - constructor: function (options) { - - var self = this; - var arrowType = this.opt.arrowType; - - this._container = jQuery('
                  ').addClass("Tooltip"); - - this._arrow = jQuery('
                  ').appendTo( self._container ); - this._body = jQuery('
                  ').appendTo( self._container ); - - this._container.appendTo('body'); - - this._initialize(); - }, - - /** - * Default values for the options - * @name Biojs.Tooltip-opt - */ - opt: { - targetSelector: "a", - cbRender: undefined, - arrowType: "left_top", - position: 2, // ELEMENT_POSITION - delay: 200 - }, - - /** - * Array containing the supported event names - * @name Biojs.Tooltip-eventTypes - */ - eventTypes: [ - /** - * @name Biojs.Tooltip#onShowUp - * @event - * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument. - * @eventData {Object} source The component which did triggered the event. - * @eventData {string} type The name of the event. - * @eventData {string} target Target element. - * - * @example - * simpleTip.onShowUp( - * function( e ) { - * alert("Mouse has passed over the first example."); - * } - * ); - * - */ - "onShowUp" - ], - - _initialize: function( ) { - - var self = this; - var timer = 0; - var targetSelector = this.opt.targetSelector; - var cbRender = this.opt.cbRender; - var refPos = this.opt.position; - var target; - - // Get the text from the title attribute by default - if ( "function" != typeof cbRender ) { - cbRender = function( element ) { - return jQuery( element ).attr('title'); - } - } - - // Add the class to the arrow - //arrow.addClass( self.opt.arrowType.match(/^(left|top|right|bottom)/g)[0] ); - this.setArrowType( this.opt.arrowType ); - - // Positioning - this._arrow.css({ - "position": "absolute", - "z-index": "99999" - }); - - this._body.css({ - 'position': 'absolute', - 'z-index': '99998', - 'margin': '0px' - }); - - if ( refPos == Biojs.Tooltip.MOUSE_POSITION ) { - jQuery( targetSelector ).mousemove( function (e) { - - target = jQuery(e.target); - - if (timer) { - clearTimeout(timer); - } - timer = 0; - - // Set the content - content = cbRender.call( self, e.target ); - - self._body.html( content ); - - // Show up - self._show(); - - // Positioning - self._setPosition( - { left: e.pageX - 10, top: e.pageY - 10 }, - { width: 20, height: 20 } - ); - - // Event triggering - self.raiseEvent( Biojs.Tooltip.EVT_ON_SHOW_UP, { 'target': target }); - - }).mouseout( function() { - timer = setTimeout( 'Biojs.getInstance(' + self.getId() + ')._hide()' , self.opt.delay ); - }); - - } else { - jQuery( targetSelector ).mouseover( function (e) { - - target = jQuery(e.target); - - if (timer) { - clearTimeout(timer); - } - timer = 0; - - // Set the content - content = cbRender.call( self, e.target ); - - self._body.html( content ); - - // Show up - self._show(); - - // Positioning - self._setPosition( - target.offset(), - { width: target.width(), height: target.height() } - ); - - // Event triggering - self.raiseEvent( Biojs.Tooltip.EVT_ON_SHOW_UP, { 'target': target }); - - }).mouseout( function() { - timer = setTimeout( 'Biojs.getInstance(' + self.getId() + ')._hide()' , self.opt.delay ); - }); - } - - self._container.mouseover( function(){ - clearTimeout(timer); - timer = 0; - self._show(); - - }).mouseout( function() { - timer = setTimeout( 'Biojs.getInstance(' + self.getId() + ')._hide()' , self.opt.delay ); - }); - - this._hide(); - }, - - _hide: function() { - this._container.hide(); - }, - - _show: function() { - this._container.show(); - }, - - _setPosition: function ( offset, dim ) { - - var arrow = this._arrow; - var arrowType = this.opt.arrowType; - var arrowPos = { top: offset.top, left: offset.left }; - - var body = this._body; - var bodyPos = {}; - - arrow.removeClass(); - arrow.addClass( 'arrow ' + arrowType.match(/^(left|top|right|bottom)/g)[0] ); - - if ( arrowType == Biojs.Tooltip.ARROW_LEFT_TOP ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left += arrow.width() + dim.width ; - - bodyPos.left = arrowPos.left + arrow.width() - 1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()/4); - - } else if ( arrowType == Biojs.Tooltip.ARROW_LEFT_MIDDLE ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left += arrow.width() + dim.width ; - - bodyPos.left = arrowPos.left + arrow.width() - 1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()/2); - - } else if ( arrowType == Biojs.Tooltip.ARROW_LEFT_BOTTOM ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left += arrow.width() + dim.width ; - - bodyPos.left = arrowPos.left + arrow.width() - 1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()*(3/4)); - - } else if ( arrowType == Biojs.Tooltip.ARROW_TOP_LEFT ) { - - arrowPos.top += dim.height; - arrowPos.left += Math.floor(dim.width/2) - Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.height()/2) - Math.floor(body.width()/4); - bodyPos.top = arrowPos.top + arrow.height() -1; - - } else if ( arrowType == Biojs.Tooltip.ARROW_TOP_MIDDLE ) { - - arrowPos.top += dim.height; - arrowPos.left += Math.floor(dim.width/2) - Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.height()/2) - Math.floor(body.width()/2); - bodyPos.top = arrowPos.top + arrow.height() -1; - - } else if ( arrowType == Biojs.Tooltip.ARROW_TOP_RIGHT ) { - - arrowPos.top += dim.height; - arrowPos.left += Math.floor(dim.width/2) - Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.height()/2) - Math.floor( body.width()*(3/4) ); - bodyPos.top = arrowPos.top + arrow.height() -1; - - } else if ( arrowType == Biojs.Tooltip.ARROW_RIGHT_TOP ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left -= arrow.width(); - - bodyPos.left = arrowPos.left - body.outerWidth() +1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()/4); - - } else if ( arrowType == Biojs.Tooltip.ARROW_RIGHT_MIDDLE ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left -= arrow.width(); - - bodyPos.left = arrowPos.left - body.outerWidth() +1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()/2); - - } else if ( arrowType == Biojs.Tooltip.ARROW_RIGHT_BOTTOM ) { - - arrowPos.top += Math.floor(dim.height/2) - Math.floor(arrow.height()/2); - arrowPos.left -= arrow.width(); - - bodyPos.left = arrowPos.left - body.outerWidth() +1; - bodyPos.top = arrowPos.top + Math.floor(arrow.height()/2) - Math.floor(body.height()*(3/4)); - - } else if ( arrowType == Biojs.Tooltip.ARROW_BOTTOM_LEFT ) { - - arrowPos.top -= arrow.height(); - arrowPos.left += Math.floor(dim.width/2) + Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.width()/2) - Math.floor(body.width()/4); - bodyPos.top = arrowPos.top - body.outerHeight() +1; - - } else if ( arrowType == Biojs.Tooltip.ARROW_BOTTOM_MIDDLE ) { - - arrowPos.top -= arrow.height(); - arrowPos.left += Math.floor(dim.width/2) - Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.width()/2) - Math.floor(body.width()/2); - bodyPos.top = arrowPos.top - body.outerHeight() +1; - - } else if ( arrowType == Biojs.Tooltip.ARROW_BOTTOM_RIGHT ) { - - arrowPos.top -= arrow.height(); - arrowPos.left += Math.floor(dim.width/2) - Math.floor(arrow.width()/2); - - bodyPos.left = arrowPos.left + Math.floor(arrow.width()/2) - Math.floor(body.width()*(3/4)); - bodyPos.top = arrowPos.top - body.outerHeight() +1; - } - - this._arrow.css( arrowPos ); - this._body.css( bodyPos ); - }, - - /** - * Changes the Tooltip direction. The point of reference is the arrow's type. - * Choose one of the following available types: - *
                    - *
                  • Biojs.Tooltip.ARROW_LEFT_TOP
                  • - *
                  • Biojs.Tooltip.ARROW_LEFT_MIDDLE
                  • - *
                  • Biojs.Tooltip.ARROW_LEFT_BOTTOM
                  • - *
                  • Biojs.Tooltip.ARROW_TOP_LEFT
                  • - *
                  • Biojs.Tooltip.ARROW_TOP_MIDDLE
                  • - *
                  • Biojs.Tooltip.ARROW_TOP_RIGHT
                  • - *
                  • Biojs.Tooltip.ARROW_RIGHT_TOP
                  • - *
                  • Biojs.Tooltip.ARROW_RIGHT_MIDDLE
                  • - *
                  • Biojs.Tooltip.ARROW_RIGHT_BOTTOM
                  • - *
                  • Biojs.Tooltip.ARROW_BOTTOM_LEFT
                  • - *
                  • Biojs.Tooltip.ARROW_BOTTOM_MIDDLE
                  • - *
                  • Biojs.Tooltip.ARROW_BOTTOM_RIGHT
                  • - *
                      - * - * @param {static} arrowType Static Biojs.Tooltip.ARROW_[TYPE] value. - * - * @example - * simpleTip.setArrowType(Biojs.Tooltip.ARROW_BOTTOM_RIGHT); - * - */ - setArrowType: function( arrowType ) { - - var newClass = arrowType.match(/^(left|top|right|bottom)/g)[0]; - - if ( newClass !== undefined ) { - this.opt.arrowType = arrowType; - } - }, - /** - * Returns the actual arrow type. - * @returns {static} Static Biojs.Tooltip.ARROW_[TYPE] value. - * - * @example - * alert ( "First example is using " + simpleTip.getArrowType() + " arrow." ); - * - */ - getArrowType: function( arrowType ) { - return this.opt.arrowType; - }, - - /** - * Returns the actual id attribute value. - * @returns {string} DOM element identifier of this component. - * - * @example - * alert ( "Identifier of the second example is " + tipRendered.getIdentifier() + "." ); - * - */ - getIdentifier: function( ) { - return this._container.attr('id'); - }, - - /** - * Sets the id attribute value. - * @param {string} DOM element identifier for this component. - * - * @example - * tipRendered.setIdentifier("MyIdentifier"); - * - */ - setIdentifier: function( value ) { - return this._container.attr( 'id', value ); - } - - -},{ - // Arrows height: 12px width: 7px; - ARROW_LEFT_TOP: "left_top", - ARROW_LEFT_MIDDLE: "left_middle", - ARROW_LEFT_BOTTOM: "left_bottom", - ARROW_TOP_LEFT: "top_left", - ARROW_TOP_MIDDLE: "top_middle", - ARROW_TOP_RIGHT: "top_right", - ARROW_RIGHT_TOP: "right_top", - ARROW_RIGHT_MIDDLE: "right_middle", - ARROW_RIGHT_BOTTOM: "right_bottom", - ARROW_BOTTOM_LEFT: "bottom_left", - ARROW_BOTTOM_MIDDLE: "bottom_middle", - ARROW_BOTTOM_RIGHT: "bottom_right", - - // Events - EVT_ON_SHOW_UP: "onShowUp", - - MOUSE_POSITION: 1, - ELEMENT_POSITION: 2 - -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.Tree.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.Tree.js deleted file mode 100755 index fbe64772ad..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.Tree.js +++ /dev/null @@ -1,3113 +0,0 @@ -/** - * Tree component - * - * @class - * @extends Biojs - * - * @author Fabian Schreiber - * @version 1.0.0 - * @category 3 - * - * @requires jQuery Core 1.9.2 - * @dependency - * - * @requires jQuery Tipsy - * @dependency - * - * @requires D3 - * @dependency - * @requires Additional tree functions - * @dependency - - * @requires BioJS Tree css - * @dependency - - * @requires jQuery Tipsy - * @dependency - * - * - * @param {Object} options An object with the options for Tree component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * - * @option {file} tree - * JSON that contains the tree information. - *
                       
                      - *    [
                      - *    	// 
                      - *    	{ name: <name>, 
                      - *		  display_label: <display_label>,
                      - *		  duplication: <duplication>,
                      - *		  branch_length: <endVal1>,
                      - *		  common_name: <common_name>,
                      - *		  seq_length: <seq_length>,
                      - *		  type: <type>,
                      - *		  uniprot_name: <uniprot_name>,
                      - *
                      - *		  children: []},
                      - *    	//
                      - *    	// Any others nodes
                      - *    	...,  
                      - *    	// 
                      - *    ]
                      - * - *
                       
                      - * tree : [
                      - * 		{"name":"Amniota_1","branch_length":"0.2212","binary_alignment":"N/A","children": [..]
                      - *		,"common_name":"Chicken","seq_length":3397,"swissprot_gene_name":"N/A","display_label":"BRCA2"}
                      - *	   ]
                      - * 
                      - * - * @option {file} domains_file - * Set of annotations for the leaves of the tree. Must be an array of objects following the syntax: - *
                      - *            [ 
                      - *              // An annotation:
                      - *              { name: <name>, 
                      - *                species_name: <message>, 
                      - *                alignment_length: <message>, 
                      - *                seq_length: <message>, 
                      - *                cigar_string: <color_code>, 
                      - *                domains: [{ name: name; domain_start: <startVal1>, domain_end: <endVal1> id: <HTMLColor> name : name}, ...,{ start: <startValN>, end: <endValN>, color: <HTMLColor>}] 
                      - *              }, 
                      - *              
                      - *              // ...
                      - *              // more annotations here 
                      - *              // ...
                      - *            ]
                      - *    		 
                      - *
                       
                      - * tree : [
                      - * 		{
                      - *        "cigar_string" : "4D22MD23M3D10MD13M2D44M2D23M3D7MD13M11D16MD57M5D27MD26M2D3M9D8MD9M2D3MD12MD11M2D10M3D3MD2MDMD9MD19M4D2MD17MD10MD24M5D7MD3MD24MD19MD10M3D6M10D26M6D5M2D17M12D11M2D10M2D52M2D7M2D12MD7M5D22M2D4M2D10M3D46MD20MD6M4D4M2D3M3DM2D11M4D4MDM2D4MDMD3MD5M4D5MD9M5D5M2DM7D18M3D5MD2MD6MD21MD5MDM2D6MDMD2MD23MD9M5D19M7D3M2D19MD2MD7M7D14M5D13MD9MD7M3D45MD7M2D4M3D7M8D3M13D2M12D3M5D4MD35MD44M3D2M2D18M15D17MD18M8D4M8DMD21MD36MD17MD2MD25M2D19MD6MD2MD3MD12M6D12MD21M4D11MD17MD18M2D79MD55M2D18M2D30M4D5MD5MD8MD11MD23MD42M8D26M4DMD25MD6M5D7M2D6M2D3MD15M6DMD14MD32M10D3MD6M5D43M3D13MD21MD6MD6M3D3MD8MD10M7D11M4D23M10D44MD12M5D4MDM3D19M13D34MD4MD15MD2MD6MD53M4D2MD10MD38MD13MD25MD104M3D62M2D15M5D5M6D37M2D6MDMD234MD3MD162MD11M2D30M2D45MD20MD2MD100M13D25M4D20M4D78M8D62MD38MD2MD8MD3MD4MD5MD41MD3MD4M16D11M2DM3D38M2D",
                      - *     "species_name" : "Ailuropoda_melanoleuca",
                      - *     "alignment_length" : 4010,
                      - *     "domains" : [ ..]
                      - *     "seq_length" : 3460,
                      - *     "name" : "ENSAMEP00000009909"}
                      - *	   ]
                      - * 
                      - * - * where: - *
                        - *
                      • name is the unique name corresponding to an id in the tree
                      • - *
                      • species_name the species the annotation belong to.
                      • - *
                      • alignment_length the length of the alignment sequence
                      • - *
                      • seq_length the length of the sequence
                      • - *
                      • domains array of objects defining the intervals which belongs to the annotation.
                      • - *
                      • domains[i].domain_start domain's start position
                      • - *
                      • domains[i].domain_end domain's stop position.
                      • - *
                      • domains[i].name name of the domain, e.g. BRCA-2_OB1
                      • . - *
                      • domains[i].id the domain's id in the source database. Here, e.g. PF09103.5
                      • - *
                      • domains[i].evalue the domains evalue
                      • - *
                      - * - * @option {string} image_path - * Path to directory which contains species images. - * - * @option {string} [annotation_option="seqDomains"] - * The display format for the annotations. - * - * @option {boolean} [two_windows] - * specifies whether the tree and the annotations should be printed into the same div/svg or separate - * - * @option {string} [highlight_gene] - * Gene identifier to be highlighted. - * - * - * @example - * var alignment_file = "../biojs/data/tree/just_sequences.json"; - * var domain_file = "../biojs/data/tree/just_domains.TF105041.json"; - * var model_json_tree = "../biojs/data/tree/TF105041_model.json"; - * - * var image_path = "../biojs/data/tree/images/species_files/"; - * //var highlight_gene = "ENSBTAP00000001311"; - * var highlight_gene = ""; - * //var newick_tree = "../data/trees/newick_tree.nh"; - * var newick_tree = ""; - * var load_from_variable = 0; - * var json_tree_string; - * - * myTree = new Biojs.Tree({ - * target : "YourOwnDivId", - * formatOptions : { - * tree:'json' - * }, - * // tree parameters - * json_tree : model_json_tree, - * alignment_file : alignment_file, - * show_real_branchlength : "false", - * annotation_option : "seq_domains", - * domains_file : domain_file, - * two_window : true, - * image_path : image_path, - * highlight_gene : highlight_gene, - * json_tree_string : json_tree_string, - * load_from_variable : load_from_variable, - * }); - * - */ - -Biojs.Tree = Biojs.extend( -/** @lends Biojs.Tree# */ -{ - constructor: function (options) { - //Biojs.console.enable(); - var self = this; - - this._container = jQuery( "#" + this.opt.target ); - //this._contentcontainer = jQuery( "#" + this.opt.tv_contentcontainer ); - - // Lazy initialization - this._container.ready(function() { - self._initialize(); - }); - }, - - /** - * Default values for the options - * @name Biojs.Tree-opt - */ - opt : { - - // new opts for tree - //__show_alignments: false, - //__show_domains: false, - //show_species_tree: false, - show_lost_taxa: false, // alignment, domains, seq_domains, speciestree || false - tree_view: "", // reconciledView - annotation_option: "annotation_grid", // alignment, domains, seq_domains, speciestree || false - species_nodes: 190, - alignment_length : "", - domains_file : "", - json_tree : "", - species_tree : "", - image_path : "", - newick_tree : "", - tree_data : "", - tree_target : "", - max_annot_div_width : "", // in case an alignment will be shown, the svg in the annotation panel needs to be a lot wider - default_view : "ensembl", - annot_target : "", - no_genes : "", - tree : "", - highlight_gene : "", - load_from_variable : undefined, - load_from_web : undefined, - json_tree_string : "", - json_alignment_string : "", - json_domain_string : "", - root : "", - show_real_branchlength: false, - alignment_font_size:8, - //domainScale : d3.scale.linear().domain([20,4000]).range([1, 250]), - - sequence : "", - id : "", - target : "", - format : "FASTA", - selection: { start: 0, end: 0 }, - columns: { size: 35, spacedEach: 10 }, - highlights : [], - annotations: [], - sequenceUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/sequence', - modelTreeOn: "", - - // Styles - duplication_circle_size : 15, - circle_size : 3, - sequence_rect_width : 12, - leaf_group_x : 188, - sequence_start_y : 300, - link_type : "elbow", - leaf_space : "300", - i : 0, - duration : 500, - two_window: false, - root: "", - diagonal: "", - fontSize: 10, - tree_representation_type: "not-radial", - max_seq_representation: 400, - - - selectionColor : 'Yellow', - selectionFontColor : 'black', - highlightFontColor : 'red', - highlightBackgroundColor : 'white', - fontFamily: '"Andale mono", courier, monospace', - fontSize: '12px', - fontColor : 'inherit', - backgroundColor : 'inherit', - width: 400, - availablewidth: 1500, - height: undefined, - formatSelectorVisible: true - }, - - /** - * Array containing the supported event names - * @name Biojs.Tree-eventTypes - */ - eventTypes : [], - - // internal members - _headerDiv : null, - _contentDiv : null, - - // Methods - - _initialize: function () { - var self = this; - - //this.__setModelOrganisms(); - // Read tree data - //if(self.opt.tree_view == "reconciledView"){ - // have to set this to the species tree - //this.opt.json_tree = this.opt.species_tree; - // Biojs.console.enable("changed to species tree"); - //} - // read tree - // read also annotation -// set padding for tree window - this.padding = { - "top": 0, - "right": 10, - "bottom": 0, - "left": 10 - }; - if(self.opt.two_window){ - // this will be the main div - this.opt.tree_target = "tree_panel"; - this.opt.annot_target = "annotation_panel" - } - //jQuery('
                      ').appendTo("#"+this.opt.target); - //jQuery('
                      ').appendTo("#"+this.opt.target); - - jQuery('
                      ').appendTo("#"+this.opt.target); - jQuery('
                      Loading treeLoading tree data...
                      ').appendTo("#"+this.opt.tree_target); - jQuery('
                      Loading annotationLoading annotation data...
                      ').appendTo("#"+this.opt.annot_target); - jQuery("#tree_spinner").hide(); - jQuery("#annotation_spinner").hide(); - - // this is important!!! - // because we are getting data via an asyncronous ajax call, the function will continue - // we have to be aware the things are getting executed within the "success" function - this.tree_data = this.__readTree({'load_from_variable': this.opt.load_from_variable,'tree_format' : this.opt.formatOptions.tree, - 'tree_data': this.opt.json_tree,'tree_data_variable' : this.opt.json_tree_string, - 'load_from_web' : this.opt.load_from_web}); - - }, - /* - * Setting the svg - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * this._setvisualSpace(); - * - */ - _setVisualSpace: function ( args ) { - var width = args.width; - var height = args.height; - var two_window = args.two_window; - var annot_div_width = args.annot_div_width; - var self = this; - /*this.opt.vis = d3.select("#"+this.opt.target).append("svg:svg") - .attr("width", width) - .attr("height", height) - //.attr("padding", "40px"); - //.attr("pointer-events", "all") - //.append('svg:g'); - - */ - var m = [40, 240, 40, 240], - w = 1000 -m[0] -m[0], - h = 1840 -m[0] -m[2], - i = 0, - root; - var div_width, div_height,computed_div_width,div_width_half; - if(two_window){ - div_width = d3.select("#"+self.opt.target).style("width"); - - //div_width = jQuery("#wrapper").width; - div_heigth = parseInt(d3.select("#"+self.opt.target).style("height")); - div_width_half = div_width.replace("px",""); - div_width_half = parseInt(div_width_half /2); - computed_div_width = div_width_half+"px"; - Biojs.console.enable("half width is "+div_width_half+" ("+div_width+"), "+computed_div_width+""); - } - else{ - div_width = d3.select("#"+this.opt.target).style("width"); - div_heigth = parseInt(d3.select("#"+this.opt.target).style("height")); - } - - self.opt.div_width_half = div_width_half; - Biojs.console.enable("heigth is "+div_heigth+" and width is "+div_width); - //blaaaa - self.opt.availablewidth = div_width; - - var w = window, - d = document, - e = d.documentElement, - g = d.getElementsByTagName('body')[0], - x = w.innerWidth || e.clientWidth || g.clientWidth, - y = w.innerHeight|| e.clientHeight|| g.clientHeight; - Biojs.console.enable("x: "+x+" y: "+y); - Biojs.console.enable("setting height to "+(height * 2)); - - if(self.opt.two_window){ - this.opt.tree_panel = d3.select("#"+this.opt.tree_target).append("svg:svg") - .attr("class","svg_container") - .attr("width", div_width_half) - .attr("height", height) - .style("overflow", "scroll") - //.style("background-color","#EEEEEE") - .append("svg:g") - .attr("class","drawarea"); - //this.opt.tree_panel.append("svg:g").attr("class","axisarea"); - this.opt.tree_panel = this.opt.tree_panel - //.append("div") - .append("svg:g") - .attr("class","treearea") - .append("svg:g") - .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); - - - this.opt.annot_panel = d3.select("#"+this.opt.annot_target).append("svg:svg"); - this.opt.annot_panel.append("svg:g").attr("class","axisarea"); - - Biojs.console.enable("annotation svg with: "+annot_div_width); - this.opt.annot_panel.attr("class","svg_container") - .attr("width", annot_div_width) - .attr("height", height + 200) - .attr("id", "annotation_svg_container") - .style("overflow", "auto") - //.style("background-color","#EEEEEE") - .append("svg:g") - .attr("class","annot_area"); - - this.opt.annot_panel = this.opt.annot_panel - //.append("div") - .append("svg:g") - .attr("class","annotationarea") - .style("padding", "20") - .append("svg:g") - .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); - } - else{ - this.opt.vis = d3.select("#"+this.opt.target).append("svg:svg") - .attr("class","svg_container") - .attr("width", div_width) - .attr("height", height) - //.attr("viewBox", "30 0 300 800") - //.style("overflow", "scroll") - //.style("background-color","#EEEEEE") - .append("svg:g") - .attr("class","drawarea"); - // add textares - this.opt.vis - .append("svg:g") - .attr("class","axisarea"); - this.opt.vis = this.opt.vis - //.append("div") - .append("svg:g") - .attr("class","treearea") - .append("svg:g") - .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); - } - // self.zoomObject = d3.behavior.zoom() - // .scaleExtent([0.5, 2]) - // .on("zoom", zoom); - - // self.zoomObject = d3.behavior.zoom().scaleExtent([0.2, 8]).on("zoom", zoom); - - // d3.select("#"+this.opt.target+" svg").call(self.zoomObject); - - }, - -_setTreeSpace: function ( args ) { - var width = args.width; - var height = args.height; - var two_window = args.two_window; - var annot_div_width = args.annot_div_width; - var self = this; - var m = [40, 240, 40, 240], - w = 1000 -m[0] -m[0], - h = 1840 -m[0] -m[2], - i = 0, - root; - var div_width, div_height,computed_div_width,div_width_half; - if(two_window){ - div_width = d3.select("#"+self.opt.target).style("width"); - - //div_width = jQuery("#wrapper").width; - div_heigth = parseInt(d3.select("#"+self.opt.target).style("height")); - div_width_half = div_width.replace("px",""); - div_width_half = parseInt(div_width_half /2); - computed_div_width = div_width_half+"px"; - Biojs.console.enable("half width is "+div_width_half+" ("+div_width+"), "+computed_div_width+""); - } - else{ - div_width = d3.select("#"+this.opt.target).style("width"); - div_heigth = parseInt(d3.select("#"+this.opt.target).style("height")); - } - self.opt.div_width_half = div_width_half; - self.opt.availablewidth = div_width; - - var w = window, - d = document, - e = d.documentElement, - g = d.getElementsByTagName('body')[0], - x = w.innerWidth || e.clientWidth || g.clientWidth, - y = w.innerHeight|| e.clientHeight|| g.clientHeight; - Biojs.console.enable("x: "+x+" y: "+y); - Biojs.console.enable("setting height to "+(height * 2)); - - if(self.opt.two_window){ - this.opt.tree_panel = d3.select("#"+this.opt.tree_target).append("svg:svg") - .attr("class","svg_container") - .attr("width", div_width_half) - .attr("height", height) - .style("overflow", "scroll") - //.style("background-color","#EEEEEE") - .append("svg:g") - .attr("class","drawarea"); - //this.opt.tree_panel.append("svg:g").attr("class","axisarea"); - this.opt.tree_panel = this.opt.tree_panel - //.append("div") - .append("svg:g") - .attr("class","treearea") - .append("svg:g") - .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); - - } - else{ - this.opt.vis = d3.select("#"+this.opt.target).append("svg:svg") - .attr("class","svg_container") - .attr("width", div_width) - .attr("height", height) - //.attr("viewBox", "30 0 300 800") - //.style("overflow", "scroll") - //.style("background-color","#EEEEEE") - .append("svg:g") - .attr("class","drawarea"); - // add textares - this.opt.vis - .append("svg:g") - .attr("class","axisarea"); - this.opt.vis = this.opt.vis - //.append("div") - .append("svg:g") - .attr("class","treearea") - .append("svg:g") - .attr("transform", "translate(" + m[3] + "," + m[0] + ")"); - } - - }, - - __slideZoom: function(zoom_level){ - - Biojs.console.enable("ready to zoom-slide:"+zoom_level); - //self.zoomObject = d3.behavior.zoom().scaleExtent([0.2, 8]).on("zoom", zoom); - //Biojs.console.enable(this.zoomObject); - //Biojs.console.enable(this.zoomObject.scale); - //this.zoomObject.translate([0,0]).scale(1); - //var currentScale = d3.event.scale; - //this.zoomObject.scale(currentScale); - - - zoom_slider({scale: [zoom_level] }); - }, - _addZoom: function(args){ - //Biojs.console.enable("add zoom"); - var self = this; - self.zoom_behavior =d3.behavior.zoom() - .scaleExtent([0.5, 2]) - .on("zoom", zoom); - if(self.opt.two_window){ - Biojs.console.enable("adding to annot"); - d3.select("#"+this.opt.annot_target+" svg").call(self.zoom_behavior); - } - else{ - Biojs.console.enable("not adding to annot"); - d3.select("#"+this.opt.target+" svg").call(self.zoom_behavior); - } - // self.zoomObject = d3.behavior.zoom().scaleExtent([0.2, 8]).on("zoom", zoom); - - - }, - - __removeZoom: function(args){ - //Biojs.console.enable("add zoom"); - //this.opt.vis.call(d3.behavior.zoom().on("zoom", this.__redraw({vis : this.opt.vis}))) - // .append('svg:g'); - - self.zoom_behavior = d3.behavior.zoom() - .scaleExtent([0.5, 2]) - .on("zoom", null); - d3.select("#"+this.opt.target+" svg").call(self.zoom_behavior); - }, - __resetZoom: function(args){ - var self = this; - //Biojs.console.enable("add zoom"); - //this.opt.vis.call(d3.behavior.zoom().on("zoom", this.__redraw({vis : this.opt.vis}))) - // .append('svg:g'); - self.zoom_behavior = d3.behavior.zoom() - .scaleExtent([0.5, 2]) - .on("zoom", null); - self.zoom_behavior.scale(1); - self.zoom_behavior.translate([0, 0]); - var vis = d3.select("#"+this.opt.target+" svg"); - vis.transition().duration(500).attr('transform', 'translate(' + zoom.translate() + ') scale(' + zoom.scale() + ')') - - //.call(self.zoom_behavior); - }, - - __comparator: function (a, b) { - var a_name = a.children? a.name.replace(/_\d+/g, '') : a.taxon; - var b_name = b.children? b.name.replace(/_\d+/g, '') : b.taxon; - var species2index = new Object(); - species2index["Tetraodon_nigroviridis"] = 0; - species2index["Takifugu_rubripes"] = 1; - species2index["Tetraodontidae"] = 2; - species2index["Oreochromis_niloticus"] = 3; - species2index["Gasterosteus_aculeatus"] = 4; - species2index["Oryzias_latipes"] = 5; - species2index["Xiphophorus_maculatus"] = 6; - species2index["Atherinomorpha"] = 7; - species2index["Smegmamorpha"] = 8; - species2index["Percomorpha"] = 9; - species2index["Gadus_morhua"] = 10; - species2index["Holacanthopterygii"] = 11; - species2index["Danio_rerio"] = 12; - species2index["Clupeocephala"] = 13; - species2index["Tupaia_belangeri"] = 14; - species2index["Cavia_porcellus"] = 15; - species2index["Spermophilus_tridecemlineatus"] = 16; - species2index["Rattus_norvegicus"] = 17; - species2index["Mus_musculus"] = 18; - species2index["Murinae"] = 19; - species2index["Dipodomys_ordii"] = 20; - species2index["Sciurognathi"] = 21; - species2index["Rodentia"] = 22; - species2index["Oryctolagus_cuniculus"] = 23; - species2index["Ochotona_princeps"] = 24; - species2index["Lagomorpha"] = 25; - species2index["Glires"] = 26; - species2index["Otolemur_garnettii"] = 27; - species2index["Microcebus_murinus"] = 28; - species2index["Strepsirrhini"] = 29; - species2index["Nomascus_leucogenys"] = 30; - species2index["Pongo_abelii"] = 31; - species2index["Homo_sapiens"] = -3; - species2index["Pan_troglodytes"] = -2; - species2index["Gorilla_gorilla"] = -1; - species2index["Homininae"] = 0; - species2index["Hominidae"] = 36; - species2index["Hominoidea"] = 37; - species2index["Macaca_mulatta"] = 38; - species2index["Catarrhini"] = 39; - species2index["Callithrix_jacchus"] = 40; - species2index["Simiiformes"] = 41; - species2index["Tarsius_syrichta"] = 42; - species2index["Haplorrhini"] = 43; - species2index["Primates"] = 44; - species2index["Euarchontoglires"] = -3; - species2index["Procavia_capensis"] = 46; - species2index["Loxodonta_africana"] = 47; - species2index["Echinops_telfairi"] = 48; - species2index["Afrotheria"] = 49; - species2index["Pteropus_vampyrus"] = 50; - species2index["Myotis_lucifugus"] = 51; - species2index["Chiroptera"] = 52; - species2index["Equus_caballus"] = 53; - species2index["Vicugna_pacos"] = 54; - species2index["Bos_taurus"] = 55; - species2index["Sus_scrofa"] = 56; - species2index["Tursiops_truncatus"] = 57; - species2index["Cetartiodactyla"] = 58; - species2index["Felis_catus"] = 59; - species2index["Mustela_putorius_furo"] = 60; - species2index["Ailuropoda_melanoleuca"] = 61; - species2index["Canis_lupus_familiaris"] = 62; - species2index["Caniformia"] = 63; - species2index["Carnivora"] = 64; - species2index["Sorex_araneus"] = 65; - species2index["Erinaceus_europaeus"] = 66; - species2index["Insectivora"] = 67; - species2index["Laurasiatheria"] = 68; - species2index["Dasypus_novemcinctus"] = 69; - species2index["Choloepus_hoffmanni"] = 70; - species2index["Xenarthra"] = 71; - species2index["Eutheria"] = 72; - species2index["Monodelphis_domestica"] = 73; - species2index["Macropus_eugenii"] = 74; - species2index["Sarcophilus_harrisii"] = 75; - species2index["Metatheria"] = 76; - species2index["Theria"] = 77; - species2index["Ornithorhynchus_anatinus"] = 78; - species2index["Mammalia"] = 79; - species2index["Pelodiscus_sinensis"] = 80; - species2index["Anolis_carolinensis"] = 81; - species2index["Taeniopygia_guttata"] = 82; - species2index["Meleagris_gallopavo"] = 83; - species2index["Gallus_gallus"] = 84; - species2index["Phasianidae"] = 85; - species2index["Neognathae"] = 86; - species2index["Sauria"] = 87; - species2index["Sauropsida"] = 88; - species2index["Amniota"] = 89; - species2index["Xenopus_tropicalis"] = 90; - species2index["Tetrapoda"] = 91; - species2index["Latimeria_chalumnae"] = 92; - species2index["Sarcopterygii"] = 93; - species2index["Euteleostomi"] = 94; - species2index["Petromyzon_marinus"] = 95; - species2index["Vertebrata"] = 96; - species2index["Ciona_savignyi"] = 97; - species2index["Ciona_intestinalis"] = 98; - species2index["Ciona"] = 99; - species2index["Chordata"] = 100; - species2index["Strongylocentrotus_purpuratus"] = 101; - species2index["Deuterostomia"] = 102; - species2index["Lottia_gigantea"] = 103; - species2index["Capitella_teleta"] = 104; - species2index["Helobdella_robusta"] = 105; - species2index["Annelida"] = 106; - species2index["Lophotrochozoa"] = 107; - species2index["Ixodes_scapularis"] = 108; - species2index["Atta_cephalotes"] = 109; - species2index["Apis_mellifera"] = 110; - species2index["Aculeata"] = 111; - species2index["Nasonia_vitripennis"] = 112; - species2index["Apocrita"] = 113; - species2index["Drosophila_virilis"] = 114; - species2index["Drosophila_mojavensis"] = 115; - species2index["Drosophila"] = 116; - species2index["Drosophila_grimshawi"] = 117; - species2index["Drosophila_willistoni"] = 118; - species2index["Drosophila_pseudoobscura_pseudoobscura"] = 119; - species2index["Drosophila_persimilis"] = 120; - species2index["pseudoobscura_subgroup"] = 121; - species2index["Drosophila_yakuba"] = 122; - species2index["Drosophila_simulans"] = 123; - species2index["Drosophila_sechellia"] = 124; - species2index["Drosophila_melanogaster"] = 125; - species2index["Drosophila_erecta"] = 126; - species2index["melanogaster_subgroup"] = 127; - species2index["Drosophila_ananassae"] = 128; - species2index["melanogaster_group"] = 129; - species2index["Sophophora"] = 130; - species2index["Drosophila"] = 131; - species2index["Anopheles_darlingi"] = 132; - species2index["Anopheles_gambiae"] = 133; - species2index["Anopheles"] = 134; - species2index["Culex_quinquefasciatus"] = 135; - species2index["Aedes_aegypti"] = 136; - species2index["Culicinae"] = 137; - species2index["Culicidae"] = 138; - species2index["Diptera"] = 139; - species2index["Heliconius_melpomene"] = 140; - species2index["Danaus_plexippus"] = 141; - species2index["Nymphalidae"] = 142; - species2index["Bombyx_mori"] = 143; - species2index["Obtectomera"] = 144; - species2index["Tribolium_castaneum"] = 145; - species2index["Endopterygota"] = 146; - species2index["Pediculus_humanus_corporis"] = 147; - species2index["Acyrthosiphon_pisum"] = 148; - species2index["Paraneoptera"] = 149; - species2index["Neoptera"] = 150; - species2index["Daphnia_pulex"] = 151; - species2index["Pancrustacea"] = 152; - species2index["Arthropoda"] = 153; - species2index["Trichinella_spiralis"] = 154; - species2index["Pristionchus_pacificus"] = 155; - species2index["Bursaphelenchus_xylophilus"] = 156; - species2index["Meloidogyne_hapla"] = 157; - species2index["Tylenchida"] = 158; - species2index["Strongyloides_ratti"] = 159; - species2index["Heterorhabditis_bacteriophora"] = 160; - species2index["Caenorhabditis_briggsae_AF16"] = 161; - species2index["Caenorhabditis_japonica"] = 162; - species2index["Caenorhabditis_brenneri"] = 163; - species2index["Caenorhabditis_remanei"] = 164; - species2index["Caenorhabditis_elegans"] = 165; - species2index["Caenorhabditis"] = 166; - species2index["Rhabditoidea"] = 167; - species2index["Rhabditida"] = 168; - species2index["Chromadorea"] = 169; - species2index["Nematoda"] = 170; - species2index["Ecdysozoa"] = 171; - species2index["Protostomia"] = 172; - species2index["Schistosoma_mansoni"] = 173; - species2index["Bilateria"] = 174; - species2index["Nematostella_vectensis"] = 175; - species2index["Eumetazoa"] = 176; - species2index["Amphimedon_queenslandica"] = 177; - species2index["Trichoplax_adhaerens"] = 178; - species2index["Metazoa"] = 179; - species2index["Saccharomyces_cerevisiae_S288c"] = 180; - species2index["Schizosaccharomyces_pombe_972h-"] = 181; - species2index["Ascomycota"] = 182; - species2index["Proterospongia"] = 183; - species2index["Monosiga_brevicollis"] = 184; - species2index["Codonosigidae"] = 185; - species2index["Opisthokonta"] = 186; - species2index["Arabidopsis_thaliana"] = 187; - species2index["Eukaryota"] = 188; - - - var comparison = species2index[a_name] > species2index[b_name]; - //Biojs.console.enable("comparing "+a_name+" ("+species2index[a_name]+") and "+b_name+" ("+species2index[b_name]+") : "+comparison); - return comparison; - }, - - __redraw: function(args){ - var vis = args.vis; - Biojs.console.enable("in zoom"); - //Biojs.console.enable("here", d3.event.translate, d3.event.scale); - //vis.attr("transform", - // "translate(" + d3.event.translate + ")" - //+ " scale(" + d3.event.scale + ")"); - }, - /* - * __readTree in different formats - * @param {string} load_from_variable whether to read the annotation from a file or variable. - * @param {string} data_source file/variable. - * @param {string} format nhx|json. - * - * @example - * myTree.__readTree(); - * - */ - __readAnnotation: function(args){ - var self = this; - var load_from_variable = args.load_from_variable; - var format = args.format; - var data_source = args.data_source; - var data_variable = args.data_variable; - var load_from_web = args.load_from_web; - var json_annotation_data; - Biojs.console.enable("load annotation from web is: "+load_from_variable); - - if(load_from_variable){ - Biojs.console.enable("load from variable selected"); - Biojs.console.enable(data_variable); - //json_tree_data = JSON.parse( - json_annotation_data = JSON.parse(data_variable); - //self.__update({'root' : json_tree_data}); - //self.__update({'root' : tree_data_variable}); - } - else if(load_from_web){ - json_annotation_data = data_variable; - } - - if(format == "json" ){ - Biojs.console.enable("json selected"); - var test_url = data_source; - Biojs.console.enable("loading annotation from "+test_url); - jQuery.ajax({ - url: test_url, - dataType: "json", - async: false, - beforeSend: function(){ - jQuery("#annotation_spinner").show(); - }, - complete: function(){ - jQuery('#annotation_spinner').hide(); - }, - //type: 'POST', - //data: {list_item: selected_from_list}, - - success: function(result){ - Biojs.console.enable("have result"); - //return result; - json_annotation_data = result; - self.annotation_data = result; - self.__update_annotation(json_annotation_data); - //Biojs.console.enable(result); - }, - error: function(){ - alert('Failed to retrieve annotations from '+test_url); - } - - }); - - - //d3.json(tree_data, function(json_tree_data) { - // //gTree.__update(root = json); - // Biojs.console.enable("setting json data from "+tree_data+" "); - // Biojs.console.enable(json_tree_data); - // self.tree_data = json_tree_data; - // some_test = json_tree_data; - // //var pruned_tree = self._iterateTree(json_tree_data); - // Biojs.console.enable(some_test); - // Biojs.console.enable("done with d3.json"); - // return json_tree_data; - // //self.__update(self.opt.root = json_tree_data); - //}); - //Biojs.console.enable("well, we are outside the json read routine"); - //Biojs.console.enable(json_tree_data); - //return json_tree_data; - } - //test - //Biojs.console.enable(json_annotation_data); - return json_annotation_data; - - }, - - - __readNHFormat: function(args){ - var self = this; - var result = args.result; - var json_tree_data; - Biojs.console.enable("have result"); - var x = newick.parse(result); - Biojs.console.enable(x); - var cluster = d3.layout.cluster() - .size([360, 1]) - .sort(null) - .value(function(d) { return d.length; }) - .children(function(d) { return d.branchset; }) - .separation(function(a, b) { return 1; }); - json_tree_data = cluster(x); - var nodes = cluster.nodes(x); - - //Biojs.console.enable(json_tree_data); - //json_tree_data = x; - return json_tree_data; - - - }, - __collapseTree: function(){ - var self = this; - var found_node; - jQuery.each(self.selected_nodes, function(i,d){ - - if(d.name == self.opt.highlight_gene){ - found_node = d; - return false; - } - }); - if(found_node){ - var curr_node = found_node; - - while(parent = curr_node.parent){ - parent.children.forEach(function(d) { - if(d.name === curr_node.name){ - curr_node = parent; - return false; - } - if (d.children) { - d._collapsed_children = get_all_childs(d).length - 1; - d._children = d.children; - d.children = null; - - } - }); - curr_node = parent; - } - } - - self.root = self.selected_nodes[0]; - - self.____update_tree(self.selected_nodes[0]); - self.__update_annotation(); - }, - __readTree: function(args){ - var self = this; - var load_from_variable = args.load_from_variable; - var tree_format = args.tree_format; - var tree_data = args.tree_data; - var tree_data_variable = args.tree_data_variable; - var load_from_web = args.load_from_web; - var json_tree_data; - Biojs.console.enable("load from web is: "+load_from_web); - - if(load_from_variable){ - Biojs.console.enable("load from variable selected"); - Biojs.console.enable(tree_data_variable); - //json_tree_data = JSON.parse( - if(tree_format == "json" ){ - json_tree_data = JSON.parse(tree_data_variable); - } - else{ - Biojs.console.enable("read nh tree"); - json_tree_data = self.__readNHFormat({result : tree_data_variable}); - } - } - else if(load_from_web){ - json_tree_data = tree_data_variable; - } - else if(tree_format == "json" ){ - Biojs.console.enable("json selected"); - - jQuery.ajax({ - url: tree_data, - dataType: "json", - beforeSend: function(){ - jQuery("#tree_spinner").show(); - }, - complete: function(){ - jQuery('#tree_spinner').hide(); - }, - //async: false, - //type: 'POST', - //data: {list_item: selected_from_list}, - - success: function(result){ - Biojs.console.enable("have result"); - json_tree_data = result; - self.root = json_tree_data; - self.all_data= json_tree_data; - - - self.____update_tree(json_tree_data); - // ok, do we read annotations as well? - if(self.opt.two_window){ - Biojs.console.enable("remove spinner"); - jQuery("#tree_spinner").remove; - $('#tree_spinner').remove() - self.domain_data = self.__readAnnotation({load_from_variable: self.opt.load_from_variable,format : "json", - data_source: self.opt.domains_file,data_variable : self.opt.json_domain_string}); - Biojs.console.enable("remove spinner"); - jQuery("#annotation_spinner").remove; - $('#annotation_spinner').remove() - } - else{ - // so annotation is in the tree json - var domains = rects.selectAll(".domain").data(function(d) { return d.domains; }) - self.__update_annotation(); - } - - if(self.opt.highlight_gene){ - self.__collapseTree(); - } - - - } - - }); - - - //d3.json(tree_data, function(json_tree_data) { - // //gTree.__update(root = json); - // Biojs.console.enable("setting json data from "+tree_data+" "); - // Biojs.console.enable(json_tree_data); - // self.tree_data = json_tree_data; - // some_test = json_tree_data; - // //var pruned_tree = self._iterateTree(json_tree_data); - // Biojs.console.enable(some_test); - // Biojs.console.enable("done with d3.json"); - // return json_tree_data; - // //self.__update(self.opt.root = json_tree_data); - //}); - //Biojs.console.enable("well, we are outside the json read routine"); - //Biojs.console.enable(json_tree_data); - //return json_tree_data; - } - else{ - Biojs.console.enable("nh selected"); - var test_url = "../../main/resources/dependencies/data/trees/life.txt"; - Biojs.console.enable("loading tree from "+test_url); - - jQuery.ajax({ - url: test_url, - //dataType: "json", - async: false, - //type: 'POST', - //data: {list_item: selected_from_list}, - - success: function(result){ - Biojs.console.enable("have result"); - json_tree_data = self.__readNHFormat({result : result}); - //var x = newick.parse(result); - //Biojs.console.enable(x); - //var cluster = d3.layout.cluster() - // .size([360, 1]) - // .sort(null) - // .value(function(d) { return d.length !== undefined; }) - // .children(function(d) { return d.branchset !== undefined; }) - // .separation(function(a, b) { return 1; }); - //json_tree_data = cluster(x); - //Biojs.console.enable(json_tree_data); - //json_tree_data = x; - return json_tree_data; - }, - error: function(){ - alert('Failed to retrieve annotations from '+test_url); - } - - }); - - } - - //Biojs.console.enable("end of 'read_tree'") - //Biojs.console.enable(some_test); - Biojs.console.enable(json_tree_data); - - //test - return json_tree_data; - - }, - /* - * Sets controls. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * myTree.__update(); - * - */ - - - _iterateTree: function(obj) { - var self = this; - for(var key in obj) { // iterate, `key` is the property key - var elem = obj[key]; // `obj[key]` is the value - //Biojs.console.enable(key); - if(key === "taxon") { // found "text" property - Biojs.console.enable(elem); - if(elem == "Homo_sapiens"){ - Biojs.console.enable("delete it"); - delete(elem); - } - //count++; - } - - if(typeof elem === "object") { // is an object (plain object or array),// so contains children - self._iterateTree(elem); // call recursively - } - } - return obj; - }, - - - - /* - * clears the div - * - * @example - * myTree.__showModelTree(); - * - */ - _clear_divs: function(){ - jQuery('.added_button').remove(); - jQuery('#tree').empty(); - jQuery('#tree_panel').empty(); - jQuery('#annotation_panel').empty(); - jQuery('#YourOwnDivId').empty(); - - Biojs.console.enable("cleared divs"); - }, - __showModelTree: function(){ - //var full_tree = this.tree_data; - this.opt.modelTreeOn = "on"; - Biojs.console.enable("model tree with "+full_tree.length); - //Biojs.console.enable(full_tree); - this.__update(); - }, - __showFullTree: function(full_tree){ - //var full_tree = this.tree_data; - this.opt.modelTreeOn = ""; - Biojs.console.enable("full tree with "+full_tree.length); - var new_tree_data = this.__readTree({'load_from_variable': this.opt.load_from_variable,'tree_format' : this.opt.formatOptions.tree, - 'tree_data': full_tree,'tree_data_variable' : this.opt.json_tree_string, - 'load_from_web' : this.opt.load_from_web}); - //Biojs.console.enable(full_tree); - var tree_layout = d3.layout.cluster(); - var nodes = tree_layout.nodes(new_tree_data); - // set correct height - var current_size = this.opt.tree.size; - var new_height = nodes.length * 11; - this.opt.tree.size([new_height, this.opt.div_width_half-this.opt.leaf_space]); - d3.select("#"+this.opt.tree_target+" svg").style("height", new_height); - this.__update(new_tree_data); - }, - - - __addAxis: function(args){ - var max_value = args.max_value; - var max_width = args.max_width; - var self = this; - // AXIS - //var annotation_scale = d3.scale.linear().domain([0, max_seq_length+((max_seq_length * 20) / 100)]).range([0, 400]); - max_value = max_value+((max_value * 20) / 100); - Biojs.console.enable("adding axis :max_seq_length "+max_value+" max_width:"+max_width+" max_value: "+max_value); - - var annotation_scale = d3.scale.linear().domain([0, max_value]).range([0, this.opt.max_seq_representation]); - - var xAnnotation_axis = d3.svg.axis().scale(annotation_scale).orient("bottom"); - - - //d3.select("#"+this.opt.target).append("svg") - jQuery('.axis').remove(); - d3.select(".axisarea").append("svg") - //d3.select("#"+this.opt.target+" svg") - //.append("svg") - .attr("class", "axis") - .attr("x", 0) - .attr("y", 0) - .attr("orient", "top") - //.attr("transform", "translate(30,30)") - .call(xAnnotation_axis); - - /*this.opt.vis.append("svg") - .append("text") - // text label for the x axis - .attr("x", 800 ) - .attr("y", 8 ) - .style("text-anchor", "middle") - .text("Sequence length"); */ - - - }, - - - _highlightGeneData: function(test,d){ - var self = this; - - Biojs.console.enable("looking at "+d.name); - var name = d.name; - - //var found_nodes = d3.select(".treearea").selectAll("[taxon="+name+"]"); - - var found_nodes = d3.selectAll(".treearea").selectAll("g.node").filter(function(d) { - return d.taxon == name; - }) - //var found_nodes = self.selected_nodes.filter(function(d){ - // return d.taxon == name - //}) - jQuery.each(found_nodes, function(d){ - //var test = this; - //var group_circle_box = d3.select(d).select("svg circle"); - //group_circle_box.attr("r", 6); - //Biojs.console.enable("looking at node "+d.name); - var this_node = d3.select(this); - this_node.name = "ahhhhh"; - //var d_node = d3.select(d); - - - //var group_circle_box = this_node.select("circle"); - //var group_circle_box2 = d_node.select("circle"); - - //group_circle_box.attr("r", 6); - - //var test = this; - //self._highlightSpeciesData(test,d); - }) - // now have to find species in gene tree - Biojs.console.enable("some test here"); - - }, - - _highlightSpeciesData: function(test,d){ - if(!d.children){ - //Biojs.console.enable("mouseovered a leaf"); - var group_circle_box = d3.select(test).select("svg circle"); - group_circle_box.attr("r", 6); - //var group_image = d3.select(test).select("svg image"); - //group_image.attr("width", 40).attr("height", 40); - //var group_text = d3.select(test).select("svg text"); - //group_text.attr("x", 65); - } - }, - _deHighlightSpeciesData: function(test,d){ - if(!d.children){ - //Biojs.console.enable("mouseovered a leaf"); - var group_circle_box = d3.select(test).select("svg circle"); - //Biojs.console.enable(group_circle_box); - group_circle_box.attr("r", 0); - //var group_image = d3.select(test).select("svg image"); - //group_image.attr("width", 20).attr("height", 20); - //var group_text = d3.select(test).select("svg text"); - //group_text.attr("x", 35); - } - }, - - __set_branchlengths: function(n, offset) { - var self = this; - var plot_domain = self.opt.plottableDomain; - var max_branch_length = self.opt.max_branch_length; - // - // - //Biojs.console.enable(n.name+" has "+n.branch_length); - //if (n.length != null) offset += n.length * 115; - // n.y = offset; - - - if (n.branch_length != null && n.branch_length != "N/A"){ - if(n.branch_length === 0){ - offset += 0; - } - else if(n.depth === 0 ){ - offset += plot_domain(parseFloat(max_branch_length*0.1)); - } - else if( n.branch_length < 0.01){ - //offset += 3; - offset += plot_domain(max_branch_length); - } - else if(n.branch_length > 2){ - //offset += 115; - offset += plot_domain(max_branch_length); - //Biojs.console.enable("found branch_length: offset += n.data.length * 115: "+offset+" += "+n.branch_length); - } - else{ - //offset += n.branch_length * 115; - offset += plot_domain(n.branch_length); - //Biojs.console.enable("found branch_length: offset += n.data.length * 115: "+offset+" += "+n.branch_length); - } - } - else{ - //offset += 100; - offset += plot_domain(max_branch_length); - } - - //if (n.data && n.data.length != null){ - // offset += n.data.length * 115; - //Biojs.console.enable("offset += n.data.length * 115: "+offset+" += "+n.data.length); - //} - //Biojs.console.enable("setting n.y to "+offset); - //offset = plot_domain(offset); - n.y = offset; - var offset_test = offset; - if (n.children) - //Biojs.console.enable("has children"); - n.children.forEach(function(n) { - //Biojs.console.enable(n) - self.__set_branchlengths(n, offset_test); - }); - }, - __show_gene_annotation: function(){ - show_leaf_common_name({target: this.opt.target}); - }, - __show_uniprot_annotation: function(){ - show_leaf_uniprot({target:this.opt.target}); - }, - __toggleAll: function(d) { - if (d.children) { - d.children.forEach(toggle); - //click(d); - } - }, - -// Toggle children. - __toggle: function(d) { - if (d.children) { - d._children = d.children; - d.children = null; - } else { - d.children = d._children; - d._children = null; - } - } , - - __toggle_branchlength: function(){ - // remove everything in annotation div - var all_nodes = jQuery('.annotation_panel .node'); - Biojs.console.enable("Found "+all_nodes.length+" nodes"); - all_nodes.remove(); - Biojs.console.enable("about to toggle branch length is: "+this.opt.show_real_branchlength) - if(this.opt.show_real_branchlength){ - this.opt.show_real_branchlength = false; - } - else{ - this.opt.show_real_branchlength = true; - } - this.____update_tree(); - }, - __show_alignments: function(){ - // remove everything in annotation div - //var all_nodes = jQuery("#annotation_panel").delete; - // jQuery('
                      ').appendTo("#tree_panel"); - //var myNode = document.getElementsByClassName("annotationarea"); - //while (myNode.firstChild) { - // myNode.removeChild(myNode.firstChild); - //} - //this.all_domains = null; - //jQuery('
                      ').appendTo("#tree_panel"); - - this.opt.annotation_option = "alignment"; - Biojs.console.enable("showing alignments now"); - this.__update(); - }, - __show_domains: function(){ - //var full_tree = this.tree_data; - //Biojs.console.enable("about to toggle branch length is: "+this.opt.show_real_branchlength) - //this.opt.show_real_branchlength = "on"; - //jQuery('#annotation_panel').empty(); - //jQuery('#annotation_panel').empty(); - var myNode = document.getElementsByClassName("annotationarea"); - while (myNode.firstChild) { - myNode.removeChild(myNode.firstChild); - } - this.opt.__show_alignments = false; - this.opt.__show_domains = true; - this.opt.annotation_option = "domains"; - - Biojs.console.enable("showing domains now"); - //Biojs.console.enable("model tree with "+full_tree.length); - //Biojs.console.enable(full_tree); - this.__update(); - }, - - __show_bootstrap: function(){ - d3.select("#"+this.opt.target+" svg").selectAll(".bootstrap").attr("visibility", ""); - //d3.select("#tree svg").selectAll(".bootstrap").attr("visibility", ""); - }, - __hide_bootstrap: function(){ - d3.select("#"+this.opt.target+" svg").selectAll(".bootstrap").attr("visibility", "hidden"); - //d3.select("#tree svg").selectAll(".bootstrap").attr("visibility", "hidden"); - }, - __show_taxlevel: function(){ - d3.select("#"+this.opt.target+" svg").selectAll(".innerNode_label").attr("visibility", ""); - //d3.select("#tree svg").selectAll(".innerNode_label").attr("visibility", ""); - }, - __hide_taxlevel: function(){ - d3.select("#"+this.opt.target+" svg").selectAll(".innerNode_label").attr("visibility", "hidden"); - //d3.select("#tree svg").selectAll(".innerNode_label").attr("visibility", "hidden"); - }, - /* - * __updates a tree layout. - * - * @example - * myTree.__update(); - * - */ - ____update_tree: function(source){ - var self = this; - var root = this.root; - var i = 0; - // get tree data - this.opt.tree = d3.layout.cluster(); - var tree = this.opt.tree; - var nodes = tree.nodes(root).reverse(); - - // set correct height - this.opt.height = nodes.length * 11; - // get available width of div - this.opt.div_width = parseInt(d3.select("#"+this.opt.target).style("width")); - if(self.opt.two_window){ - if(this.opt.__show_alignments){ - // setting width of annotation div to max alignment length - this.opt.max_annot_div_width = d3.max(self.alignment_data, function(d) { return +d.alignment_length;} ) * this.opt.alignment_font_size; - } - else{ - div_width = d3.select("#"+self.opt.target).style("width"); - div_width_half = div_width.replace("px",""); - div_width_half = parseInt(div_width_half /2); - this.opt.div_width_half = div_width_half; - this.opt.max_annot_div_width = div_width_half; - this.opt.max_seq_representation = div_width_half; - } - } - // build the svg(s) - // if using two divs/windows, there will be one div to hold the tree and another one to hold the annotation - if (!$('#tree_panel svg').length){ - this._setVisualSpace({'width':div_width,'height':this.opt.height, "two_window": self.opt.two_window, "annot_div_width" : this.opt.max_annot_div_width}); - } - // set visual area to this.opt.vis - var width = this.opt.width - this.padding.left - this.padding.right; - var height = this.opt.height - this.padding.top - this.padding.bottom; - var div_width; - - // - if(self.opt.two_window){ - div_width = parseInt(d3.select("#"+this.opt.tree_target).style("width")); - this.opt.leaf_space = parseInt( div_width/ 4); - //this.opt.tree = d3.layout.cluster() - this.opt.tree - .separation(function(a, b) { - return a.parent === b.parent ? 4 : 4; - }) - .sort(this.__comparator) - .size([height, self.opt.div_width_half-this.opt.leaf_space]); - } - else{ - div_width= parseInt(d3.select("#"+this.opt.target).style("width")) - 400; - this.opt.leaf_space = parseInt( div_width/ 2); - this.opt.tree - .separation(function(a, b) { return a.parent === b.parent ? 4 : 4; }) - .size([height, div_width-this.opt.leaf_space]); - } - this.opt.diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x]; }); - - // define colors used to draw the domains - if(!self.opt.two_window){ - Biojs.console.enable("domaincolors: opt.vis"); - this.__setDomainColors({target : this.opt.vis}); - } - else{ - Biojs.console.enable("domaincolors: opt.annot_panel"); - this.__setDomainColors({target : this.opt.annot_panel}); - } - - var target = d3.select(".treearea"); - var tree_target = d3.select(".treearea"); - var annot_target = d3.select(".annotationarea"); - - //var tree = this.opt.tree; - var nodes = this.opt.tree.nodes(root); - // set correct height - //this.opt.height = nodes.length * 11; - - // get the tree's nodes - var selected_nodes = nodes; - - if(self.opt.formatOptions.tree == "json"){ - Biojs.console.enable("using json in branch length test"); - selected_nodes = nodes.slice(0); - } - else{ - Biojs.console.enable("well, selecting nodes and setting branch lengths"); - selected_nodes = nodes[0].slice(0); - //self.__set_branchlengths(selected_nodes[0], 0); - } - - // from here on --> all nodes should be in self.selected_nodes - self.selected_nodes = selected_nodes; - - selected_nodes = self.selected_nodes; - nodes = self.selected_nodes; - // showing ultrametric tree or using real branch length - // sets the "branch_length" field of each node - if(self.opt.show_real_branchlength){ - Biojs.console.enable("switched on real branch length"); - if(!self.opt.formatOptions.tree === "json"){ - Biojs.console.enable("well, selecting nodes and setting branch lengths"); - selected_nodes = nodes[0].slice(0); - } - self.opt.plottable_tree_space = self.opt.div_width_half-self.opt.leaf_space; - self.opt.max_branch_length= d3.max(selected_nodes, function(d) { return +d.branch_length;} ); - - self.opt.max_depth= d3.max(selected_nodes, function(d) { return +d.depth;} ); - var max_estimated_tree_length = self.opt.max_depth * self.opt.max_branch_length; - self.opt.plottableDomain = d3.scale.linear().domain([0,max_estimated_tree_length]).range([0, self.opt.plottable_tree_space]); - self.__set_branchlengths(selected_nodes[0], 0); - } - self.nodes = nodes; - - /* if(self.opt.two_window){ - Biojs.console.enable("remove spinner"); - jQuery("#tree_spinner").remove; - jQuery("#annotation_spinner").remove; - $('#tree_spinner').remove() - $('#annotation_spinner').remove() - } */ - this.opt.domainScale = d3.scale.linear().domain([0,4000]).range([0, 400]); - this.opt.divScale = d3.scale.linear().domain([0,5]).range([0, this.opt.availablewidth]); - - - // Recompute the layout: __update the nodes - var node = target.selectAll("g.node").data(selected_nodes, function(d) { return d.id || (d.id = ++i); }); - //var node = target.selectAll("g.node").data(tree.nodes(root), function(d) { - // return d.id || (d.id = ++i); - //}); - this.nodeEnter = node.enter().append("svg:g").attr("class", "node") - .on("click", function(d){ - Biojs.console.enable("clicked!!!!"); - //self._focus(d); - Biojs.console.enable("clicked!!!!"); - self._collapseNode(d); - }) - //.on("dblclick", function(d) { self._reset_tree(d) }) - .on("contextmenu", function(d, index) { - var position = d3.mouse(this); - var offsetLeft = document.getElementById("tree_panel").offsetLeft; - var offsetTop = document.getElementById("tree_panel").offsetTop; - var mouse_x =d3.event.x ; - var mouse_y =d3.event.y ; - this.current_d = d; - d3.select('#my_custom_menu') - .style('position', 'absolute') - .style('left', mouse_x + "px") - .style('top', mouse_y + "px") - .style('display', 'block'); - self._buildContextMenu(d); - - d3.event.preventDefault(); - }) - .on("mouseover", function(d){ - var test = this;self._highlightSpeciesData(test,d) - }) - .on("mouseout", function(d){var test = this;self._deHighlightSpeciesData(test,d)}) - // __update the links… - var link = target.selectAll("path.link").data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; }); - - draw_nodes({nodeEnter : this.nodeEnter, node : node, source : self.tree_data , circle_size : this.opt.circle_size,tree_representation_type : this.opt.tree_representation_type, availablewidth : this.opt.availablewidth}); - - var species_silhouette = self.opt.tree_view == "reconciledView"? true: false; - set_links({link: link, link_type : this.opt.link_type, duration : this.opt.duration, species_silhouette : species_silhouette}); - - - // colors based on taxonomy - var subtree_colors = get_subtree_color_data({nodeEnter : this.nodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - jQuery('.clade_tax_rect').remove(); - var color_codes = color_subtrees({subtree_colors : subtree_colors, target : this.opt.target}); - //Biojs.console.enable("here are the color codes: "); - this._addLegend({target : "legend_panel", legend_dictionary : color_codes}) - - // shall we print the species tree silhouette here? - if(self.opt.tree_view == "reconciledView"){ - //collect_data_from_plotted_tree({target : this.opt.target}); - //print_species_tree_silhouette({link: link, link_type : this.opt.link_type, duration : this.opt.duration, species_silhouette : species_silhouette}); - self.____showSpeciesTreeSilhouette({annot_target : annot_target}); - } - - //Biojs.console.enable(color_codes); - - - var how_to_color_hash = get_gene_color_stats({nodeEnter : this.nodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - - - // remove on __update - jQuery('.tax_color_rect').remove(); - - var circles = draw_circles({nodeEnter : this.nodeEnter, circle_size : this.opt.circle_size}); // Draw the little symbols for each node - var images = draw_images({nodeEnter : this.nodeEnter , image_path : this.opt.image_path}); // Draw images for species - - // Bootstrap nodes - - // Draw taxon names (leaf nodes) - var texts = draw_taxon_names({nodeEnter : this.nodeEnter, show_taxa: this.opt.show_taxa,highlight_gene : this.opt.highlight_gene, default_view : this.opt.default_view}); - var bootstrap_texts = draw_bootstraps({nodeEnter : this.nodeEnter, visibility : "hidden"}); // Draw bootstrap values - self.__setTooltips(); - - //self.root.children.forEach(self._toggleAll); - - //collapse nodes - - }, - - - __update: function(source){ - var self = this; - // var root = this.tree_data; - var root = source; - var target = d3.select(".treearea"); - var tree_target = d3.select(".treearea"); - var annot_target = d3.select(".annotationarea"); - //this.opt.target; - var i = 0; - - // tree data - this.opt.tree = d3.layout.cluster(); - var tree = this.opt.tree; - var nodes = tree.nodes(root); - // get the tree's nodes - var selected_nodes; - //nodes.forEach(function(d) { - // if(d.depth == 0){ d.y = 10;} - // else{ - // d.y = d.depth * 180; - // } - // }); - /*if(self.opt.show_lost_taxa){ - Biojs.console.enable("show lost taxa"); - var copy_of_nodes = nodes.slice(0); - for (var i = 0 ; i < nodes.length; i++) { - //Biojs.console.enable(selected_nodes[i]); - var node = nodes[i]; - var name = node.name; - //Biojs.console.enable("node "+name+" has lost taxa and "+node.children.length+" children"); - - if(node.lost_taxa){ - var n = {name: "lost_taxon","branch_length":"1536","taxon":"Danio_rerio","x":95, "y":689,"children":[]}; - //node.children.push(node.lost_taxa); - Biojs.console.enable("node "+name+" has lost taxa"); - //Biojs.console.enable("now "+node.children.length+" children"); - //selected_nodes.push(node.lost_taxa); - - if (node.children){ - node.children.push(n); - } - else{ - node.children = [n]; - } - //Array.prototype.insert = function (index, item) { - // this.splice(index, 0, item); - //}; - var first_part = copy_of_nodes.slice(0,i); - var second_part = copy_of_nodes.slice(i,copy_of_nodes.length); - //selected_nodes.insert(i,n); - var all = first_part.concat(n,second_part); - copy_of_nodes = all.slice(0); - Biojs.console.enable("test"); - - } - //var x = node.x; - //nodeindex[name] = x; - - } - //sdf - nodes = copy_of_nodes.slice(0); - } */ - - /*var n = {id: nodes.length, name : "lost_taxon", taxon: "lost_taxon", type: "leaf"}, - p = nodes[4]; - if (p.children) p.children.push(n); else p.children = [n]; - nodes.push(n); - */ - //self.__set_branchlengths(nodes[0], 0); - // make a copy of all nodes - - if(self.opt.formatOptions.tree == "json"){ - Biojs.console.enable("using json in branch length test"); - selected_nodes = nodes.slice(0); - } - else{ - Biojs.console.enable("well, selecting nodes and setting branch lengths"); - selected_nodes = nodes[0].slice(0); - self.__set_branchlengths(selected_nodes[0], 0); - } - - // from here on --> all nodes should be in self.selected_nodes - - self.selected_nodes = selected_nodes; - nodes = selected_nodes; - self.nodes = nodes; - // showing ultrametric tree or using real branch length - // sets the "branch_length" field of each node - if(self.opt.show_real_branchlength){ - Biojs.console.enable("switched on real branch length"); - self.__set_branchlengths(nodes[0], 0); - } - - if(self.opt.two_window){ - Biojs.console.enable("remove spinner"); - jQuery("#tree_spinner").remove; - jQuery("#annotation_spinner").remove; - $('#tree_spinner').remove() - $('#annotation_spinner').remove() - } - - //Biojs.console.enable(selected_nodes); - // get the max of either - // - length of aligned sequence - // - domain - // - length of unaligned sequence - var max_seq_length, max_value, max_width; - this.__get_max_values(); - // this will add an axis to the top of the annotation panel - if(this.opt.annotation_option && this.opt.annotation_option != "speciestree" && this.opt.two_window){ - this.__addAxis({max_value : this.opt.max_value, max_width: this.opt.max_width}); - } - // since the annotation space is limited, we define a domain that maps all input values to a certain range. - // e.g. an unaligned sequence might be 3432 AA long, so we can do domainScale(3432) and get the value e.g. 374 - // set domain scale - this.opt.domainScale = d3.scale.linear().domain([0,this.opt.max_seq_length]).range([0, this.opt.max_seq_representation]); - this.opt.divScale = d3.scale.linear().domain([0,5]).range([0, this.opt.availablewidth]); - - - // Recompute the layout: __update the nodes - //var node = target.selectAll("g.node").data(selected_nodes, function(d) { return d.id || (d.id = ++i); }); - var node = target.selectAll("g.node").data(tree.nodes(root), function(d) { - return d.id || (d.id = ++i); - }); - this.nodeEnter = node.enter().append("svg:g").attr("class", "node") - //.on("click", function(d){Biojs.console.enable("uff, clicked");self._collapseNode(d);}) - .on("click", function(d){Biojs.console.enable("uff, clicked");self._focus(d);}) - //.on("mouseover", function(d){var test = this;self._highlightSpeciesData(test,d)}) - //.on("mouseout", function(d){var test = this;self._deHighlightSpeciesData(test,d)}) - // __update the links… - var link = target.selectAll("path.link").data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; }); - - draw_nodes({nodeEnter : this.nodeEnter, node : node, source : self.tree_data , circle_size : this.opt.circle_size,tree_representation_type : this.opt.tree_representation_type, availablewidth : this.opt.availablewidth}); - - var species_silhouette = self.opt.tree_view == "reconciledView"? true: false; - set_links({link: link, link_type : this.opt.link_type, duration : this.opt.duration, species_silhouette : species_silhouette}); - - - // colors based on taxonomy - var subtree_colors = get_subtree_color_data({nodeEnter : this.nodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - jQuery('.clade_tax_rect').remove(); - var color_codes = color_subtrees({subtree_colors : subtree_colors, target : this.opt.target}); - //Biojs.console.enable("here are the color codes: "); - this._addLegend({target : "legend_panel", legend_dictionary : color_codes}) - - // shall we print the species tree silhouette here? - if(self.opt.tree_view == "reconciledView"){ - //collect_data_from_plotted_tree({target : this.opt.target}); - //print_species_tree_silhouette({link: link, link_type : this.opt.link_type, duration : this.opt.duration, species_silhouette : species_silhouette}); - self.____showSpeciesTreeSilhouette({annot_target : annot_target}); - } - - //Biojs.console.enable(color_codes); - - - var how_to_color_hash = get_gene_color_stats({nodeEnter : this.nodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - - - // remove on __update - jQuery('.tax_color_rect').remove(); - - var circles = draw_circles({nodeEnter : this.nodeEnter, circle_size : this.opt.circle_size}); // Draw the little symbols for each node - var images = draw_images({nodeEnter : this.nodeEnter , image_path : this.opt.image_path}); // Draw images for species - - // Bootstrap nodes - - // Draw taxon names (leaf nodes) - var texts = draw_taxon_names({nodeEnter : this.nodeEnter, show_taxa: this.opt.show_taxa,highlight_gene : this.opt.highlight_gene, default_view : this.opt.default_view}); - var bootstrap_texts = draw_bootstraps({nodeEnter : this.nodeEnter, visibility : "hidden"}); // Draw bootstrap values - - - - Biojs.console.enable("showing annotation: "+this.opt.annotation_option); - if(this.opt.annotation_option == "speciestree"){ - Biojs.console.enable("showing speciestree"); - self.__showSpeciesTree({annot_target : annot_target}); - } - else if(this.opt.annotation_option == "alignment" - || this.opt.annotation_option == "domains" - || this.opt.annotation_option == "seq_domains"){ - var nodeindex = self.__getNodeIndices({selected_nodes : selected_nodes}); - - switch(this.opt.annotation_option){ - case "alignment": - Biojs.console.enable("adding alignment"); - self.__showAlignments({nodeindex : nodeindex, annot_target : annot_target}); - break; - case "domains": - Biojs.console.enable("adding domains"); - self.__showDomains({nodeindex : nodeindex, annot_target : annot_target}); - break; - case "seq_domains": - Biojs.console.enable("adding seq_domains"); - self.__showSeqDomains({nodeindex : nodeindex, annot_target : annot_target}); - break; - - - default: - Biojs.console.enable("no annotation selected"); - } - } - self.__setTooltips(); - - }, - /* __updates a tree annotationlayout. - * - * @example - * myTree.__update_annotation(); - * - */ - __update_annotation: function(source){ - var self = this; - // var root = this.tree_data; - var annotation_data = self.annotation_data; - var target = d3.select(".treearea"); - var tree_target = d3.select(".treearea"); - var annot_target = d3.select(".annotationarea"); - //this.opt.target; - var i = 0; - self.domain_data = annotation_data; - //Biojs.console.enable(selected_nodes); - // get the max of either - // - length of aligned sequence - // - domain - // - length of unaligned sequence - var max_seq_length, max_value, max_width; - this.__get_max_values({annotation : annotation_data}); - // this will add an axis to the top of the annotation panel - if(this.opt.annotation_option && this.opt.annotation_option != "speciestree" && this.opt.two_window){ - this.__addAxis({max_value : this.opt.max_value, max_width: this.opt.max_width}); - } - // since the annotation space is limited, we define a domain that maps all input values to a certain range. - // e.g. an unaligned sequence might be 3432 AA long, so we can do domainScale(3432) and get the value e.g. 374 - // set domain scale - this.opt.domainScale = d3.scale.linear().domain([0,this.opt.max_seq_length]).range([0, this.opt.max_seq_representation]); - this.opt.divScale = d3.scale.linear().domain([0,5]).range([0, this.opt.availablewidth]); - - - Biojs.console.enable("showing annotation: "+this.opt.annotation_option); - if(this.opt.annotation_option == "speciestree"){ - Biojs.console.enable("showing speciestree"); - self.__showSpeciesTree({annot_target : annot_target}); - } - else if(this.opt.annotation_option == "alignment" - || this.opt.annotation_option == "domains" - || this.opt.annotation_option == "annotation_grid" - || this.opt.annotation_option == "seq_domains"){ - var nodeindex = self.__getNodeIndices({selected_nodes : this.nodes}); - - switch(this.opt.annotation_option){ - case "alignment": - Biojs.console.enable("adding alignment"); - self.__showAlignments({nodeindex : nodeindex, annot_target : annot_target}); - break; - case "domains": - Biojs.console.enable("adding domains"); - self.__showDomains({nodeindex : nodeindex, annot_target : annot_target}); - break; - case "seq_domains": - Biojs.console.enable("adding seq_domains"); - self.__showSeqDomains({nodeindex : nodeindex, annot_target : annot_target}); - break; - case "annotation_grid": - Biojs.console.enable("adding annotation_grid"); - self.__showAnnotationGrid({nodeindex : nodeindex, annot_target : annot_target}); - break; - - - default: - Biojs.console.enable("no annotation selected"); - } - } - self.__setTooltips(); - - }, - - - __get_max_values: function(args){ - var annotation = args.annotation; - if(this.opt.two_window){ - if(this.opt.annotation_option){ - if(this.opt.annotation_option == "seq_domains"){ - this.opt.max_value = d3.max(annotation, function(d) { return +d.alignment_length;} ); - this.opt.max_width = this.opt.max_value; - this.opt.max_seq_length = this.opt.max_value; - } - else{ - this.opt.max_width = d3.max(annotation, function(d) { return +d.seq_length;} ); - this.opt.max_value = this.opt.max_width; - this.opt.max_seq_length = this.opt.max_width; - } - } - } - else{ - this.opt.max_width = d3.max(annotation, function(d) { return +d.seq_length;} ); - this.opt.max_value = this.opt.max_value; - this.opt.max_seq_length = this.opt.max_width; - } - }, - - __getNodeIndices: function(args){ - var selected_nodes = args.selected_nodes; - var nodeindex = new Object(); - //Biojs.console.enable(selected_nodes); - for (var i = 0 ; i < selected_nodes.length; i++) { - //Biojs.console.enable(selected_nodes[i]); - var node = selected_nodes[i]; - var name = node.name; - var x = node.x; - nodeindex[name] = x; - - } - if(nodeindex.length < 1){ - Biojs.console.enable("could not map annotations"); - // need to capture this case - } - return nodeindex; - }, - - __showAlignments: function(args){ - var nodeindex = args.nodeindex; - var annot_target = args.annot_target; - var self = this; - - Biojs.console.enable("nodeindex is: "); - Biojs.console.enable(nodeindex); - - var annot_node = annot_target.selectAll("g.node").data(self.alignment_data); - annot_node.exit().remove(); - this.annot_nodeEnter = annot_node.enter() - .append("svg:g").filter(function(d){ return nodeindex.hasOwnProperty(d.name)}) - .attr("class", "node") - //.on("click", function(d) { __toggle(d); self.__update(d); }) - .on("mouseover", function(d){var test = this;self._highlightSpeciesData(test,d)}) - .on("mouseout", function(d){var test = this;self._deHighlightSpeciesData(test,d)}); - if(self.opt.two_window){ - this.nodeEnter = this.annot_nodeEnter; - } - draw_nodes({two_window:self.opt.two_window, nodeEnter : this.nodeEnter, nodeindex: nodeindex, node : annot_node, source : self.tree_data , tree_representation_type : this.opt.tree_representation_type}); - var alignment_patterns = this.nodeEnter.selectAll("text").data(function(d) { return d.sequence;}) - this.aligned_sequences = draw_alignment_sequences({alignment_patterns: alignment_patterns, - domainScale : this.opt.domainScale , - leaf_group_x : this.opt.leaf_group_x, - sequence_start_y : this.opt.sequence_start_y, - two_window : this.opt.two_window, - nodeindex : nodeindex, - alignment_font_size : this.opt.alignment_font_size, - visibility : ""}); - - - }, - - __showAnnotationGrid: function(args){ - var nodeindex = args.nodeindex; - var annot_target = args.annot_target; - var self = this; - Object.size = function(obj) { - var size = 0, key; - for (key in obj) { - if (obj.hasOwnProperty(key)) size++; - } - return size; - }; - - var size = Object.size(nodeindex); - - // columns are: protein_id, sf_name, definition, organism, gene_id, gene_symbol, molecular function, biological process, cellular component, protein class - // well, which of those do we need? - // expande - var table_html = ""; - jQuery.each(self.annotation_data, function(seq_no,d){ - table_html += ""; - if(d.xref){ - if(d.xref.protein_id){table_html += ""} - else {table_html += ""} - if(d.xref.sf_name){table_html += ""} - else {table_html += ""} - if(d.xref.definition){table_html += ""} - else {table_html += ""} - if(d.xref.gene_id){table_html += ""} - else {table_html += ""} - if(d.xref.molecular_function){table_html += ""} - else {table_html += ""} - if(d.xref.biological_process){table_html += ""} - else {table_html += ""} - if(d.xref.cellular_component){table_html += ""} - else {table_html += ""} - if(d.xref.protein_class){table_html += ""} - else {table_html += ""} - - } - table_html += ""; - }); - table_html += "
                      "+d.xref.protein_id+""+d.xref.sf_name+""+d.xref.definition+""+d.xref.gene_id+""+d.xref.molecular_function+""+d.xref.biological_process+""+d.xref.cellular_component+""+d.xref.protein_class+"
                      "; - jQuery(table_html).appentTo("#annotation_panel"); - - }, - - __showSeqDomains: function(args){ - var nodeindex = args.nodeindex; - var annot_target = args.annot_target; - var self = this; - Object.size = function(obj) { - var size = 0, key; - for (key in obj) { - if (obj.hasOwnProperty(key)) size++; - } - return size; - - - // bind data to nodes - var annot_node = annot_target.selectAll("g.node").data(self.annotation_data); - // enter selection - this.annot_nodeEnter = annot_node.enter() - .append("svg:g").filter(function(d){ - var test = d; - if(nodeindex.hasOwnProperty(d.name)){ - Biojs.console.enable("take "+d.name); - } - else{ - Biojs.console.enable("could not map "+d.name); - } - return nodeindex.hasOwnProperty(d.name)}) - .attr("class", "xref_node") - - // exit selection - annot_node.exit().remove(); - if(self.opt.two_window){ - this.nodeEnter = this.annot_nodeEnter; - } - // draw conservation patterns - var alignment_length = this.opt.max_value; - //var rects = this.annot_nodeEnter.filter(function(d){ return typeof d.children == 'undefined' }); - draw_xref_nodes({two_window:self.opt.two_window, nodeEnter : this.nodeEnter, nodeindex: nodeindex, node : annot_node, source : self.tree_data , tree_representation_type : this.opt.tree_representation_type}); - - }; - - var size = Object.size(nodeindex); - var offset_dictionary = {}; - Biojs.console.enable("looking at the domains, nodeindex: "+size); - //Biojs.console.enable(nodeindex); - Biojs.console.enable(self.domain_data); - var alignment_length; - - /* - todo: save offset mapping for each seq. - this will be used for mapping the domains correctly. - Given: domain start+end: 34-114 - want: start+stop coordinates mapped onto alignment - todo: foreach position in alignment count number of gaps until here - dict[curr_pos-gaps] = curr_pos - */ - var offset_dictionary = {}; - jQuery.each(self.domain_data, function(seq_no,d){ - var gap_counter = 0, - real_position= 1, - cigar_array = []; - if(d.cigar_string){ - var offset = 0; // this is to plot the rects next to each other - var result = d.cigar_string.match(/(\d*\w)/g); - //for (var set = 0; set < result.length; set++) { - for (var set = 0; set < result.length; set++) { - var submatch = result[set].match(/(\d*)(\w)/), - length, - cigar_type = submatch[2]; - if(submatch[1]){ - // there was a number for this cigar state - length = parseInt(submatch[1]); - } - else{ - length = 1; - } - if(cigar_type.toLowerCase() === "d"){ - gap_counter += length; - } - if(cigar_type.toLowerCase() === "m"){ - for (var j=0; j < length; j++){ - if(offset_dictionary[d.name] === undefined){ - offset_dictionary[d.name] = {}; - } - var new_real_position = j+real_position; - offset_dictionary[d.name][new_real_position] = gap_counter + new_real_position; - - } - real_position +=length; - cigar_array.push({"type": cigar_type, "length": length, "offset" : offset}); - } - offset = offset + length; - } - //alignment_length = offset; - } - // change the coordinates of the domains - if(d.domains){ - jQuery.each(d.domains, function(iteration,domain){ - if(offset_dictionary[d.name] !== undefined){ - domain.domain_start = offset_dictionary[d.name][domain.domain_start]; - domain.domain_stop = offset_dictionary[d.name][domain.domain_stop]; - } - }); - } - d.cigar_array = cigar_array; - }) - - this.opt.cigarScale = d3.scale.linear().domain([0,this.opt.max_value]).range([0, this.opt.max_seq_representation]); - var annot_node = annot_target.selectAll("g.node").data(self.domain_data); - // enter selection - this.annot_nodeEnter = annot_node.enter() - .append("svg:g").filter(function(d){ - var test = d; - if(nodeindex.hasOwnProperty(d.name)){ - Biojs.console.enable("take "+d.name); - } - else{ - Biojs.console.enable("could not map "+d.name); - } - return nodeindex.hasOwnProperty(d.name)}) - .attr("class", "node") - .on("mouseover", function(d){var test = this;self._highlightSpeciesData(test,d)}) - .on("mouseout", function(d){var test = this;self._deHighlightSpeciesData(test,d)}); - - // exit selection - annot_node.exit().remove(); - //Biojs.console.enable(this.annot_nodeEnter); - if(self.opt.two_window){ - this.nodeEnter = this.annot_nodeEnter; - } - // draw conservation patterns - var alignment_length = this.opt.max_value; - //var rects = this.annot_nodeEnter.filter(function(d){ return typeof d.children == 'undefined' }); - draw_nodes({two_window:self.opt.two_window, nodeEnter : this.nodeEnter, nodeindex: nodeindex, node : annot_node, source : self.tree_data , tree_representation_type : this.opt.tree_representation_type}); - var rects = draw_cigar_borders({nodeEnter: this.nodeEnter, - domainScale : this.opt.cigarScale , - leaf_group_x : this.opt.leaf_group_x+2, - sequence_start_y : this.opt.sequence_start_y, - two_window : this.opt.two_window, - nodeindex : nodeindex, - visibility : "", - alignment_length: alignment_length}); - - - var cigars = rects.selectAll(".cigar_rect").data(function(d) { return d.cigar_array}); - - //draw_nodes({two_window:self.opt.two_window, nodeEnter : this.nodeEnter, nodeindex: nodeindex, node : annot_node, source : self.tree_data , tree_representation_type : this.opt.tree_representation_type}); - - var cigar_rects = draw_cigar_sequences({domains: cigars, - domainScale : this.opt.cigarScale, - leaf_group_x : this.opt.leaf_group_x+4, - sequence_rect_width : this.opt.sequence_rect_width - 4, - sequence_start_y : this.opt.sequence_start_y, - two_window : this.opt.two_window, - nodeindex : nodeindex, - visibility : "" - }); - // Domains - var domains = rects.selectAll(".domain").data(function(d) { return d.domains; }) - var leaves = rects.selectAll(".leaf_label"); - //Biojs.console.enable(domains); - //Biojs.console.enable(" after specified domains/leaves"); - //this.opt.domainScale = d3.scale.linear().domain([0,this.opt.max_seq_length]).range([0, this.opt.max_seq_representation]); - this.all_domains = draw_domains({domains : domains, sequence_start_y : this.opt.sequence_start_y, - domainScale: this.opt.cigarScale, sequence_rect_width : this.opt.sequence_rect_width, - two_window : this.opt.two_window, - leaf_group_x : this.opt.leaf_group_x,domain_colors : this.opt.domain_colors,visibility: "" }); - - }, - - __showDomains: function(args){ - var nodeindex = args.nodeindex; - var annot_target = args.annot_target; - var self = this; - - - Object.size = function(obj) { - var size = 0, key; - for (key in obj) { - if (obj.hasOwnProperty(key)) size++; - } - return size; - }; - - var size = Object.size(nodeindex); - - // binding data - var annot_node = annot_target.selectAll("g.node").data(self.domain_data); - this.annot_nodeEnter = annot_node.enter() - .append("svg:g").filter(function(d){ - //if(nodeindex.hasOwnProperty(d.name)){ Biojs.console.enable("take "+d.name); } - return nodeindex.hasOwnProperty(d.name)}) - .attr("class", "node") - .on("mouseover", function(d){var test = this;self._highlightSpeciesData(test,d)}) - .on("mouseout", function(d){var test = this;self._deHighlightSpeciesData(test,d)}); - - annot_node.exit().remove(); - if(self.opt.two_window){ - this.nodeEnter = this.annot_nodeEnter; - } - draw_nodes({two_window:self.opt.two_window, nodeEnter : this.nodeEnter, nodeindex: nodeindex, node : annot_node, source : self.tree_data , tree_representation_type : this.opt.tree_representation_type}); - var rects = draw_sequences({nodeEnter: this.nodeEnter, - domainScale : this.opt.domainScale , - leaf_group_x : this.opt.leaf_group_x, - sequence_start_y : this.opt.sequence_start_y, - two_window : this.opt.two_window, - nodeindex : nodeindex, - visibility : ""}); - // - - Biojs.console.enable("after sequence drawn"); - - // Domains - var domains = rects.selectAll(".domain").data(function(d) { return d.domains; }) - var leaves = rects.selectAll(".leaf_label"); - //Biojs.console.enable(domains); - //Biojs.console.enable(" after specified domains/leaves"); - Biojs.console.enable("setting domainscale to "+this.opt.max_seq_length); - this.opt.domainScale = d3.scale.linear().domain([0,this.opt.max_seq_length]).range([0, this.opt.max_seq_representation]); - Biojs.console.enable(" after domainscale"); - this.all_domains = draw_domains({domains : domains, sequence_start_y : this.opt.sequence_start_y, - domainScale: this.opt.domainScale, sequence_rect_width : this.opt.sequence_rect_width, - two_window : this.opt.two_window, - leaf_group_x : this.opt.leaf_group_x,domain_colors : this.opt.domain_colors,visibility: "" }); - - }, - - ____showSpeciesTreeSilhouette: function(args){ - var annot_target = args.annot_target; - var right2left = false; - var class_type_path = "species_link"; - var class_type_node = "species_node"; - var i = 0; - Biojs.console.enable("before reading tree") - this.species_tree_data = this.__readTree({'load_from_variable': this.opt.load_from_variable,'tree_format' : this.opt.formatOptions.tree, - 'tree_data': this.opt.species_tree,'tree_data_variable' : this.opt.json_tree_string, - 'load_from_web' : this.opt.load_from_web}); - - var temp_tree = d3.layout.cluster(); - - var temp_nodes = temp_tree.nodes(this.species_tree_data); - // set correct height - //var species_height = this.opt.species_nodes * 11; - var species_height = temp_nodes.length * 11; - jQuery("#annotation_svg_container").height(species_height); - Biojs.console.enable("d3.layout.cluster: "+species_height+", "+this.opt.div_width_half+"-"+this.opt.leaf_space+""); - - var available_width = this.opt.div_width_half-this.opt.leaf_space; - var species_tree = d3.layout.cluster() - .separation(function(a, b) { return a.parent === b.parent ? 4 : 4; }) - .size([species_height , available_width ]); - Biojs.console.enable("read tree"); - Biojs.console.enable(this.species_tree_data); - - // get the tree's nodes - var species_nodes = species_tree.nodes(this.species_tree_data); - - - - - var species_node = annot_target.selectAll("g.node").data(species_nodes, function(d) { - var value = d.id || (d.id = ++i); - return value; - }); - - this.speciesnodeEnter = species_node.enter().append("svg:g").attr("class", "node"); - - draw_nodes({nodeEnter : this.speciesnodeEnter, node : species_node, source : this.species_tree_data, - right2left : right2left, - circle_size : this.opt.circle_size,tree_representation_type : this.opt.tree_representation_type, availablewidth : this.opt.div_width_half}); - // __update the links… - var link = annot_target.selectAll("path."+class_type_path).data(species_tree.links(species_nodes), function(d) { return d.target.id; }); - - set_links({link: link, link_type : this.opt.link_type, duration : this.opt.duration, right2left : right2left, availablewidth : this.opt.div_width_half, - species_silhouette: true, class_type : class_type_path, opacity: 0.3, node_thickness : 30}); - //var species_subtree_colors = get_subtree_color_data({nodeEnter : this.speciesnodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.annot_target}); - //jQuery('.clade_tax_rect').remove(); - //var species_color_codes = color_subtrees({subtree_colors : species_subtree_colors, target : this.opt.annot_target, right2left : right2left}); - //Biojs.console.enable("here are the color codes: "); - //Biojs.console.enable(color_codes); - - //this._addLegend({target : "legend_panel", legend_dictionary : color_codes}) - //var how_to_color_hash = get_gene_color_stats({nodeEnter : this.speciesnodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - - - // remove on __update - //jQuery('.tax_color_rect').remove(); - // Draw the little symbols for each node - //var circles = draw_circles({nodeEnter : this.speciesnodeEnter, circle_size : this.opt.circle_size}); - // Draw images for species - //var images = draw_images({nodeEnter : this.speciesnodeEnter , image_path : this.opt.image_path, right2left : right2left}); - // Bootstrap nodes - // Draw taxon names (leaf nodes) - //var texts = draw_taxon_names({nodeEnter : this.speciesnodeEnter, show_taxa: this.opt.show_taxa, - // right2left : right2left,highlight_gene : this.opt.highlight_gene, model_organisms : this.opt.model_organisms}); - // Draw bootstrap values - //var bootstrap_texts = draw_bootstraps({nodeEnter : this.speciesnodeEnter, visibility : "hidden"}); - - }, - - __showSpeciesTree: function(args){ - var annot_target = args.annot_target; - var class_type_path = "species_link"; - var class_type_node = "species_node"; - var right2left = true; - var self = this; - Biojs.console.enable("before reading tree") - this.species_tree_data = this.__readTree({'load_from_variable': this.opt.load_from_variable,'tree_format' : this.opt.formatOptions.tree, - 'tree_data': this.opt.species_tree,'tree_data_variable' : this.opt.json_tree_string, - 'load_from_web' : this.opt.load_from_web}); - - - var species_height = this.opt.species_nodes * 5; - jQuery("#annotation_svg_container").height(species_height); - Biojs.console.enable("d3.layout.cluster: "+species_height+", "+this.opt.div_width_half+"-"+this.opt.leaf_space+""); - - var available_width = this.opt.div_width_half-this.opt.leaf_space; - var species_tree = d3.layout.cluster() - .separation(function(a, b) { return a.parent === b.parent ? 1 : 1; }) - .size([species_height , available_width ]); - - Biojs.console.enable("read tree"); - Biojs.console.enable(this.species_tree_data); - - // get gt node data - var geneNode2Coordinate = {}; - var speciesNode2Path = []; - - self._getGTNodeInfo({speciesNode2Path: speciesNode2Path, geneNode2Coordinate : geneNode2Coordinate}) - - - // get the tree's nodes - var species_nodes = species_tree.nodes(this.species_tree_data); - var i = 0; - var species_node = annot_target.selectAll("g.node").data(species_nodes, function(d) { return d.id || (d.id = ++i); }); - - this.speciesnodeEnter = species_node.enter().append("svg:g").attr("class", "node") - .on("mouseover", function(d){ - var test = this; - self._highlightGeneData(test,d) - }); - - draw_nodes({nodeEnter : this.speciesnodeEnter, node : species_node, source : this.species_tree_data , - right2left : right2left, - circle_size : this.opt.circle_size,tree_representation_type : this.opt.tree_representation_type, availablewidth : this.opt.div_width_half}); - // __update the links… - var link = annot_target.selectAll("path.link").data(species_tree.links(species_nodes), function(d) { return d.target.id; }); - - // ok, we want to show branches leading to species not in the gene tree with different lines - - set_links({link: link, link_type : this.opt.link_type, duration : this.opt.duration, right2left : right2left, availablewidth : this.opt.div_width_half, - class_type : class_type_path, genePresence: geneNode2Coordinate}); - //var species_subtree_colors = get_subtree_color_data({nodeEnter : this.speciesnodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.annot_target}); - //jQuery('.clade_tax_rect').remove(); - //var species_color_codes = color_subtrees({subtree_colors : species_subtree_colors, target : this.opt.annot_target, right2left : right2left}); - //Biojs.console.enable("here are the color codes: "); - //Biojs.console.enable(color_codes); - - //this._addLegend({target : "legend_panel", legend_dictionary : color_codes}) - //var how_to_color_hash = get_gene_color_stats({nodeEnter : this.speciesnodeEnter, highlight_gene : this.opt.highlight_gene, target : this.opt.target}); - - - // remove on __update - //jQuery('.tax_color_rect').remove(); - // Draw the little symbols for each node - var circles = draw_circles({nodeEnter : this.speciesnodeEnter, circle_size : this.opt.circle_size}); - // Draw images for species - //var images = draw_images({nodeEnter : this.speciesnodeEnter , image_path : this.opt.image_path, right2left : right2left}); - // Bootstrap nodes - // Draw taxon names (leaf nodes) - var texts = draw_taxon_names({nodeEnter : this.speciesnodeEnter, show_taxa: this.opt.show_taxa, - right2left : right2left,highlight_gene : this.opt.highlight_gene, model_organisms : this.opt.model_organisms, - genePresence : geneNode2Coordinate}); - // Draw bootstrap values - //var bootstrap_texts = draw_bootstraps({nodeEnter : this.speciesnodeEnter, visibility : "hidden"}); - - - // now we save the coordinates for gene tree and species tree nodes - var geneNode2Coordinate = {}; - var speciesNode2Path = []; - self.selected_nodes.forEach(function(d) { - var coordinates = {"y":d.y, "x":d.x}; - geneNode2Coordinate[d.taxon] = coordinates; - /*if(geneNode2Coordinate.hasOwnProperty(d.taxon)){ - var tmp_array = []; - tmp_array = geneNode2Coordinate[d.taxon]; - tmp_array.push(coordinates); - geneNode2Coordinate[d.taxon] = tmp_array; - } - else{ - var tmp_array = []; - tmp_array.push(coordinates); - geneNode2Coordinate[d.taxon] = coordinates; - }*/ - //d.y = d.depth * 180; - }); - /*species_nodes.forEach(function(d) { - - var species_name = d.name; - if(geneNode2Coordinate.hasOwnProperty(species_name)){ - var gene4species = geneNode2Coordinate[species_name]; - if(gene4species){ - var path_coord = { - "species_name":species_name, - "source": {"x":d.x,"y": d.y}, - "target": {"x":gene4species.x, "y":gene4species.y} - } - speciesNode2Path.push(path_coord); - } - } - else{ - //Biojs.console.enable("skipping "+species_name); - - } - });*/ - - // on mouseover - // - // var btw_link = d3.select("#"+self.opt.target).selectAll("path.link").data(speciesNode2Path); - // set_links({link: btw_link, link_type : this.opt.link_type, duration : this.opt.duration, right2left : right2left, availablewidth : this.opt.div_width_half}); - // return speciesNode2Path; - - }, - _getGTNodeInfo: function(args){ - var self = this; - - var geneNode2Coordinate = args.geneNode2Coordinate; - var speciesNode2Path = args.speciesNode2Path; - self.selected_nodes.forEach(function(d) { - var coordinates = {"y":d.y, "x":d.x}; - geneNode2Coordinate[d.taxon] = coordinates; - /*if(geneNode2Coordinate.hasOwnProperty(d.taxon)){ - var tmp_array = []; - tmp_array = geneNode2Coordinate[d.taxon]; - tmp_array.push(coordinates); - geneNode2Coordinate[d.taxon] = tmp_array; - } - else{ - var tmp_array = []; - tmp_array.push(coordinates); - geneNode2Coordinate[d.taxon] = coordinates; - }*/ - //d.y = d.depth * 180; - }); - /*species_nodes.forEach(function(d) { - - var species_name = d.name; - if(geneNode2Coordinate.hasOwnProperty(species_name)){ - var gene4species = geneNode2Coordinate[species_name]; - if(gene4species){ - var path_coord = { - "species_name":species_name, - "source": {"x":d.x,"y": d.y}, - "target": {"x":gene4species.x, "y":gene4species.y} - } - speciesNode2Path.push(path_coord); - } - } - else{ - //Biojs.console.enable("skipping "+species_name); - - } - });*/ - - }, - - __setTooltips: function(){ - add_tipsy({where : ".leaf_label", default_view:this.opt.default_view}); - add_tipsy({where : ".domain", default_view:this.opt.default_view}); - add_tipsy({where : ".clade_tax_rect", default_view:this.opt.default_view}); - - }, - - /* - * Sets controls. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * myTree.setControls(); - * - */ - __setControls: function(){}, - - /* - * Sets domain colors. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * myTree.__setDomainColors(); - * - */ - __setDomainColors: function(arg){ - var target = arg.target; - Biojs.console.enable("set domain colors to: "+target); - var domain_colors = new Object(); - domain_colors[0] = "domain_gradient"; - domain_colors[1] = "domain_gradient2"; - domain_colors[2] = "domain_gradient3"; - domain_colors[3] = "domain_gradient4"; - domain_colors[4] = "domain_gradient5"; - domain_colors[5] = "domain_gradient6"; - var gradient = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "line_gradient") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "0").attr("x2", "2").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#999999"); - gradient.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "40%").attr("stop-color", "#eeeeee"); - gradient.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#cccccc"); - gradient.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#999999"); - - var gradient2 = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "domain_gradient") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "1").attr("x2", "6.12").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient2.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#FF8585"); - gradient2.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "50%").attr("stop-color", "#7a1e74"); - gradient2.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#7a1e74"); - gradient2.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#ffffff"); - - var gradient3 = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "domain_gradient2") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "1").attr("x2", "6.12").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient3.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#0099CC"); - gradient3.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "50%").attr("stop-color", "#7a1e74"); - gradient3.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#7a1e74"); - gradient3.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#ffffff"); - - var gradient4 = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "domain_gradient3") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "1").attr("x2", "6.12").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient4.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#CCF2CC"); - gradient4.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "50%").attr("stop-color", "#7a1e74"); - gradient4.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#7a1e74"); - gradient4.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#ffffff"); - - var gradient5 = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "domain_gradient4") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "1").attr("x2", "6.12").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient5.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#14101f"); - gradient5.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "50%").attr("stop-color", "#7a1e74"); - gradient5.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#7a1e74"); - gradient5.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#ffffff"); - - var gradient6 = target.append("svg:defs").append("svg:linearGradient") - .attr("id", "domain_gradient5") - .attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("x1", "0").attr("y1", "1").attr("x2", "6.12").attr("y2", "0").attr("gradientTransform", "matrix(1,0,0,1,0,0)"); - gradient6.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "0%").attr("stop-color", "#623e32"); - gradient6.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "50%").attr("stop-color", "#7a1e74"); - gradient6.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "60%").attr("stop-color", "#7a1e74"); - gradient6.append("svg:stop").attr("webkit-tap-highlight-color", "rgba(0, 0, 0, 0)").attr("offset", "100%").attr("stop-color", "#ffffff"); - - this.opt.domain_colors = domain_colors; - }, - - - - _collapseNode: function(d){ - //var d = arg.d; - Biojs.console.enable("collapsing "+d.name); - //d3.select(d).append("svg:circle") - // .attr("r", function(d){ - // return d.children ? circle_size : 0; }) - // .attr("fill", function(d){return d.duplication == "Y"? "red":"green"}) - if (d.children) { - d._collapsed_children = get_all_childs(d).length - 1; - d._children = d.children; - d.children = null; - - } else { - d.children = d._children; - d._children = null; - } - this.____update_tree(d); - this.__update_annotation(d); - }, - __expandNode: function(arg){}, - - - /* - * Get maximal length of domain/aligned_seq. - * @param {array} leaves The leaves of the tree with annotated domains. - * - * @example - * myTree.__getMaxSeqLength(); - * - */ - __getMaxSeqLength: function(args){ - var self = this; - var leaves = args.leaves; - var max_seq_length; - Biojs.console.enable("looking at "+leaves.length+" leaves"); - for (var i = 0; i < leaves.length; i++) { - Biojs.console.enable("first leaf is: "); - Biojs.console.enable(leaves[i]); - Biojs.console.enable(leaves[i].seq_length); - var temp_x, temp_y; - var temp_seq_length = leaves[i].seq_length; - - if ( temp_seq_length >= max_seq_length ) { max_seq_length = temp_seq_length; } - - } - return max_seq_length; - }, - - /* - * Sets model organism. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * myTree.__setModelOrganisms(); - * - */ - __setModelOrganisms: function (){ - - var model_organisms = new Object(); // or just {} - model_organisms['Homo_sapiens'] = "red"; - model_organisms['Pan_troglodytes'] = "red"; - - model_organisms['Mus_musculus'] = "blue"; - model_organisms['Xenopus_tropicalis'] = "blue"; - model_organisms['Gallus_gallus'] = "blue"; - model_organisms['Drosophila_melanogaster'] = "blue"; - model_organisms['Arabidopsis_thaliana'] = "blue"; - model_organisms['Caenorhabditis_elegans'] = "blue"; - - this.opt.model_organisms = model_organisms; - }, - - - - /* - * Prunes a tree given a selected subset of species - * @param {string} a list of nodes of the tree. - * - * @example - * myTree._pruneTree(); - * - */ - _pruneTree: function (selected_nodes) { - var self = this; - var children2hide = new Object(); - var nodes2delete = new Array(); - for (var i = selected_nodes.length; i >= 0; i--) { - if(!selected_nodes[i]){ - Biojs.console.enable("could not look at node "+i); - continue; - } - var node = selected_nodes[i]; - var name = selected_nodes[i].name; - var parent = node.parent; - var taxon = selected_nodes[i].taxon; - - Biojs.console.enable("Looking at node: "+name+" taxon: "+taxon); - //continue; - // Leaf - if(!node.children){ - Biojs.console.enable("is a leaf"); - } - // can implement inner node deletions here - //if(!self.opt.innerNodes[taxon] && node.children){ - if(!self.opt.model_organisms[taxon] && !node.children){ - //Biojs.console.enable("should be deleted"); - // tell parent - var parent = node.parent; - if (typeof parent.children2hide == 'undefined' || parent.children2hide.length == 0) { - //Biojs.console.enable("creating empty children2hash in parent: "+parent.name); - parent.children2hide = {}; - } - parent.children2hide[name] = 1; - //Biojs.console.enable("adding node "+name+" to be deleted in parent: "+parent.name); - selected_nodes.splice(i, 1); - //nodes2delete.push(node); - } - else{ - //Biojs.console.enable("keep it"); - } - //} - //else{ - // Inner Node - Biojs.console.enable("is a innerNode"); - //Biojs.console.enable("list of children2hide"); - //Biojs.console.enable(node.children2hide); - //Biojs.console.enable("list of children2add"); - //Biojs.console.enable(node.children2add); - Biojs.console.enable(node.children2hide); - Biojs.console.enable(node.children2add); - if(node.children2hide){ - // since we are changing a node's children, let's make a backup. - node._children = node.children; - var size = 0, key; - for (key in node.children2hide) { - if (node.children2hide.hasOwnProperty(key)) size++; - } - //Biojs.console.enable("has "+node.children.length+" children and to hide: "+size); - if(size == node.children.length && typeof node.parent != 'undefined'){ - Biojs.console.enable("hide all children"); - // hide children (d3 will look for .children by default) - node.children = null; - // tell the parent about this - if (typeof parent.children2hide == 'undefined' || parent.children2hide.length == 0) { - //Biojs.console.enable("creating empty children2hash in parent: "+parent.name); - parent.children2hide = {}; - } - Biojs.console.enable("splice current node from selected nodes"); - parent.children2hide[name] = 1; - //selected_nodes.splice(i, 1); - //nodes2delete.push(node); - - // tell parent - //Biojs.console.enable("now we have: 0 nodes"); - } - else{ - //hide only a few nodes - //Biojs.console.enable("looping over "+node.children.length+" children"); - //Biojs.console.enable(node.children); - - var copy_of_children = node.children.slice(0); - for (var j = 0 ; j < node.children.length; j++) { - var curr_child = node.children[j]; - var child_name = node.children[j].name; - Biojs.console.enable("looking at child: "+child_name); - if(node.children2hide[child_name]){ - Biojs.console.enable("slicing it no: "+j+" out!") - copy_of_children.splice(j, 1); - } - //else{ - //} - } - // now copy back to children - node.children = copy_of_children.slice(0); - // do we need to copy a child child here? - // in case we deleted a child node and there is only one left (A) - // -> mark current node as to be deleted from parent.children - // but give him a copy of the current child node A - } - } - - if(node.children2add){ - - var size_children2add = 0 - for (key in node.children2add) { - if (node.children2add.hasOwnProperty(key)) size_children2add++; - } - //for(var k=0; k < node.children2add.length; k++){ - - //if (typeof node.children == 'undefined' || node.children.length == 0) { - // Biojs.console.enable("setting children to 0"); - // node.children = []; - //} - node.children = ( typeof node.children != 'undefined' && node.children instanceof Array ) ? node.children : []; - - for (key in node.children2add) { - //Biojs.console.enable("will add node "+key) - node.children.push(node.children2add[key]); - } - //Biojs.console.enable("has "+node.children.length+" children and to add: "+size_children2add); - //Biojs.console.enable("afterwards has "+node.children.length+" children"); - } - - if(typeof node.children != 'undefined' && node.children instanceof Array){ - Biojs.console.enable("now we have: "+node.children.length+" nodes"); - if(node.children.length == 1 && typeof node.parent != 'undefined'){ - if (typeof parent.children2add == 'undefined' || parent.children2add.length == 0) { - //Biojs.console.enable("adding empty children2add array"); - parent.children2add = {}; - } - //Biojs.console.enable("well, let's keep node "+node.children[0].name+" in the parent"); - parent.children2add[node.children[0].name] = node.children[0]; - //Biojs.console.enable("ok, we tell the parent "+parent.name+" to add child "+curr_child.name); - //Biojs.console.enable(parent.children2add); - - Biojs.console.enable("wow, just one child. tell my parent to hide/ignore this inner node!"); - if (typeof parent.children2hide == 'undefined' || parent.children2hide.length == 0) { - //Biojs.console.enable("creating empty children2hash in parent: "+parent.name); - parent.children2hide = {}; - } - parent.children2hide[name] = 1; - Biojs.console.enable("splice current node from selected nodes"); - selected_nodes.splice(i, 1); - //nodes2delete.push(node); - } - } - //if(typeof node.children == 'undefined' && node.children instanceof Array){ - //} - } - - Biojs.console.enable("done with the nodes"); - - //Biojs.console.enable("have to delete "+nodes2delete.length+" nodes"); - //for (var i = 0; i < nodes2delete.length; ++i) { - // var obj = nodes2delete[i]; - // Biojs.console.enable("delete: "+obj.name); - //} - //sdsdad - - // get a list of leaf - - //var selected_nodes = selected_nodes - /* Biojs.console.enable("showing model tree only"); - var filtered_nodes = copy_of_nodes.filter(function(d){ - - var current_node = d; - var taxon = d.taxon; - - // is leaf node - if(!d.children){ - if(!self.opt.model_organisms[taxon]){ - var parent = d.parent; - if(parent.children){ - var i = 0; - while(i < parent.children.length) { - var data = parent.children[i].taxon; - if(!self.opt.model_organisms[data]){ - var child = parent.children.splice(i,1); - } - else{i++;} - } - Biojs.console.enable("parent now has: "+parent.children+" childen"); - if(!parent.children){ - var parent_of_parent - } - } - } - else{ - return d; - } - } - else{ - return d; - } - }); */ - - function prune(array, label) { - for (var i = 0; i < array.length; ++i) { - var obj = array[i]; - var taxon = obj.taxon; - Biojs.console.enable("looking at taxon: "+taxon); - if (taxon === label) { - //if(!self.opt.model_organisms[taxon]){ - // splice out 1 element starting at position i - array.splice(i, 1); - //return true; - //continue; - Biojs.console.enable("found label: "+taxon); - } - if (typeof obj.children !== 'undefined' && obj.children.length > 0) { - var no_children = obj.children.length; - obj.node_type = "innerNode"; - Biojs.console.enable("internal node with "+no_children+" children"); - Biojs.console.enable("node_type is "+obj.node_type); - if (prune(obj.children, label)) { - if (obj.children.length === 0) { - // delete children property when empty - //delete obj.children; - obj._children = obj.children; - obj.children = null; - - } - return true; - } - } - else{ - if(obj.node_type == "innerNode"){ - Biojs.console.enable("is an innerNode, but is empty. splicing i:"+i); - array.splice(i, 1); - } - Biojs.console.enable("must be a leaf"); - } - - } - } - //var wasItPruned = prune(selected_nodes, "Pan_troglodytes"); - //var wasItPruned = prune(selected_nodes, "Homo_sapiens"); - //var wasItPruned = prune(selected_nodes, "Homininae"); - //var wasItPruned = prune(copy_of_nodes, "Pan_troglodytes"); - //var wasItPruned = prune(copy_of_nodes, "Pongo_abelii"); - //var wasItPruned = prune(copy_of_nodes, "Gorilla_gorilla"); - //var wasItPruned = prune(copy_of_nodes, "Tarsius_syrichta"); - //var wasItPruned = prune(copy_of_nodes, "Tupaia_belangeri"); - //var wasItPruned = prune(copy_of_nodes, "Microcebus_murinus"); - //var wasItPruned = prune(copy_of_nodes, "Otolemur_garnettii"); - //var wasItPruned = prune(copy_of_nodes, "Callithrix_jacchus"); - //var wasItPruned = prune(copy_of_nodes, "Macaca_mulatta"); - - }, - _focus: function(d) { - var self = this; - - // determine the subset of - if(self.current_d){ - self.root = self.current_d; - } - else{ - self.root = d; - } - self.____update_tree(); - } - , - _reset_tree: function(d) { - var self = this; - - // determine the subset of - - this.root = this.all_data; - self.____update_tree(); - self.__update_annotation(); - }, - _prune: function(array, label) { - var self = this; - for (var i = 0; i < array.length; ++i) { - var obj = array[i]; - if (obj.label === label) { - // splice out 1 element starting at position i - array.splice(i, 1); - return true; - } - if (obj.children) { - if (self._prune(obj.children, label)) { - if (obj.children.length === 0) { - // delete children property when empty - delete obj.children; - - // or, to delete this parent altogether - // as a result of it having no more children - // do this instead - array.splice(i, 1); - } - return true; - } - } - } - }, - - - _addLegend: function (args) { - var self = this; - var target = args.target; - var legend_dictionary = args.legend_dictionary; - var html_text = ""; - - //html_text += "
                        "; - for (var key in legend_dictionary) { - Biojs.console.enable(""+key+"
                        "); - html_text += ""+key+""; - //html_text += "
                      • "+key+"
                      • "; - } - //html_text += "
                      "; - html_text += ""; - - jQuery("#"+target).html(html_text); - Biojs.console.enable("added to #legend_panel: "+html_text); - }, - - _buildContextMenu: function(d){ - var self = this; - jQuery("
                    • Information:
                    • ").appendTo('#my_custom_menu ul'); - jQuery("
                    • collapse:
                    • ").appendTo('#my_custom_menu ul'); - jQuery("
                    • focus on this node:
                    • ").appendTo('#my_custom_menu ul'); - }, - - _buildDivs: function () { - var self = this; - - //this._headerDiv = jQuery('
                      ').appendTo(this._contentcontainer); - - jQuery( - //''+ - //''+ - // ''+ - - //''+ - //''+ - //''+ - - //''+ - - // ''+ - // ''+ - - // ''+ -// ''+ - - - //''+ - //''+ - - //''+ - //''+ - //''+ - // ''+ - // ''+ - - - - - - - - //''+ - // '
                      '+ - // ''+ - // ''+ - ' internal nodes: '+ - ''+ - ''+ - ''+ - //''+ - ''+ - ''+ - ''+ - //''+ - ''+ - ''+ - ''+ - //''+ - ''+ - ''+ - ''+ - //''+ - // ''+ - // ''+ - // ''+ - // ''+ - // ''+ - // ''+ -// ''+ -// ''+ -// ''+ -// ''+ -// ''+ -// ''+ - // ''+ - // ''+ - // ''+ - //''+ - 'leaves: '+ - ''+ - ''+ - ''+ - //''+ - // ''+ - // ''+ - // ''+ - //''+ - ''+ - ''+ - ''+ - //''+ - ''+ - ''+ - '' - //''+ - // ''+ - // ''+ - // ''+ - // ''+ - // ''+ - // ''+ - // ''+ - // '
                      ' - ).appendTo('#tv_controls'); - //jQuery('

                      Lappen

                      ').appendTo('#tv_controls'); - Biojs.console.enable("finished building div"); - //jQuery('
                      ').appentTo(jQuery("#tv_controls")); - - - // font size - jQuery('img.increase_font').click(function() { - self.opt.fontSize = parseInt(self.opt.fontSize) + 1 + "px"; - d3.select("svg").selectAll(".text").attr("font-size", function(d){ return self.opt.fontSize; }); - }); - - jQuery('img.decrease_font').click(function() { - self.opt.fontSize = parseInt(self.opt.fontSize) - 1 + "px"; - d3.select("svg").selectAll(".text").attr("font-size", function(d){ return self.opt.fontSize; }); - }); - - - - }, - /* - * Shows the columns indicated by the indexes array. - * @param {string} seq The sequence strand. - * @param {string} [identifier] Sequence identifier. - * - * @example - * myTree.__setModelOrganisms(); - * - */ - _setTaxaToShow: function (){ - - var show_taxa = new Object(); - show_taxa['Metazoa'] = 1; - show_taxa['Bilateria'] = 1; - show_taxa['Mammalia'] = 1; - show_taxa['Dipteria'] = 1; - show_taxa['Primates'] = 1; - show_taxa['Arabidopsis_thaliana'] = 1; - - - this.opt.show_taxa = show_taxa; - }, - __drawProteinDomains: function (){ - Biojs.console.enable("drawing protein domains"); - // Sequences - var rects = draw_sequences({nodeEnter: this.nodeEnter, - domainScale : this.opt.domainScale , - leaf_group_x : this.opt.leaf_group_x, - sequence_start_y : this.opt.sequence_start_y, - visibility : ""}); - // Domains - var domains = rects.selectAll(".domain").data(function(d) { return d.domains; }) - var all_domains = draw_domains({domains : domains, - sequence_start_y : this.opt.sequence_start_y, - domainScale: this.opt.domainScale, - sequence_rect_width : this.opt.sequence_rect_width, - leaf_group_x : this.opt.leaf_group_x, - domain_colors : this.opt.domain_colors, - visibility: "" }); - - } -}, -{ - EVT_ON_SELECTION_CHANGE: "onSelectionChange", - EVT_ON_SELECTION_CHANGED: "onSelectionChanged", - EVT_ON_ANNOTATION_CLICKED: "onAnnotationClicked" - -}); - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.UniProtDiseaseSummary.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.UniProtDiseaseSummary.js deleted file mode 100755 index eb8d0934d5..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.UniProtDiseaseSummary.js +++ /dev/null @@ -1,375 +0,0 @@ -/** - * Component to present UniProt disease information. - * - * @class - * @extends Biojs - * - * @author Rafael C Jimenez - * @version 1.0.0 - * @category 2 - * - * @requires jQuery 1.7.2 - * @dependency - * - * - * @requires Biojs.UniProtDiseaseSummary.css - * @dependency - * - * - * @param {Object} options An object with the options for this component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * @option {string} uniProtDasUrl - * Url pointing to an XML including UniProt infomration in DAS format - * - * @option {string} keywordFiltereing [['cancer','brain']] - * List of keywords to filter disease information - * - * @option {string} [proxyUrl='../biojs/dependencies/proxy/proxy.php'] - * Since the same origin policy ({@link http://en.wikipedia.org/wiki/Same_origin_policy}) in the browsers - * Biojs include a proxy script in PHP which redirects Ajax requests from local to any other domain. - * You can use tour own proxy script by modifying this value. - * - * @option {string} width [100%] - * Defines the width of the component - * - * @option {string} referencesColumnWidth [200px] - * Defines the width of the columns with reference links - * - * @option {boolean} tableHeader - * Boolean value to control the display of the table header - * - * @option {boolean} componentTitle - * Boolean value to control the display of the title of the component - * - * @example - * var instance = new Biojs.UniProtDiseaseSummary({ - * target: 'YourOwnDivId', - * uniProtDasUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/features?segment=P08123;type=BS:01019', - * keywordFiltereing: ['osteogenesis','lipoblastoma'], - * proxyUrl: '../biojs/dependencies/proxy/proxy.php', - * width: '100%', - * referencesColumnWidth: '150px', - * tableHeader: false, - * componentTitle: false - * }); - * - */ - - -Biojs.UniProtDiseaseSummary = Biojs.extend ( - /** @lends Biojs.UniProtDiseaseSummary# */ - { - constructor: function (options) { - //Biojs.console.enable(); - this.setUniProtDasUrl(this.opt.uniProtDasUrl); - this._component_wrapper_id = "UDS_component_wrapper"; - }, - - /** - * Set an URL to start the query and visualization - * @param {string} uniProtDasUrl DAS XML - * - * @example - * instance.setUniProtDasUrl("http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/features?segment=P37173;type=BS:01019"); - * - * @example - * instance.setUniProtDasUrl("http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/features?segment=P08123;type=BS:01019"); - * - */ - - setUniProtDasUrl: function(uniProtDasUrl){ - var self = this; - self._clearHtmlTemplate(); - /* URL where to get DAS XML */ - self._url; - if(self.opt.proxyUrl != ""){ - self._url= self.opt.proxyUrl + "?url=" + uniProtDasUrl; - } else { - self._url= uniProtDasUrl; - } - - /* get XML */ - jQuery.ajax({ - type: "GET", - url: self._url, - dataType: "xml", - success: function(a){self._processDasUniProtXml(a);}, - error: function(a){self._processErrorRequest(a);} - }); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._processErrorRequest - * Purpose: Process request error - * Returns: - - * Inputs: textStatus -> {String} Text satus - */ - _processErrorRequest: function (textStatus){ - var self = this; - Biojs.console.log("ERROR: " + textStatus ); - self.raiseEvent( Biojs.UniProtDiseaseSummary.EVT_ON_REQUEST_ERROR, { message: textStatus } ); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._drawHtmlTemplate - * Purpose: Create HTML template - * Returns: - - * Inputs: - - */ - _drawHtmlTemplate: function (){ - var _selector = "#" + this.opt.target; - var _container = jQuery(_selector); - var _tableTitle = jQuery('
                      ').appendTo(_container); - jQuery("
                      ").appendTo(_tableTitle); - jQuery("
                      ").appendTo(_tableTitle); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._clearHtmlTemplate - * Purpose: Remove component content - * Returns: - - * Inputs: - - */ - _clearHtmlTemplate: function (){ - var _selector = "#" + this.opt.target; - var _container = jQuery(_selector).html(''); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._drawComponentTitle - * Purpose: Draw component title - * Returns: - - * Inputs: - - */ - _drawComponentTitle: function (){ - if(this.opt.componentTitle){ - var _selector = "#" + this._component_wrapper_id; - var _container = jQuery(_selector); - var _tableTitle = jQuery("
                      Involvement in disease
                      ").appendTo(_container); - } - }, - /* - * Function: Biojs.UniProtDiseaseSummary._drawComments - * Purpose: Draw disease main summary using UniProt disease comments - * Returns: - - * Inputs: - - */ - _drawComments: function (){ - var _container = jQuery("#UDS_info"); - var _tableWrapper = jQuery("
                      "); - var _table = jQuery('
                      ').appendTo(_tableWrapper); - if(this.opt.tableHeader){ - var _fisrtRow = jQuery("").appendTo(_table); - jQuery("Notes").appendTo(_fisrtRow); - jQuery("References").appendTo(_fisrtRow); - } - /* Print table */ - var isVisible = true; - var rowType = "UDS_even"; - var commmentsDisplayed = 0; - for(i=0; i 0) { - isVisible = this._isAnyKewordInText(this.opt.keywordFiltereing, this._comments[i].notes[0]); - } - /* Print table */ - if (isVisible) { - if (rowType == "UDS_odd") { - rowType = "UDS_even"; - } - else { - rowType = "UDS_odd"; - } - var _row = jQuery("").appendTo(_table); - jQuery("" + this._comments[i].notes[0] + "").appendTo(_row); - var reference = ""; - var omimAccs = ""; - var pubmedAccs = ""; - /* Display OMIM */ - for (j = 0; j < this._comments[i].omimAccs.length; j++) { - omimAccs += '' + this._comments[i].omimAccs[j] + ', '; - } - if (omimAccs.length > 0) { - omimAccs = omimAccs.substring(0, omimAccs.length - 2); - omimAccs = "Links to OMIM:
                      " + omimAccs + "
                      "; - - } - /* Display Pubmed */ - for (k = 0; k < this._comments[i].pubmedAccs.length; k++) { - pubmedAccs += '' + this._comments[i].pubmedAccs[k] + ', '; - } - if (pubmedAccs.length > 0) { - pubmedAccs = pubmedAccs.substring(0, pubmedAccs.length - 2); - pubmedAccs = "Links to Pubmed:
                      " + pubmedAccs + "
                      "; - - } - jQuery("" + omimAccs + pubmedAccs + "").appendTo(_row); - commmentsDisplayed++; - } - } - if (commmentsDisplayed == 0) { - jQuery("#UDS_warnings").html("No disease notes found for this query"); - } else { - _tableWrapper.appendTo(_container); - } - - }, - /* - * Function: Biojs.UniProtDiseaseSummary._isAnyKewordInText - * Purpose: Check if a keyword from a list is present in a text - * Returns: - - * Inputs: - - */ - _isAnyKewordInText: function (keywords, text){ - /* Check keywords */ - var found = false; - keyword_loop: - for(j=0; j 0) { - isVisible = this._isAnyKewordInText(this.opt.keywordFiltereing, this._keywords[i].label); - } - if (isVisible) { - links += ""+this._keywords[i].label+", "; - } - } - if (links.length > 0) { - links = links.substring(0, links.length - 2); - links = "
                      Keywords: " + links + "
                      "; - jQuery(links).appendTo(_container); - } else { - var _info = jQuery("#UDS_info").html(); - if(_info.length > 0){ - jQuery("#UDS_warnings").html("No disease keywords or notes found for this query"); - } else { - jQuery("#UDS_warnings").html("No disease keywords found for this query"); - } - } - - }, - - - /* - * Function: Biojs.UniProtDiseaseSummary._processUniProtXml - * Purpose: process XML - * Returns: - - * Inputs: xml -> {String} DAS XML - */ - _processDasUniProtXml: function (xml){ - Biojs.console.log("SUCCESS: data received"); - this._keywords = new Array(); - this._comments = new Array(); - var self = this; - jQuery(xml).find("FEATURE").each(function(){ - var xmlType = jQuery(this).find("TYPE")[0]; - var featureCategory = jQuery(xmlType).attr("category"); - if(featureCategory.toLowerCase() == "keyword"){ - self._setKeyword(this); - } else if (featureCategory.toLowerCase() == "comment"){ - self._setComment(this); - } - - }); - this._drawHtmlTemplate(); - this._drawComponentTitle() - this._drawComments(); - this._drawKeywords(); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._setKeyword - * Purpose: parse keyword information - * Returns: - - * Inputs: featureXml -> {String} DAS XML - */ - _setKeyword: function (featureXml){ - var keyword = new Object(); - keyword.label = jQuery(featureXml).attr("label"); - keyword.link = "http://www.uniprot.org/keywords/?query=" + jQuery(featureXml).attr("label"); - this._keywords.push(keyword); - }, - /* - * Function: Biojs.UniProtDiseaseSummary._setComment - * Purpose: parse comment information - * Returns: - - * Inputs: featureXml -> {String} DAS XML - */ - _setComment: function (featureXml){ - /* Find OMIM accs and notes */ - var diseaseHeader = "DISEASE: "; - var comment = new Object(); - comment.omimAccs = new Array(); - comment.pubmedAccs = new Array(); - comment.notes = new Array(); - jQuery(featureXml).find("NOTE").each(function(){ - var omimPatern = /\[MIM\:[0-9]*\]/i; //[MIM:166200] - var note = jQuery(this).text(); - if (note.indexOf(diseaseHeader) == 0) { - note = note.substring(diseaseHeader.length,note.length); - } - if(note.match(omimPatern) != null){ - var omim = note.match(omimPatern)[0]; - var omimIndexStart = note.indexOf(omim); - var omimIndexEnd = parseInt(omimIndexStart) + omim.length; - note = note.substring(0,omimIndexStart-1) + note.substring(omimIndexEnd,note.length); - comment.omimAccs.push(omim.substring(5,omim.length-1)); - } - comment.notes.push(note); - }); - /* Find Pubmed accs */ - jQuery(featureXml).find("LINK").each(function(){ - var linkHref = jQuery(this).attr("href"); - pubmedAcc =""; - var pubmedUrl = "http://www.ncbi.nlm.nih.gov/pubmed/"; - var pubmedUrlIndex = linkHref.indexOf(pubmedUrl); - if(pubmedUrlIndex == 0){ - pubmedAcc = linkHref.substring(pubmedUrl.length,linkHref.length); - comment.pubmedAccs.push(pubmedAcc); - } - }); - this._comments.push(comment); - Biojs.console.log(comment.omimAccs); - Biojs.console.log(comment.pubmedAccs); - Biojs.console.log(comment.notes); - }, - - - - /** - * Default values for the options - * @name Biojs.UniProtDiseaseSummary-opt - */ - opt: { - target: 'uniprotDiseaseSummary', - uniProtDasUrl: 'http://www.ebi.ac.uk/das-srv/uniprot/das/uniprot/features?segment=P08123;type=BS:01019', - keywordFiltereing: [], - proxyUrl: '../biojs/dependencies/proxy/proxy.php', - width: '100%', - referencesColumnWidth: '150px', - tableHeader: false, - componentTitle: false - }, - /** - * Array containing the supported event names - * @name Biojs.UniProtDiseaseSummary-eventTypes - */ - eventTypes: [] -}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.js deleted file mode 100755 index b09b92ccb2..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.js +++ /dev/null @@ -1,727 +0,0 @@ -/** - * Main container of the BioJS library. It is the parent class for all the components. - * - * @namespace - * - */ -var Biojs = function() { - // dummy -}; - -/** - * @class - * @param {string} eventType The name of the event. - */ -Biojs.EventHandler = function(eventType) { - /** - * The name of the event. - * @type {string} - */ - this.eventType = eventType; - /** - * Array of the registered listeners. - * @type {function[]} - */ - this.listeners = []; - /** - * Register action listeners for the event. - * @param {function} actionPerformed The action listener to be registered. - */ - this.addListener = function ( actionPerformed ) { - if ( (typeof actionPerformed) == "function" ) { - this.listeners.push(actionPerformed); - } - }; - /** - * Removes an action listener for the event. - * @param {function} actionPerformed The action listener to be removed. - */ - this.removeListener = function ( actionPerformed ) { - if ( (typeof actionPerformed) == "function" ) { - var pos = Biojs.Utils.indexOf(this.listeners,actionPerformed); - if (pos!=-1) - this.listeners.splice(pos,1); - } - }; - /** - * Executes all listener actions registered in the listeners field. - * @param {Object} eventObject The event' object to be passed as argument to the listeners. - */ - this.triggerEvent = function( eventObject ) { - for ( var i in this.listeners ) { - this.listeners[i](eventObject); - } - } -}; - -/** - * @class - * @param {string} type The name of the event. - * @param {Object} data An object containing the data for copying it in this event. - * @param {Biojs} source The component source of the event. - */ -Biojs.Event = function ( type, data, source ) { - - /** - * The component which did triggered the event. - * @type {Biojs} - */ - this.source = source; - /** - * The name of the event. - * @type {string} - */ - this.type = type; - - for ( var key in data ) { - this[key] = data[key]; - } -}; - -/** - * @class - * - */ -Biojs.Utils = { - /** - * Clone all members from an object. - * @param {object} object The object to be cloned. - * @returns {object} A Clone of the object passed as argument. - * - */ - clone: function(obj) { - var newObj = (obj instanceof Array) ? [] : {}; - for (i in obj) { - if (obj[i] && typeof obj[i] == "object") { - newObj[i] = Biojs.Utils.clone(obj[i]); - } else { - newObj[i] = obj[i]; - } - } - return newObj; - }, - - /** - * Determine if an onject or array is empty. - * @param {object|array} o Either object or array to figure out if empty or not. - * @returns {bool} true if empty, false if don't - */ - isEmpty: function(o){ - if (o instanceof Array) { - return (o.length<=0); - } else { - for (var i in o) { - if (o.hasOwnProperty(i)) { - return false; - } - } - return true; - } - }, - - /** - * Searches the array for the specified item, and returns its position. - * The search will start at the specified position, or at the beginning if no start position is specified, - * and end the search at the end of the array. - * - * Returns -1 if the item is not found. - * If the item is present more than once, the indexOf method returns the position of the first occurence. - * - * indexOf is not supported in IE < v9 - * - * @param {array} The array containing the element to look for. - * @param {object} Required. The item to search for. - * @param {int} Optional. Where to start the search. - */ - indexOf : function(elem, arr, i){ - var len; - - if ( arr ) { - if ( indexOf ) { - return indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - /** - * Cross-browser console for debugging. - * The console is disabled by default. That means, all messages written by means Biojs.console.log("My Message") will be ignored. - * Use Biojs.console.enable() to enable it. - * - * @example - * // Enabling loggin messages - * Biojs.console.enable(); - * ... - * // Writing a log - * Biojs.console.log("My Message"); - * - * @type {Object} - */ - console: { - enable: function() { - // Define a cross-browser window.console.log method. - // For IE and FF without Firebug, fallback to using an alert. - if (window.console) { - /** - * @ignore - */ - // In this case, there are a console, perfect! - this.log = function (msg) { console.log(msg) }; - } else { - // We have not window.console, but it is Opera browser? - if (window.opera) { - /** - * @ignore - */ - // Right! then lets use window.opera.postError - this.log = function (msg) { window.opera.postError(msg) }; - } else { - // None console found! - // Try to write the logs somewhere - // That's it! in a new window, identified by 'Biojs.console' - var consoleWin = window.open('','myconsole', - 'width=350,height=250' - +',menubar=0' - +',toolbar=0' - +',status=0' - +',scrollbars=1' - +',resizable=1'); - - // We got it? - if (consoleWin) { - // Good, build a blank document into with a DIV 'Biojs.console' - consoleWin.document.writeln( - 'BioJS Console' - +'' - +'
                      ' - +'' - ); - consoleWin.document.close(); - - Biojs.console.domDocument = consoleWin.document; - Biojs.console.domDivNode = consoleWin.document.getElementById("Biojs.console"); - - /** - * @ignore - */ - // Finally, the log function will write into the DIV - this.log = function (msg) { - var message = ''; - - if (msg instanceof Array) { - for ( i=0; i < msg.length; i++ ) { - message += '[' + i + ']=' + msg[i] + ' '; - } - - } else if (msg instanceof String || typeof msg === "string") { - message = msg; - - } else { - for (var i in msg) { - message += '[' + i + ']=' + msg[i] + ' '; - } - } - - textNode = Biojs.console.domDocument.createTextNode(message); - line = Biojs.console.domDocument.createElement('pre'); - line.appendChild(textNode); - Biojs.console.domDivNode.appendChild(line); - }; - - } else { - // Game over! do not write logs, but let's tell to user by means an alert (sorry!) - alert("Please activate the pop-up window in this page " + - "in order to enable the BioJS console"); - } - } - } - }, - - log: function (msg) { ; /* Do nothing by default */ } - } -}; - -/** - * Extend this class Biojs in order to create a new component. - * @param {object} instance The subclass. - * @param {object} interface (optional) A second parameter passed to the extend method of a class defines the class interface. - * @returns {object} SubClass The class with its own members and the inherited ones from Biojs. - * - * @example - * Biojs.MyComponent = Biojs.extend( - * { // instance - * constructor: function(options) { - * // constructor code here - * }, - * - * opt: { target: "divId" }, - * - * eventTypes: [ "myEvent1", "myEvent2" ], - * - * getVersion: function() { - * return Biojs.MyComponent.VERSION; - * } - * }, - * { // class interface - * VERSION: "3.14.15" - * }); - * - * alert(Biojs.MyComponent.VERSION); - * - */ -Biojs.extend = function(_child, _static) { // subclass - var extend = Biojs.prototype.extend; - - // build the prototype - Biojs._prototyping = true; - - /** - * @name proto - * @constructs - */ - var proto = new this; - - // Inherit parent' events to the child - if (proto.eventTypes instanceof Array) { - for ( var i in proto.eventTypes ) { - _child.eventTypes.push(proto.eventTypes[i]); - } - } - - // Inherit parent' options to the child - if (proto.opt instanceof Object) { - for ( var key in proto.opt ) { - _child.opt[key] = proto.opt[key]; - } - } - - extend.call(proto, _child); - - /** - * @ignore - */ - proto.base = function() { - // call this method from any other method to invoke that method's ancestor - }; - - delete Biojs._prototyping; - - // create the wrapper for the constructor function - var constructor = proto.constructor; - var klass = proto.constructor = function() { - - if (!Biojs._prototyping) { - - if (this.constructor == klass) { // instantiation - - // Create a instance of this class - function BiojsComponent() {}; - BiojsComponent.prototype = proto; - var instance = new BiojsComponent(); - - // Change the default option's values - // in the instance by the provided ones - instance.setOptions(arguments[0]); - - // Set the event handlers - instance.setEventHandlers(instance.eventTypes); - - // Set the unique id for the instance - instance.biojsObjectId = Biojs.uniqueId(); - - // register instance - Biojs.addInstance(instance); - - // execute the instance's constructor - constructor.apply(instance, arguments); - - // return the instance - return instance; - - } else { // Calling to ancestor's constructor - constructor.apply(this,arguments); - } - } - }; - - // build the class interface - klass.ancestor = this; - klass.extend = this.extend; - klass.forEach = this.forEach; - klass.implement = this.implement; - klass.prototype = proto; - /** - * @ignore - */ - klass.valueOf = function(type) { - return (type == "object") ? klass : constructor.valueOf(); - }; - klass.toString = this.toString; - extend.call(klass, _static); - - // class initialization - if (typeof klass.init == "function") { - klass.init(); - } - - return klass; -}; - -Biojs.prototype = -/** @lends Biojs# */ -{ - extend: function(source, value) { - if (arguments.length > 1) { // extending with a name/value pair - var ancestor = this[source]; - if (ancestor && (typeof value == "function") && // overriding a method? - // the valueOf() comparison is to avoid circular references - (!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) && - /\bbase\b/.test(value)) { - // get the underlying method - var method = value.valueOf(); - // override - value = function() { - var previous = this.base || Biojs.prototype.base; - this.base = ancestor; - var returnValue = method.apply(this, arguments); - this.base = previous; - return returnValue; - }; - // point to the underlying method - value.valueOf = function(type) { - return (type == "object") ? value : method; - }; - value.toString = Biojs.toString; - } - this[source] = value; - } else if (source) { // extending with an object literal - var extend = Biojs.prototype.extend; - // if this object has a customised extend method then use it - if (!Biojs._prototyping && typeof this != "function") { - extend = this.extend || extend; - } - var proto = {toSource: null}; - // do the "toString" and other methods manually - var hidden = ["constructor", "toString", "valueOf"]; - // if we are prototyping then include the constructor - var i = Biojs._prototyping ? 0 : 1; - while (key = hidden[i++]) { - if (source[key] != proto[key]) { - extend.call(this, key, source[key]); - } - } - // copy each of the source object's properties to this object - for (var key in source) { - if (!proto[key]) extend.call(this, key, source[key]); - } - } - - return this; - }, - - /** - * Register a function under an event type in order to execute it whenever the event is triggered. - * @param {string} eventType The event to be listened. - * @param {function} actionPerformed The action to be executed whenever the event occurs. it - * - * - * @example - * - * var listener = function(eventObj){ - * alert("Selected: "+eventObj.start+", end: "+ eventObj.end); - * } - * - * var mySequence = new Biojs.Sequence( { - * sequence : "mlpglallllaawtaralevptdgnagllaepqiamfcgrlnmhmnvqngsgtktcidtkegilqy", - * target : "#div0001", - * format : 'CODATA', - * id : 'P918283' - * }); - * - * mySequence.addListener('onSelectionChanged', listener); - * - * // HTML div tag with the id='div0001' must exist in the HTML document - * - */ - addListener: function(eventType, actionPerformed) { - if (this._eventHandlers) { - // register the listener in this._eventHandlers for the eventType - for(var key in this._eventHandlers) { - if ( eventType == this._eventHandlers[key].eventType ) { - this._eventHandlers[key].addListener( actionPerformed ); - return; - } - } - } - }, - - /** - * Unregister a function under an event type in order to stop its execution it whenever the event is triggered. - * @param {string} eventType The event to be listened. - * @param {function} actionPerformed The action to be unregister. - * - * - * @example - * mySequence.removeListener('onSelectionChanged', listener); - * - * // HTML div tag with the id='div0001' must exist in the HTML document - * - */ - removeListener: function(eventType, actionPerformed) { - if (this._eventHandlers) { - // register the listener in this._eventHandlers for the eventType - for(var key in this._eventHandlers) { - if ( eventType == this._eventHandlers[key].eventType ) { - this._eventHandlers[key].removeListener( actionPerformed ); - return; - } - } - } - }, - - /** - * Sets an event handler and an alias method for each string in the array eventTypes. - * This method is executed automatically before constructing an instance, using the eventTypes array - * that should be defined as member of subclass. Then, the resulting instance will have methods - * named in the form instance.≶eventName>(actionPerformed) for all eventTypes. - * - * @param {string[]} eventTypes Array of names of the events to be set. - * - */ - setEventHandlers: function (eventTypes) { - // Supposed that this._eventHandlers does not exist. - this._eventHandlers = []; - // Because the event handlers are not initialized yet - - var alias = function (handler) { - return function (actionPerformed) { - handler.listeners.push(actionPerformed); - } - }; - - if ( typeof eventTypes == "object" ) { - // Create an event handler for each eventType in eventTypes - for ( var i=0; i < eventTypes.length; i++ ) { - var handler = new Biojs.EventHandler( eventTypes[i] ); - this._eventHandlers.push( handler ); - // Creates the alias this. () - // as alternative to be used instead of this.addistener(, ) - - this[ eventTypes[i] ] = new alias(handler); - } - } - }, - - /** - * Trigger the registered functions under an event type. - * @param {string} eventType The event to be raised. - * @param {Object} params The values to be included into Biojs.Event object. - * - * @example - * - * Biojs.MyComponent = Biojs.extend({ - * // ... - * // code before the event - * - * this.raiseEvent('onSelectionChanged', {start : start, end : end}); - * - * // code after the event - * // ... - * }); - * - */ - raiseEvent : function(eventType, eventObj) { - for(var key in this._eventHandlers ) { - if ( eventType == this._eventHandlers[key].eventType ) { - this._eventHandlers[key].triggerEvent( eventObj ); - return; - } - } - }, - - - // - // Save the option values to be applied to this component - // options -> [Object] containing the values - // - setOptions : function (options) { - if ( this.opt instanceof Object ) - { - this.opt = Biojs.Utils.clone(this.opt); - for ( var key in options ) { - this.opt[key] = options[key]; - } - } - }, - - // - // - // source -> [BioJs] the another component - // eventType -> [string] the event to be listened - // callbackFunction -> [function] the action to be executed - // - /** - * Connect this component with another by means listening its events. - * @param {Biojs} source The another component. - * @param {string} eventType The event to be listened. - * @param {function} actionPerformed The action to be executed whenever the event occurs. it - * - * - * @example - * - * var mySequence = new Biojs.Sequence( { - * sequence : "mlpglallllaawtaralevptdgnagllaepqiamfcgrlnmhmnvqngsgtktcidtkegilqy", - * target : "#div0001", - * format : 'CODATA', - * id : 'P918283' - * }); - * - * var anotherSequence = new Biojs.Sequence({ - * sequence : "laawtaralevptmlpglallldgnagllaepqi", - * target : "#div0002", - * }); - * - * anotherSequence.listen( - * mySequence, - * "onSelectionChange", - * function( eventObj ) { - * anotherSequence.setSelection(eventObj.start, eventObj.end); - * } - * ); - * - */ - listen: function ( source, eventType, callbackFunction ) { - if ( source instanceof Biojs ){ - if ( typeof callbackFunction == "function" ) { - source.addListener(eventType, callbackFunction); - } - } - }, - - getId: function () { - return this.biojsObjectId; - } - -}; - -// initialize -Biojs = Biojs.extend({ - constructor: function() { - this.extend(arguments[0]); - }, - - vaueOf: function () { return "Biojs" } -}, -/** @static */ -/** @lends Biojs */ -{ - /** - * Ancestor of the Biojs class (Object). - * @type {Object} - */ - ancestor: Object, - /** - * Version of the Biojs class. - * @type {string} - */ - version: "1.0", - - forEach: function(object, block, context) { - for (var key in object) { - if (this.prototype[key] === undefined) { - block.call(context, object[key], key, object); - } - } - }, - - implement: function() { - for (var i = 0; i < arguments.length; i++) { - if (typeof arguments[i] == "function") { - // if it's a function, call it - arguments[i](this.prototype); - } else { - // add the interface using the extend method - this.prototype.extend(arguments[i]); - } - } - return this; - }, - /** - * Get string. - * @type {function} - */ - toString: function() { - return String(this.valueOf()); - }, - /** - * Get a unique identifier. It is useful to assign the instance' id - * @type {function} - */ - uniqueId: function() { - if ( typeof Biojs.prototype.__uniqueid == "undefined" ) { - Biojs.prototype.__uniqueid = 0; - } - return Biojs.prototype.__uniqueid++; - }, - /** - * Register a Biojs instance. - * @type {function} - */ - addInstance: function ( instance ) { - if ( typeof Biojs.prototype.__instances == "undefined" ) { - Biojs.prototype.__instances = {}; - } - return Biojs.prototype.__instances[instance.biojsObjectId] = instance; - }, - /** - * Get a Biojs instance by means of its id. - * @type {function} - */ - getInstance: function ( id ) { - return Biojs.prototype.__instances[id]; - }, - /** - * Set a variable in the DOM window. - * @type {function} - */ - registerGlobal: function ( key, value ) { - window[key] = value; - }, - /** - * Get a variable value from the DOM window. - * @type {function} - */ - getGlobal: function(key){ - return window[key]; - }, - /** - * Cross-browser console for debugging. - * This is a shorcut for {@link Biojs.Utils.console} - * - * @type {Object} - * - */ - console: Biojs.Utils.console, - - EventHandler: Biojs.EventHandler, - - Event: Biojs.Event, - - Utils: Biojs.Utils - -}); - - - diff --git a/src/lib/biojs-1.0/src/main/javascript/Biojs.wigExplorer.js b/src/lib/biojs-1.0/src/main/javascript/Biojs.wigExplorer.js deleted file mode 100755 index c8523439fb..0000000000 --- a/src/lib/biojs-1.0/src/main/javascript/Biojs.wigExplorer.js +++ /dev/null @@ -1,864 +0,0 @@ -/** - * This component uses the D3 library to visualise a wig formatted file as an area chart, with panning and zooming functionality. - * - * @class - * @extends Biojs - * - * @author Anil Thanki - * @version 1.0.0 - * @category 2 - * - * - * @requires D3 - * @dependency - * - * - * @requires jQuery UI 1.8.2+ - * @dependency - * - * @requires jQuery Core 1.6.4 - * @dependency - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * @requires jQuery.tooltip - * @dependency - * - * @requires jQuery.tooltip CSS - * @dependency - * - * @requires biojs.wigExplorer.css - * @dependency - * - * - * @requires jQuery UI CSS 1.8.2 - * @dependency - * - * - * @param {Object} options An object with the options for wigExplorer component. - * - * @option {string} target - * Identifier of the DIV tag where the component should be displayed. - * - * - * @example - * var instance = new Biojs.wigExplorer({ - * target: "YourOwnDivId", - * selectionBackgroundColor: 'steelblue', - * dataSet: "../biojs/data/wigExplorerDataSet5.txt" - * }); - * - * @option {string} dataSet - * File in text format including input data. Examples of text file ...
                      - *
                      variableStep chrom=chr2 span=5
                      - * 10    34
                      - * 20    41
                      - * 30    46
                      - * 40    49
                      - * 50    52
                      - *
                      - *  ...
                      - *
                      - * or
                      - *
                      - * fixedStep chrom=chr2 start=10 step=10 span=5
                      - * 34
                      - * 41
                      - * 46
                      - * 49
                      - * 52
                      - *
                      - *  ...
                      - * - * @option {string} [selectionBackgroundColor] - * Name of the colour to be set as background for area chart - * - */ - - -Biojs.wigExplorer = Biojs.extend( - /** @lends Biojs.wigExplorer# */ - - - { - zoomSlider: '', - slider_stop: 0, - slider_start: 0, - track: [], - width: 1, - height: 1, - data_last_start: 1, - data_first_start: 1, - max: 0, - span: null, - chrom: [], - data: [], - main_data: [], - - - constructor: function (options) { - - var self = this; - self.vis = null; - self.color = null; - self.foci = []; - - - this.track; // data - - - this._container = $("#wigFeaturePainter-holder"); - $(this._container).addClass("graph"); - - - // Apply options values - this._container.css({ - 'font-family': self.opt.fontFamily, // this is one example of the use of self instead of this - 'background-color': self.opt.selectionBackgroundColor, - 'color': self.opt.fontColor, - 'font-size': '36px', - 'text-align': 'center', - 'vertical-align': 'middle', - 'width': '700px', - 'height': '100px', - 'bottom': '0px' - }); - - // Disable text selection and - // Change the selection mouse pointer - // from text to hand. - this._container.css({ - '-moz-user-select': 'none', - '-webkit-user-select': 'none', - 'user-select': 'none' - }); - - this.color = self.opt.selectionBackgroundColor; - this.paintFeatures(self.opt.dataSet); - - }, - - /** - * Default values for the options - * @name Biojs.wigExplorer-opt - */ - opt: { - target: "YourOwnDivId", - dataSet: "", - fontFamily: '"Andale mono", courier, monospace', - fontColor: "white", - backgroundColor: "", - selectionFontColor: "black", - selectionBackgroundColor: "yellow", - width: "100%", - height: "130", - radius: 10, - reference: null - }, - - /** - * Array containing the supported event names - * @name Biojs.wigExplorer-eventTypes - */ - eventTypes: [ - /** - * No events added for now but can be added in future - */ - ], - - - /** - * Repaints everything: ruler, shapes, and legend. - * @param {int} [newStart] Zoom from this sequence start value. - * @param {int} [newStop] Zoom to this sequence end value. - * - * @example - * instance._updateDraw(); - * - */ - _updateDraw: function (newStart, newStop, target) { - var self = this; - //recalculate start and stop - if (newStart && newStop) { - this.slider_start += newStart; - this.slider_stop += newStop; - } - - if (target) { - } else { - target = self.opt.target; - } - if (this.slider_start < this.data_first_start) { - if (newStart == newStop) { - this.slider_stop += this.data_first_start - this.slider_start; - } - this.slider_start = this.data_first_start; - - } - - if (this.slider_stop > this.data_last_start) { - - if (newStart == newStop) { - this.slider_start += this.data_last_start - this.slider_stop; - } - this.slider_stop = this.data_last_start; - } - //recalculate start and stop - if ((parseFloat(this.slider_start) < parseFloat(this.slider_stop))) { - this.paintWig(this.slider_start, this.slider_stop, target); - } - }, - - /** - * Paint the features according to the values specified in the json object defined when creating the object. - * This method initializes the holder, paints the slider and print button depending on the options, and - * paints the features and legend. - * - * @example - * instance.paintFeatures("path-to-wig.txt"); - * - * @param {string} dataSet Location of the file with the input data in text format. - *
                      variableStep chrom=chr2 span=5
                      -         * 10    34
                      -         * 20    41
                      -         * 30    46
                      -         * 40    49
                      -         * 50    52
                      -         *
                      -         *  ...
                      -         *
                      -         * or
                      -         *
                      -         * fixedStep chrom=chr2 start=10 step=10 span=5
                      -         * 34
                      -         * 41
                      -         * 46
                      -         * 49
                      -         * 52
                      -         *
                      -         *  ...
                      - * - */ - paintFeatures: function (dataSet) { - if (dataSet != undefined) { - this._setDataSource(dataSet); - this._init(); - } else { - alert('Dataset not defined '); - } - - }, - - /** - * Private: Initializes the component. - */ - _init: function () { - Biojs.wigExplorer.myself = this; - var self = this; - var painter_div = jQuery("#" + this.opt.target); - painter_div.text(''); - painter_div.append(this._withSliderOnly(100)); - - painter_div.append('
                      '); - var holder = document.getElementById(this.opt.target + '_wigFeaturePainter-holder'); - if (!holder) { - this.$errorMsg = jQuery('
                      ') - .html('There was an unexpected failure, the image cannot be displayed.') - .dialog({ - autoOpen: true, - title: 'Error', - modal: true - }); - throw "Error"; - } - - - holder.innerHTML = ""; - holder.style.height = "250px"; - holder.style.width = "700px"; - this.width = $('#' + self.opt.target + '_wigFeaturePainter-holder').width(), - this.height = $('#' + self.opt.target + '_wigFeaturePainter-holder').height(), - this.r = self.opt.radius; - - self.opt.width = self.opt.width.toString(); - - if (self.opt.width.indexOf("%") >= 1) - self.opt.width = self.opt.width.toString(); - else - self.opt.width = parseInt(this.width); - - //had similar problem before so I used contains and it should works - self.opt.height = self.opt.height.toString(); - if (self.opt.height.indexOf("%") >= 1) - self.opt.height = self.opt.height.toString(); - if (self.opt.height.indexOf("%") != -1) - this.height = this.height * (self.opt.height.substring(0, self.opt.height.length - 1) * 1) / 100.0; - else - this.height = self.opt.height * 1; - self.opt.height = parseInt(this.height); - - self.color = function () { - return d3.scale.ordinal().range(self.colors); - }(); - - jQuery.ajax({ - type: "GET", - url: self.opt.dataSet, - dataType: "text", - success: function (data) { - var wig = []; - var max = 0 - var data_split = data.split("\n") - var data_len = data_split.length; - if (data.indexOf("variableStep") >= 0 || data.indexOf("fixedStep") >= 0) { - self.chrom = [] - for (var i = 0; i < data_len; i++) { - if (data_split[i].indexOf("chrom") >= 0) { - var chr = data_split[i].split(/\s+/)[1].split("=")[1]; - if (self.chrom.indexOf(chr) < 0) { - self.chrom.push(chr); - } - } - } - self._buildReferenceSelector(); - } else { - alert("Unknown format detected") - } - - }, - error: function (qXHR, textStatus, errorThrown) { - alert(textStatus); - } - }); - }, - - - /** - * Private: Function to create reference dropdown. - * @ignore - */ - _buildReferenceSelector: function () { - var self = this; - - this._headerDiv = jQuery('#' + self.opt.target + '_selectorMenu'); - this._headerDiv.css({ - 'font-family': '"Heveltica Neue", Arial, "sans serif"', - 'font-size': '14px' - }).append('Reference: '); - - var selector_html = ""; - - this._formatSelector = jQuery(selector_html).appendTo(self._headerDiv); - - this._formatSelector.change(function (e) { - self.opt.reference = jQuery(this).val(); - self.setReference(self.opt.reference, self.opt.target) - }); - - self.setReference(this._formatSelector.val()) - }, - - - /** - * Private: Function to create slider only. - * @param {int} sizeX Width. - * @ignore - */ - _withSliderOnly: function (sizeX) { - var self = this; - var text = - '' + - '' + - '' + - '' + - '' + - '
                      ' + - '
                      ' + - '
                      ' + - '
                      ' + - '
                      '; - return text; - }, - /** - * Private: Paints the slider - * Purpose: set up slider buttons - * Returns: - - * @ignore - */ - _paintSlider: function () {//holder size, left and right margins of the holder, and number of amino acids - var sequenceLength = 100;//config.sequenceLength; - var self = this; - if (!document.getElementById(self.opt.target + "_wigFeaturePainter-slider")) { - return; - } - - var slider_div = jQuery("#" + self.opt.target + "_wigFeaturePainter-slider"); - slider_div.text(''); - slider_div.append(''); - slider_div.append('
                      '); - - var length = this.track.length - 1; - var difference = parseInt(this.track[length][0]) - parseInt(this.track[0][0]); - - var diff = parseInt(difference / 20); - this.zoomSlider = jQuery('
                      ').appendTo(slider_div); - - - var updater_html = '
                      ' + - '
                      ' + - '
                      ' + - '
                      '; - - jQuery(slider_div).html("") - this._updateSelector = jQuery(updater_html).appendTo(slider_div); - - this._updateSelector.click(function (e) { - if (jQuery(this).hasClass("left")) { - self._updateDraw(-1 * diff, -1 * diff, self.opt.target); - } else if (jQuery(this).hasClass("right")) { - self._updateDraw(diff, diff, self.opt.target); - } else if (jQuery(this).hasClass("zoomin")) { - self._updateDraw(diff, -1 * diff, self.opt.target); - } else if (jQuery(this).hasClass("zoomout")) { - self._updateDraw(-1 * diff, diff, self.opt.target); - } - }); - }, - - - /** - * Select reference from Wig file from the given parameter and then parse Data for reference - * - * @example - * instance.setReference("ref_name") - * - */ - setReference: function (ref_chr) { - var self = this; - var flag = false; - jQuery.ajax({ - type: "GET", - url: self.opt.dataSet, - dataType: "text", - success: function (data) { - var wig = []; - var max = 0 - var data_split = data.split("\n") - var data_len = data_split.length; - var span = null; - var ref = false; - if (data.indexOf("variableStep") >= 0) { - - var data_split = data.split("\n") - var data_len = data_split.length; - - - for (var i = 0; i < data_len; i++) { - if (data_split[i].indexOf("chrom") >= 0) { - var chr = data_split[i].split(/\s+/)[1].split("=")[1]; - flag = false; - if (chr == ref_chr) { - if (data_split[i].indexOf("span") >= 0) { - span = data_split[i].split(/\s+/)[2].split("=")[1] - } - flag = true; - ref = true; - } - } - else if (data_split[i].indexOf("#") >= 0) { - continue; - } else if (flag) { - var temp_data = data_split[i].split(/\s+/); - wig.push([temp_data[0], temp_data[1], span]); - if (parseInt(temp_data[1]) > parseInt(max)) { - max = temp_data[1]; - } - } - } - self.max = max; - - self.track = wig; - if (ref == false) { - alert("Selected reference not found") - } else if (wig.length > 0) { - var start = parseInt(wig[0][0]);//config.requestedStart; - var stop = parseInt(wig[wig.length - 1][0]); - - - self.slider_start = start; - self.slider_stop = stop; - self.data_last_start = stop; - self.data_first_start = start; - - } - else { - alert("No data for selected reference") - } - - - } - else if (data.indexOf("fixedStep") >= 0) { - var data_split = data.split("\n") - var data_len = data_split.length; - var start = null; - var step = null; - var ref = false; - - for (var i = 0; i < data_len; i++) { - if (data_split[i].indexOf("chrom") >= 0) { - var line = data_split[i].split(/\s+/); - - var chr = data_split[i].split(/\s+/)[1].split("=")[1]; - flag = false; - - if (chr == ref_chr) { - start = line[2].split("=")[1]; - step = line[3].split("=")[1]; - if (data_split[i].indexOf("span") >= 0) { - span = line[4].split("=")[1] - } - - flag = true; - ref = true; - } - } - else if (data_split[i].indexOf("#") >= 0) { - continue; - } else if (flag) { - var temp_data = data_split[i]; - start = parseInt(start) + parseInt(step) - wig.push([start, temp_data, span]); - if (parseInt(temp_data) > parseInt(max)) { - max = temp_data; - } - } - } - - self.max = max; - self.track = wig; - - if (ref == false) { - alert("Selected reference not found") - } else if (wig.length > 0) { - var start = parseInt(wig[0][0]);//config.requestedStart; - var stop = parseInt(wig[wig.length - 1][0]); - - - self.slider_start = start; - self.slider_stop = stop; - self.data_last_start = stop; - self.data_first_start = start; - - } else if (start == null || step == null) { - alert("Unknown format detected") - } - else { - alert("No data for selected reference") - } - } - else { - alert("Unknown format detected") - } - }, - error: function (qXHR, textStatus, errorThrown) { - alert(textStatus); - } - }).done(function () { - self._paintSlider(); - self._updateDraw(); - }); - }, - - /** - * Draws area chart from wig file using D3.js based on the specified positions - * - * @example - * instance.paintWig(1000,100000,"target-div") - * - */ - paintWig: function (start, end, target) { - var self = this; - if (this.track.length > 0) { - var color = this.opt.selectionBackgroundColor - var left = "50px"; - var top = "0px"; - var filtered_track = []; - var height = this.height; - var width = this.width; - var max = this.max; - - - // filter data if start and end positions are defined - if (start && end) { - if (start < self.slider_start) { - start = self.slider_start; - } - if (end > self.slider_stop) { - end = self.slider_stop - } - - - filtered_track = this.track; - filtered_track = jQuery.grep(filtered_track, function (element) { - return element[0] >= start && element[0] <= end; // retain appropriate elements - }); - } - else { - filtered_track = this.track; - var length = this.track.length - 1; - end = parseInt(this.track[length][0]); - start = parseInt(this.track[0][0]); - } - var space = parseInt(width) / (end - start); - - var length = filtered_track.length - 1; - if (length > 0) { - - this._clear(target); - var svg = d3.select('#' + target + '_wigFeaturePainter-holder').append("svg") - .attr("width", this.width + 20) - .attr("height", $('#' + target + '_wigFeaturePainter-holder').height()) - .append("g") - .attr("transform", "translate(" + left + "," + top + ")"); - - this._container = jQuery('#' + target + '_wigFeaturePainter-holder'); - - var d3line2 = d3.svg.line() - .x(function (d) { - return d.x; - }) - .y(function (d) { - return d.y; - }) - .interpolate("linear"); - - var end_val = parseInt(filtered_track[length][0]) + parseInt(filtered_track[1][0] - filtered_track[0][0]); - var start_val = parseInt(filtered_track[0][0]) - (parseInt(filtered_track[1][0] - filtered_track[0][0])); - - if (start_val < 0) { - start_val = 0; - } - - // add a 0 to start position - filtered_track.splice(0, 0, [start_val, 0]); - - // add a 0 to end position - filtered_track.splice(filtered_track.length, 0, [end_val, 0]); - - var pathinfo = []; - - var last_start = 0; - // check for average difference between each positions - var diff = parseInt(filtered_track[1][0] - filtered_track[0][0]); - if (diff > parseInt(filtered_track[2][0] - filtered_track[1][0]) || diff > parseInt(filtered_track[3][0] - filtered_track[2][0])) { - if (diff > parseInt(filtered_track[2][0] - filtered_track[1][0])) { - diff = parseInt(filtered_track[2][0] - filtered_track[1][0]) - } - else { - diff = parseInt(filtered_track[3][0] - filtered_track[2][0]) - } - } - else { - } - - // loop through each element and calculate x and y axis for chart - for (var i = 0; i < filtered_track.length - 1;) { - var tempx; - if (start > 0) { - tempx = (filtered_track[i][0] - start) * space; - } - else { - tempx = (filtered_track[i][0]) * space; - } - var tempy = height - (filtered_track[i][1] * height / max); - pathinfo.push({ x: tempx, y: tempy}); - - i++; - - if (last_start < filtered_track[i][0] - diff) { - - if (start > 0) { - tempx = ((parseInt(last_start) + parseInt(diff)) - start) * space; - } - else { - tempx = ((parseInt(last_start) + parseInt(diff))) * space; - } - - var tempy = height; - - pathinfo.push({ x: tempx, y: tempy}); - - if (start > 0) { - tempx = ((parseInt(filtered_track[i][0]) - parseInt(diff)) - start) * space; - } - else { - tempx = ((parseInt(filtered_track[i][0]) - parseInt(diff))) * space; - } - var tempy = height; - - pathinfo.push({ x: tempx, y: tempy}); - - } - - last_start = filtered_track[i][0]; - - } - - if (start > 0) { - tempx = (filtered_track[filtered_track.length - 1][0] - start) * space; - } - else { - tempx = (filtered_track[filtered_track.length - 1][0]) * space; - } - - var tempy = height - (filtered_track[filtered_track.length - 1][1] * height / max); - - pathinfo.push({ x: tempx, y: tempy}); - var path = svg.selectAll("path") - .data([1]); - - //select 10 positions to be displayed on x axis - var filter_track_legend = []; - var legend_start = filtered_track[0][0] - var diff = (filtered_track[filtered_track.length - 1][0] - filtered_track[0][0]) / 10; - - for (i = 0; i < 10; i++) { - if (filtered_track[i][2]) { - filter_track_legend.push([ - [parseInt(legend_start) + parseInt(i * diff)], - [filtered_track[i][2]] - ]); - } else { - filter_track_legend.push([ - [parseInt(legend_start) + parseInt(i * diff)] - ]); - } - } - - //draw selected 10 positions as legend - var legendtext = svg.selectAll('text.day') - .data(filter_track_legend); - - legendtext.enter().append('svg:text') - .attr('x', 40) - .attr('y', 155) - .attr("transform", function (d, i) { - if (start > 0) { - return "translate(" + (((d[0] - start) * space) + 150) + "," + 100 + ")rotate(90)"; - } - else { - return "translate(" + (((d[0]) * space) + 150) + "," + 100 + ")rotate(90)"; - } - }) - .text(function (d) { - if (d[0] > 1000000) { - return parseFloat(d[0] / 1000000).toFixed(2) + "M"; - } else if (d[0] > 1000) { - return parseFloat(d[0] / 1000).toFixed(2) + "K"; - } else { - if (d[1]) { - return parseInt(d[0]) + " - " + (parseInt(d[0]) + parseInt(d[1])); - } else { - return parseInt(d[0]); - } - } - }); - - -// lines at bottom of diagram to show the positions - var line = svg.selectAll("line.bottom") - .data(filter_track_legend); - - line.enter().insert("svg:line") - .attr("class", "line") - .attr("x1", function (d) { - if (start > 0) { - return parseInt((d[0] - start) * space); - } - else { - return parseInt((d[0] ) * space); - } - }) - .attr("y1", 130) - .attr("x2",function (d) { - if (start > 0) { - return parseInt((d[0] - start) * space); - } - else { - return parseInt((d[0] ) * space); - } - }).attr("y2", 140) - .attr('stroke', function () { - return "black"; - }); - - //draw path from calculated chart axis - path.enter().append("svg:path") - .attr("width", 200) - .attr("height", 200) - .attr("class", "path") - - .attr('stroke', function () { - return "steelblue"; - }) - .attr('stroke-width', function () { - return "1px"; - }) - .attr("fill", function () { - return color; - }) - .attr("d", d3line2(pathinfo)); - - } - } else { - alert("Reference not set: use instance.setReference") - } - - - }, - - /** - * Private: Clears all divs content. - * @ignore - */ - _clear: function (target) { - jQuery('#' + target + '_wigFeaturePainter-holder').html(""); - }, - - /** - * Private: sets data source. - * @param {string} [dataset], it sets file path to this.opt.dataset. - * @ignore - */ - _setDataSource: function (dataSet) { - this.opt.dataSet = dataSet; - }, - - _addSimpleClickTrigger: function () { - - var self = this; - - // Add the click event to each character in the content - this._container.find('span') - .click(function (e) { - // TIP: e.target contains the clicked DOM node - var selected = jQuery(e.target).text(); - - // Create an event object - var evtObject = { "selected": selected }; - - // We're ready to raise the event onClick of our component - self.raiseEvent('onClick', evtObject); - }); - } - - - }, { - myself: undefined - }); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.EbiGlobalSearch.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.EbiGlobalSearch.css deleted file mode 100755 index 9b250b7746..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.EbiGlobalSearch.css +++ /dev/null @@ -1,7 +0,0 @@ -body { - /* - background-image: none; - background-color: transparent; - */ -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeature.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeature.css deleted file mode 100755 index 4a3ffaa558..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeature.css +++ /dev/null @@ -1,63 +0,0 @@ -table.hpaSummaryFeature_table { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - vertical-align: baseline; - background: transparent; - border-collapse:collapse; - border-spacing:0; -} - -.hpaSummaryFeature_leftColumn { - background-color:#E0E0E0; - padding:8px; - border:#E0E0E0 solid 1px; - border-top:#E0E0E0 solid 0px; -} - -.hpaSummaryFeature_rightColumn { - padding:8px; - border:#E0E0E0 solid 0px; - border-top:#E0E0E0 solid 1px; - border-left:#C0C0C0 solid 3px; - line-height:120%; -} - -.hpaSummaryFeature_image { - border: #808080 solid 1px; -} - -.hpaSummaryFeature_linkImage{ - background: url('Rocky32px/link.png') no-repeat top right; - background-size:20px; - opacity:0.6; - filter:alpha(opacity=60); - float:right; - z-index:1; - height:30px; - position:absolute; - top:3px; - width:100%; -} - -.hpaSummaryFeature_contentTitle { - font-size:120%; - font-weight:bold; -} - -.hpaSummaryFeature_imageTitle { - font-size:85%; - font-style:italic; -} - -.hpaSummaryFeature_leftContainer{ - width:100%; - text-align:right; - position:relative; -} - -.hpaSummaryFeature_contentNotes, .hpaSummaryFeature_contentLinks { - list-style-type:square; -} diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeatures.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeatures.css deleted file mode 100755 index ecaf27fa39..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.HpaSummaryFeatures.css +++ /dev/null @@ -1,12 +0,0 @@ -.hpaSummaryFeatures_antibodyTitle { - font-size:120%; - font-weight:bold; - border-bottom:#808080 solid 1px; - margin-bottom:4px; - margin-top:4px; -} - -.hpaSummaryFeatures_summary { - margin-bottom:10px; -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.InteractionsFilterGraph.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.InteractionsFilterGraph.css deleted file mode 100755 index 6800bcc4cc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.InteractionsFilterGraph.css +++ /dev/null @@ -1,38 +0,0 @@ - .miFilterTitle{ - background-color: #F0F0F0; - padding: 2px; - font-size: 100%; - font-weight: bold; - } - .miFilterOptions{ - padding: 6px; - font-size: 92%; - - } - .miDisplay{ - margin-top:2px; - /*float:left;*/ - } - #miInformation{ - font-size: 92%; - } - .inInformation{ - padding-right:15px; - } - .miDisplay, .miFilter{ - border: 1px solid #D8D8D8; - background-color:#FAFAFA; - } - .miFilter, .miDisplay{ - margin-bottom:5px; - } - .miFilter{ - margin-right:-2px; - } - .miRadioBtnName{ - padding-right:10px; - } - .miGreyText{ - color:#C0C0C0; - } - diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.PsicquicViewSearch.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.PsicquicViewSearch.css deleted file mode 100755 index 4b54a8a04d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.PsicquicViewSearch.css +++ /dev/null @@ -1,23 +0,0 @@ -@CHARSET "UTF-8"; - -div.PsicquicViewSearch { - padding: 0px; - margin: 40px; - font-family: "Heveltica Neue", Arial, "sans serif"; - font-size: 12px; - color: #066; - white-space:nowrap; - position:relative; - float: left; - -} - -#TheTable{ - font-family: "Heveltica Neue", Arial, "sans serif"; - font-size: 12px; - color: #066; - white-space:nowrap; - position:relative; - float: left; - -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.Tree.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.Tree.css deleted file mode 100755 index 697035b064..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.Tree.css +++ /dev/null @@ -1,489 +0,0 @@ -#YourOwnDivId { - /*width: 900px; */ - //border: 1px solid black; - //overflow: auto; /* will contain if #first is longer than #second */ -} -#tree_panel { - /*width: 300px; - #background-color: #EEEEEE; */ - //max-height:700px; - float:left; /* add this */ - padding: 20px; - /*border: 1px solid red; */ - overflow: auto; /* will contain if #first is longer than #second */ -} -#annotation_panel { - /*border: 1px solid green; - //padding: 20px; */ - //max-height:700px; - overflow: auto; /* if you don't want #second to wrap below #first */ -} - - -text.alignment_text { - /* fill: black; - stroke: none; - opacity: 0.5; */ - font-family: Monaco, Arial, monospace; - font-size: 8pt; -} -rect.A{ - background-color: #EEEEEE; - opacity: 0.4; -} -rect.B{ - background-color: #EEEEEE; - opacity: 0.3; -} -rect.C{ - background-color: #EEEEEE; - opacity: 0.2; -} -rect.D{ - background-color: #EEEEEE; - opacity: 0.1; -} - - -text.leaf_label { - font-size:11px; -} - -text.model_organism { - font-size:12px; - font-weight: bold; -} - -text.highlight_gene { - font-size:14px; - font-weight: bold; -} - -text.missing_species { - font-size:9px; - //color:grey; - opacity: 0.5; -} - -text.species_name { - font-style:italic; -} -path.link { - fill: none; - stroke: gray; - stroke-width: 2.5px; - } - -path.species_link { - fill: none; - stroke: black; - stroke-width: 2.5px; -} -path.absent_species_link { - fill: none; - opacity: 0.5; - stroke-dasharray: 2,2; - //stroke: red; - //stroke-width: 0.5px; -} - - path.selected { - stroke: darkred; - fill: none; - stroke-width: 5px; - } - -.tv_tree_container { - height: 660px; - overflow: auto; - padding: 20px; -} - -.tree_container{ -} - -.middle-display{ } - -.tv_general_info_container { - padding: 10px; - height: 40%; - max-height:210px; - background-color: #FEFEFE; - box-shadow: 0 1px 5px #3D3D3D; - -moz-border-radius: 1em 1em 1em 1em; - border-radius: 1em 1em 1em 1em; - margin-top: 9px; -} - - -circle { - stroke-width: 5.5px; -} - -text.domainlabel{ - color : white; -} - - - -.tv_tooltip, .tv_tooltip-pending-removal { - position: absolute; - background-color: rgba(255,255,255,1); - padding: 10px; - border: 1px solid #ddd; - z-index: 10000; - display: inline-block; - font-family: Arial; - font-size: 13px; - border-radius: 10px; - - pointer-events: none; - - -webkit-user-select: none; - user-select: none; -} - -.tv_contentcontainer { - margin: 0 auto; - padding: 0; - width: 100%; -} - -.tv_breadcrumbs { - color: #48402E; - box-shadow: 0 1px 5px #3D3D3D; - font-size: 1em; - /*height: 40px; */ - padding-bottom: 11px; - padding-left: 11px; - padding-right: 11px; - padding-top: 4px; - -moz-border-radius: 1em 1em 1em 1em; - border-radius: 1em 1em 1em 1em; -} - -.tv_homesidebar { - float: right; - font-size: 0.9em; - margin-left: 13px; - margin-top: 0; - padding-bottom: 10px; - padding-top: 0; - width: 19%; - height: 650px; - -moz-border-radius: 1em 1em 1em 1em; - border-radius: 1em 1em 1em 1em; - -} -.tv_contentcontainer .tv_homecontent { - margin-bottom: 9px; - margin-top: 9px; -} -.tv_homecontent { - background-color: #FEFEFE; - color: #48402E; - overflow: auto; - font-size: 0.9em; - padding-top: 30px; - padding-left: 10px; - /*width: 79.6%;*/ - -moz-border-radius: 1em 1em 1em 1em; - border-radius: 1em 1em 1em 1em; - -} -.clearfloat { - clear: both; - font-size: 1px; - height: 0; - line-height: 0; -} - -div.inline { float:right; } - - -.annotation_div { - filter: alpha(opacity=50); /* internet explorer */ - -khtml-opacity: 0.5; /* khtml, old safari */ - -moz-opacity: 0.5; /* mozilla, netscape */ - opacity: 0.5; /* fx, safari, opera */ -} - - - -.dotted_line { -border-left: 1px dotted gray !important; -margin-left: 5px !important; -padding-left: 5px !important; -} - -.highlight_gene{ - /*font-size: 22px; */ - background: blue; - color: white; -} - -.axis path, -.axis line { - fill: none; - stroke: black; - shape-rendering: crispEdges; - padding-left: 100px; -} - -.axis text { - font-family: sans-serif; - font-size: 11px; -} -.axis { - padding-left: 50px !important; -} - - -.treearea { - padding-top: 50px !important; -} - -#toggle-view { - list-style:none; - font-family:arial; - font-size:11px; - margin:0; - padding:0; - max-width:500px; - min-width:300px; - -} - - #toggle-view #li_head { - margin:10px; - border-bottom:1px solid #ccc; - position:relative; - cursor:pointer; - } - - #toggle-view h3 { - margin:0; - font-size:14px; - } - - #toggle-view span { - position:absolute; - right:5px; top:0; - color:#ccc; - font-size:13px; - } - - #toggle-view .panel { - margin:5px 0; - display:none; - } - - - p { - margin: 10px; - } - - #sliderLabel { - border: 1px solid #a2a2a2; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - cursor: pointer; - display: block; - height: 30px; - margin: 20px auto; - overflow: hidden; - position: relative; - width: 200px; - } - #sliderLabel input { - display: none; - } - #sliderLabel input:checked + #slider { - left: 110px; - } - #slider { - left: -50px; - position: absolute; - top: 0px; - -moz-transition: left .25s ease-out; - -webkit-transition: left .25s ease-out; - -o-transition: left .25s ease-out; - transition: left .25s ease-out; - } - #sliderOn, #sliderBlock, #sliderOff { - display: block; - font-family: arial, verdana, sans-serif; - font-weight: bold; - height: 30px; - line-height: 30px; - position: absolute; - text-align: center; - top: 0px; - } - #sliderOn { - background: #3269aa; - background: -moz-linear-gradient(top, #3269aa 0%, #82b3f4 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3269aa), color-stop(100%,#82b3f4)); - background: -webkit-linear-gradient(top, #3269aa 0%,#82b3f4 100%); - background: -o-linear-gradient(top, #3269aa 0%,#82b3f4 100%); - background: -ms-linear-gradient(top, #3269aa 0%,#82b3f4 100%); - background: linear-gradient(top, #3269aa 0%,#82b3f4 100%); - color: white; - left: -110px; - width: 164px; - } - #sliderBlock { - background: #d9d9d8; - background: -moz-linear-gradient(top, #d9d9d8 0%, #fcfcfc 100%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#d9d9d8), color-stop(100%,#fcfcfc)); - background: -webkit-linear-gradient(top, #d9d9d8 0%,#fcfcfc 100%); - background: -o-linear-gradient(top, #d9d9d8 0%,#fcfcfc 100%); - background: -ms-linear-gradient(top, #d9d9d8 0%,#fcfcfc 100%); - background: linear-gradient(top, #d9d9d8 0%,#fcfcfc 100%); - border: 1px solid #a2a2a2; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - height: 28px; - left: 50px; - width: 50px; - } - #sliderOff { - background: #f2f3f2; - background: -moz-linear-gradient(top, #8b8c8b 0%, #f2f3f2 50%); - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#8b8c8b), color-stop(50%,#f2f3f2)); - background: -webkit-linear-gradient(top, #8b8c8b 0%,#f2f3f2 50%); - background: -o-linear-gradient(top, #8b8c8b 0%,#f2f3f2 50%); - background: -ms-linear-gradient(top, #8b8c8b 0%,#f2f3f2 50%); - background: linear-gradient(top, #8b8c8b 0%,#f2f3f2 50%); - color: #8b8b8b; - left: 100px; - width: 150px; - } - - - -.settings div { - float: left; - margin-right: 5px; - -} - -.settings ul { - list-style-type: none; - margin: 0; - padding: 0; -} - -.settings { - width: 100%; - overflow: hidden; -} -.settings .left{ - float: left; -} -.settings .middle{ - top: 10px; - margin-bottom: -2000px; - padding-bottom: 2000px; -} - .settings .right{ -} - - - -.collapsible, -.page_collapsible { - margin: 0; - padding:10px; - height:20px; - - border-top:#f0f0f0 1px solid; - background: #cccccc; - - font-family: Arial, Helvetica, sans-serif; - text-decoration:none; - text-transform:uppercase; - color: #000; - font-size:1em; -} - -.collapse-open { - background:#000; - color: #fff; -} - -.collapse-open span { - display:block; - float:right; - padding:10px; -} - -.collapse-open span { - background:url(images/minus.png) center center no-repeat; -} - -.collapse-close span { - display:block; - float:right; - background:url(images/plus.png) center center no-repeat; - padding:10px; -} - -div.container { - padding:0; - margin:0; -} - -div.content { - background:#f0f0f0; - margin: 0; - padding:10px; - font-size:.9em; - line-height:1.5em; - font-family:"Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; -} - -div.content ul, div.content p { - margin:0; - padding:3px; -} - -div.content ul li { - list-style-position:inside; - line-height:25px; -} - -div.content ul li a { - color:#555555; -} - -code { - overflow:auto; -} - -div.legend -{ -background-color:transparent; -padding-left: 13px; -//z-index:+2; -font-size:10pt; -font-family:times new roman; -//font-weight:bold; -//font-style:italic; -//color:#23238e; -} - -div.my_custom_menu{ - position: absolute; - text-align: center; - width: 60px; - height: 28px; - padding: 2px; - font: 12px sans-serif; - background: lightsteelblue; - border: 0px; - border-radius: 8px; - pointer-events: none; -} diff --git a/src/lib/biojs-1.0/src/main/resources/css/Biojs.UniProtDiseaseSummary.css b/src/lib/biojs-1.0/src/main/resources/css/Biojs.UniProtDiseaseSummary.css deleted file mode 100755 index 5a3884dd11..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Biojs.UniProtDiseaseSummary.css +++ /dev/null @@ -1,87 +0,0 @@ -#UDS_component_wrapper{ - font-family:Verdana, Geneva, Arial, Helvetica, sans-serif; - font-size:10pt; -} - -table.UDS_table { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - vertical-align: baseline; - background: transparent; - border-collapse:collapse; - border-spacing:0; -} - -.UDS_table_title { - font-size:larger; - font-weight:bold; -} - -.UDS_table_wrapper { - padding: 5px; -} - -.UDS_keywords_wrapper{ - font-size:smaller; - padding: 0px 5px 5px 5px; -} - -.UDS_accs { - padding: 3px 0px 6px 8px; -} - -table.UDS_table tr td -{ - vertical-align:top; - padding: 4px; -} - -table.UDS_table tr -{ - -} - - -.UDS_notes { - text-align:justify; - border: solid 1px #CCCCCC; -} - -.UDS_references{ - border: solid 1px #CCCCCC; -} - - - -.UDS_header { - background-color:#ffffff; - font-weight:bold; -} - -.UDS_omim_title { - font-size:smaller; - font-weight:bold; - text-decoration:underline; -} - -.UDS_pubmed_title { - font-size:smaller; - font-weight:bold; - text-decoration:underline; -} - -.UDS_odd { - background-color:#e7e8ec; -} - -.UDS_even { - background-color:#feffff; -} - -#UDS_warnings { - font-size:smaller; - font-style:italic; -} diff --git a/src/lib/biojs-1.0/src/main/resources/css/GeneExpressionSummary.css b/src/lib/biojs-1.0/src/main/resources/css/GeneExpressionSummary.css deleted file mode 100755 index d2af5b2b9b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/GeneExpressionSummary.css +++ /dev/null @@ -1,68 +0,0 @@ -@CHARSET "UTF-8"; - -div.GeneExpressionSummary { - margin:0px; - padding:0px; -} - -div.GeneExpressionSummary_title { - font-size:120%; - font-weight: bold; - margin-bottom:15px; -} - -.GeneExpressionSummary_table{ - margin: 0; - padding: 0; - border: 0; -} - -div.GeneExpressionSummary table tr td { - vertical-align:top; -} - -div.GeneExpressionSummary table { - padding-left:20px; -} - -div.GeneExpressionSummary_image { - border: thin silver solid; -} - -div.GeneExpressionSummary_image p { - text-align: justify; - font-style: italic; - font-size:85%; - text-indent: 0; - margin:10px; -} - -.GeneExpressionSummary_subtitle { - text-transform: uppercase; - font-size:85%; - font-weight:bold; -} -.GeneExpressionSummary_feature{ - margin-top:5px; - margin-bottom:15px; -} - -/* -div.GeneExpressionSummary_summary a { - background-image:url(Rocky32px/link.png); - display:block; - height:8px; - width:8px; -}*/ - -div.GeneExpressionSummary_summary { - -} - -div.GeneExpressionSummary_footer { - text-align: justify; - font-style: italic; - font-size: 85%; - text-indent: 0; - -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/accessibility.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/accessibility.png.mno deleted file mode 100755 index def6a79bc5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/accessibility.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/add.png.mno deleted file mode 100755 index 5ef5efb4df..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/agenda.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/agenda.png.mno deleted file mode 100755 index 2ac75b95f5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/agenda.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/airplane.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/airplane.png.mno deleted file mode 100755 index d199e91220..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/airplane.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alarm.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alarm.png.mno deleted file mode 100755 index 81dabe2582..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alarm.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/album.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/album.png.mno deleted file mode 100755 index d3ef205772..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/album.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alert.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alert.png.mno deleted file mode 100755 index 8d37e5eaca..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/alert.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/announcement.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/announcement.png.mno deleted file mode 100755 index 9ffe11d61f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/announcement.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/archive.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/archive.png.mno deleted file mode 100755 index b39f4b0ecf..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/archive.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-down.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-down.png.mno deleted file mode 100755 index 7b3ce3db56..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-down.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-left.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-left.png.mno deleted file mode 100755 index 1fc9c75f97..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-left.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-right.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-right.png.mno deleted file mode 100755 index 8358a01869..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-right.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-up.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-up.png.mno deleted file mode 100755 index 7c21df9cf5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/arrow-up.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/art-brush.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/art-brush.png.mno deleted file mode 100755 index a4ac49c3e6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/art-brush.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/auction.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/auction.png.mno deleted file mode 100755 index 6caf7c0ed3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/auction.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/award.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/award.png.mno deleted file mode 100755 index 6373dd34bd..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/award.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-charge.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-charge.png.mno deleted file mode 100755 index 3ceca08e1e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-charge.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-full.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-full.png.mno deleted file mode 100755 index 63d2530746..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-full.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-half.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-half.png.mno deleted file mode 100755 index 74ca1693fd..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-half.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-low.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-low.png.mno deleted file mode 100755 index 33b299f582..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/battery-low.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bell.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bell.png.mno deleted file mode 100755 index f3e26c7a29..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bell.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bicycle.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bicycle.png.mno deleted file mode 100755 index 878215e63b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bicycle.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/blackberry.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/blackberry.png.mno deleted file mode 100755 index 1e3df5ba81..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/blackberry.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bluetooth.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bluetooth.png.mno deleted file mode 100755 index a828247f2d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bluetooth.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/boat.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/boat.png.mno deleted file mode 100755 index 236838c752..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/boat.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/book.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/book.png.mno deleted file mode 100755 index f7c28e59da..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/book.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bookmark.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bookmark.png.mno deleted file mode 100755 index 6bc5ba3bca..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bookmark.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/briefcase.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/briefcase.png.mno deleted file mode 100755 index cebb0804b2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/briefcase.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/brightness.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/brightness.png.mno deleted file mode 100755 index aec948939a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/brightness.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bug.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bug.png.mno deleted file mode 100755 index 6e3752ed50..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bug.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bus.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bus.png.mno deleted file mode 100755 index e901c25c19..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/bus.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calculator.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calculator.png.mno deleted file mode 100755 index 8cc4186f2f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calculator.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-add.png.mno deleted file mode 100755 index 46541f5735..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-delete.png.mno deleted file mode 100755 index 869818d433..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-edit.png.mno deleted file mode 100755 index aada76b8f9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-na.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-na.png.mno deleted file mode 100755 index 7e984606a9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-na.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-time.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-time.png.mno deleted file mode 100755 index 55cc9d6796..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar-time.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar.png.mno deleted file mode 100755 index 2e552666d5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/calendar.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/camera.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/camera.png.mno deleted file mode 100755 index 855d79bafe..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/camera.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/car.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/car.png.mno deleted file mode 100755 index 1a21bbc911..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/car.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cd.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cd.png.mno deleted file mode 100755 index 8f7d798c29..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cd.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/chart.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/chart.png.mno deleted file mode 100755 index bfa8e1ac36..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/chart.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check-box.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check-box.png.mno deleted file mode 100755 index ec6e7410d1..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check-box.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check.png.mno deleted file mode 100755 index 1ed08ef92b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/check.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clipboard.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clipboard.png.mno deleted file mode 100755 index 9d568cc446..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clipboard.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clock.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clock.png.mno deleted file mode 100755 index e20b3a118d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/clock.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-cup.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-cup.png.mno deleted file mode 100755 index f5b15c69d8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-cup.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-mug.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-mug.png.mno deleted file mode 100755 index 39bee616f6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/coffee-mug.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/collapse.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/collapse.png.mno deleted file mode 100755 index 14188db472..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/collapse.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-add.png.mno deleted file mode 100755 index 3c7895ab3f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-check.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-check.png.mno deleted file mode 100755 index 3f9618f129..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-check.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-delete.png.mno deleted file mode 100755 index dccde8ece7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-disable.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-disable.png.mno deleted file mode 100755 index 95733beb5e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-disable.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-write.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-write.png.mno deleted file mode 100755 index 8bb1e4c2b8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment-write.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment.png.mno deleted file mode 100755 index c3979aa97b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/comment.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/compass.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/compass.png.mno deleted file mode 100755 index 8a6d4b4e8a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/compass.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connect.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connect.png.mno deleted file mode 100755 index 8da8633c3e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connect.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connection-signal.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connection-signal.png.mno deleted file mode 100755 index 90b7104c0b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/connection-signal.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction-hat.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction-hat.png.mno deleted file mode 100755 index dacea85ce7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction-hat.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction.png.mno deleted file mode 100755 index ca42218aeb..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/construction.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-book.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-book.png.mno deleted file mode 100755 index 096c14dc80..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-book.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-card.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-card.png.mno deleted file mode 100755 index 0edbffe331..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contact-card.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contrast.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contrast.png.mno deleted file mode 100755 index b045a917db..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/contrast.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-eject.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-eject.png.mno deleted file mode 100755 index ab148b4af8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-eject.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-forward.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-forward.png.mno deleted file mode 100755 index e5339d5a8e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-forward.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-next.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-next.png.mno deleted file mode 100755 index 820c13d8c7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-next.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-pause.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-pause.png.mno deleted file mode 100755 index c2d7ee1024..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-pause.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-play.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-play.png.mno deleted file mode 100755 index 6593be8799..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-play.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-previous.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-previous.png.mno deleted file mode 100755 index e6302ddceb..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-previous.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-record.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-record.png.mno deleted file mode 100755 index 632272aff4..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-record.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-rewind.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-rewind.png.mno deleted file mode 100755 index 2b2cc0de98..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-rewind.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-stop.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-stop.png.mno deleted file mode 100755 index 9bab87e8dd..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/controller-stop.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cool.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cool.png.mno deleted file mode 100755 index 6c57dcd4e7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cool.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/copy.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/copy.png.mno deleted file mode 100755 index 7a403eda11..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/copy.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/credit-card.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/credit-card.png.mno deleted file mode 100755 index 27417878e5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/credit-card.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cursor.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cursor.png.mno deleted file mode 100755 index e6447e0143..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cursor.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cut.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cut.png.mno deleted file mode 100755 index e9a62dc695..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/cut.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/dashboard.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/dashboard.png.mno deleted file mode 100755 index 1f16e770e2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/dashboard.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-add.png.mno deleted file mode 100755 index c9b8dec6b5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-check.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-check.png.mno deleted file mode 100755 index e2838bb5fc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-check.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-delete.png.mno deleted file mode 100755 index ead59d6570..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-edit.png.mno deleted file mode 100755 index c1359910c4..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-error.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-error.png.mno deleted file mode 100755 index b5b7e83c16..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-error.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-export.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-export.png.mno deleted file mode 100755 index 45493984b8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-export.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-import.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-import.png.mno deleted file mode 100755 index 3d03131b36..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-import.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-lock.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-lock.png.mno deleted file mode 100755 index b41f8f786f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-lock.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-na.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-na.png.mno deleted file mode 100755 index 44c4e226bb..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-na.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-reload.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-reload.png.mno deleted file mode 100755 index a3ad08fa24..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-reload.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-save.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-save.png.mno deleted file mode 100755 index 123ff52081..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-save.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-search.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-search.png.mno deleted file mode 100755 index a289a1981f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-search.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-start.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-start.png.mno deleted file mode 100755 index 59668f9c5b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-start.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-stop.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-stop.png.mno deleted file mode 100755 index 67b3715e62..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-stop.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-user.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-user.png.mno deleted file mode 100755 index 648e998f43..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database-user.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database.png.mno deleted file mode 100755 index 0fe7a3ffb2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/database.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delete.png.mno deleted file mode 100755 index 36c2f8cf83..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delivery-truck.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delivery-truck.png.mno deleted file mode 100755 index 6b00297c8a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/delivery-truck.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/disconnect.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/disconnect.png.mno deleted file mode 100755 index 823985cee7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/disconnect.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/discussion.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/discussion.png.mno deleted file mode 100755 index c22bba970d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/discussion.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/download.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/download.png.mno deleted file mode 100755 index f778e70949..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/download.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/earth.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/earth.png.mno deleted file mode 100755 index 502c18fc6b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/earth.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/edit-disable.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/edit-disable.png.mno deleted file mode 100755 index fcfeb92979..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/edit-disable.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-delete.png.mno deleted file mode 100755 index 5ee73af91c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-forward.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-forward.png.mno deleted file mode 100755 index 68edfc7e47..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-forward.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-new.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-new.png.mno deleted file mode 100755 index dea45ecc97..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-new.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-open.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-open.png.mno deleted file mode 100755 index 16d015eeb2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-open.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-reply.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-reply.png.mno deleted file mode 100755 index acbbd28e82..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-reply.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-write.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-write.png.mno deleted file mode 100755 index 5b7da42dee..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email-write.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email.png.mno deleted file mode 100755 index 69b962ec3c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/email.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/employee-id.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/employee-id.png.mno deleted file mode 100755 index 5bef7ce4e4..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/employee-id.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/exchange.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/exchange.png.mno deleted file mode 100755 index 2c0cf31930..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/exchange.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/expand.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/expand.png.mno deleted file mode 100755 index f94e5a59ab..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/expand.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eye.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eye.png.mno deleted file mode 100755 index 81036770bb..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eye.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eyedropper.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eyedropper.png.mno deleted file mode 100755 index c5a3f1b13a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/eyedropper.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fan.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fan.png.mno deleted file mode 100755 index ef440b69b1..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fan.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-add.png.mno deleted file mode 100755 index 68f04a132a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-delete.png.mno deleted file mode 100755 index 8cfdaf7992..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-edit.png.mno deleted file mode 100755 index a3b45ce291..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite.png.mno deleted file mode 100755 index a340646d06..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/favorite.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fever-chart.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fever-chart.png.mno deleted file mode 100755 index 2cfb419e34..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fever-chart.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/filter.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/filter.png.mno deleted file mode 100755 index 10964f36d0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/filter.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/financial.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/financial.png.mno deleted file mode 100755 index 0d69928110..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/financial.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/first-aid-box.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/first-aid-box.png.mno deleted file mode 100755 index 4758b82a45..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/first-aid-box.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flag.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flag.png.mno deleted file mode 100755 index c7832240cb..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flag.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flash.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flash.png.mno deleted file mode 100755 index 646d6148dc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/flash.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-add.png.mno deleted file mode 100755 index c357c69733..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-delete.png.mno deleted file mode 100755 index d4c4800d07..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-edit.png.mno deleted file mode 100755 index 8ef85758b3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-search.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-search.png.mno deleted file mode 100755 index a549496447..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder-search.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder.png.mno deleted file mode 100755 index 10215e180a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/folder.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-decrease.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-decrease.png.mno deleted file mode 100755 index 873a1f3793..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-decrease.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-increase.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-increase.png.mno deleted file mode 100755 index 7d46cd74b1..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/font-increase.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-enter.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-enter.png.mno deleted file mode 100755 index 7962a69baa..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-enter.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-exit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-exit.png.mno deleted file mode 100755 index 4f106f97f0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen-exit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen.png.mno deleted file mode 100755 index 7459dd1877..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/fullscreen.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/game-controller.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/game-controller.png.mno deleted file mode 100755 index 9c19e55293..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/game-controller.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift-card.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift-card.png.mno deleted file mode 100755 index 1d28a89f49..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift-card.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift.png.mno deleted file mode 100755 index f7a2200ff6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gift.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-bottom.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-bottom.png.mno deleted file mode 100755 index d9fa5c0b83..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-bottom.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-top.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-top.png.mno deleted file mode 100755 index 0a397081b5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/go-to-top.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gym.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gym.png.mno deleted file mode 100755 index b3e4a0b923..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/gym.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hammer.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hammer.png.mno deleted file mode 100755 index 0d3aba57ff..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hammer.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand-pointer.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand-pointer.png.mno deleted file mode 100755 index 022293ea00..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand-pointer.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand.png.mno deleted file mode 100755 index a1c5309cad..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hand.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/headphone.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/headphone.png.mno deleted file mode 100755 index 2993014466..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/headphone.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/help.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/help.png.mno deleted file mode 100755 index 63b5b8a22c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/help.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/highlighter.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/highlighter.png.mno deleted file mode 100755 index 5cf753997a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/highlighter.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/history.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/history.png.mno deleted file mode 100755 index e26d30e0dc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/history.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/home.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/home.png.mno deleted file mode 100755 index b0798bc09d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/home.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hot.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hot.png.mno deleted file mode 100755 index 8af4835418..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hot.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hourglass.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hourglass.png.mno deleted file mode 100755 index 9c5682bf2b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/hourglass.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/infinite.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/infinite.png.mno deleted file mode 100755 index 3b020b3d8c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/infinite.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/info.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/info.png.mno deleted file mode 100755 index 58cc3e4733..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/info.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/iphone.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/iphone.png.mno deleted file mode 100755 index c9284274cf..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/iphone.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ipod.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ipod.png.mno deleted file mode 100755 index 054e52ca30..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ipod.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/key.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/key.png.mno deleted file mode 100755 index c1364e89d6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/key.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lab.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lab.png.mno deleted file mode 100755 index a85f48b23f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lab.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/laptop.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/laptop.png.mno deleted file mode 100755 index 3d5058cb92..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/laptop.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/light-bulb.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/light-bulb.png.mno deleted file mode 100755 index 0c98aaba55..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/light-bulb.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/link.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/link.png.mno deleted file mode 100755 index 6250cbc4da..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/link.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location-pin.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location-pin.png.mno deleted file mode 100755 index 9d18ec5aa3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location-pin.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location.png.mno deleted file mode 100755 index 057994677e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/location.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lock.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lock.png.mno deleted file mode 100755 index 3cb24fd1ba..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/lock.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/login.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/login.png.mno deleted file mode 100755 index 20ce86c865..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/login.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/logout.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/logout.png.mno deleted file mode 100755 index 1264017a84..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/logout.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/luggage.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/luggage.png.mno deleted file mode 100755 index cd7cf18f66..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/luggage.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/magic-wand.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/magic-wand.png.mno deleted file mode 100755 index ddbea0d27a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/magic-wand.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-in.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-in.png.mno deleted file mode 100755 index 2e411e93e6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-in.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-out.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-out.png.mno deleted file mode 100755 index cf00fc2a8b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox-out.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox.png.mno deleted file mode 100755 index 559d7d7048..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mailbox.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/martini-glass.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/martini-glass.png.mno deleted file mode 100755 index c2a8366a2b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/martini-glass.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/merge.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/merge.png.mno deleted file mode 100755 index e8687d77ad..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/merge.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/microphone.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/microphone.png.mno deleted file mode 100755 index 3116033e13..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/microphone.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/minus.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/minus.png.mno deleted file mode 100755 index c17e539f2f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/minus.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/monitor.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/monitor.png.mno deleted file mode 100755 index 8ee1774120..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/monitor.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mouse.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mouse.png.mno deleted file mode 100755 index 002504a038..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/mouse.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/move.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/move.png.mno deleted file mode 100755 index 135a7001e5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/move.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/museum.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/museum.png.mno deleted file mode 100755 index 182be5128d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/museum.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/music.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/music.png.mno deleted file mode 100755 index 25b4f58644..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/music.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/network.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/network.png.mno deleted file mode 100755 index 4ba6dc70f8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/network.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/newspaper.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/newspaper.png.mno deleted file mode 100755 index 280d7bda44..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/newspaper.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/notepad.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/notepad.png.mno deleted file mode 100755 index 2e2fb09420..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/notepad.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/office-chair.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/office-chair.png.mno deleted file mode 100755 index 422a702235..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/office-chair.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/orbit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/orbit.png.mno deleted file mode 100755 index 676ab5a890..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/orbit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/package-box.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/package-box.png.mno deleted file mode 100755 index 02c5745065..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/package-box.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-add.png.mno deleted file mode 100755 index f189fde898..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-check.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-check.png.mno deleted file mode 100755 index cf968a1224..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-check.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-delete.png.mno deleted file mode 100755 index 93402901e9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-edit.png.mno deleted file mode 100755 index 032fe4a302..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-error.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-error.png.mno deleted file mode 100755 index a55001d17e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-error.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-lock.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-lock.png.mno deleted file mode 100755 index 977c231423..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-lock.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-new.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-new.png.mno deleted file mode 100755 index 0e4931d29e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-new.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-not-found.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-not-found.png.mno deleted file mode 100755 index f1609eb56f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-not-found.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-save.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-save.png.mno deleted file mode 100755 index 489cd86c48..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-save.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-search.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-search.png.mno deleted file mode 100755 index d992b7614a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-search.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-user.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-user.png.mno deleted file mode 100755 index 829e73f827..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page-user.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page.png.mno deleted file mode 100755 index 7708e59fc5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/page.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paint-brush.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paint-brush.png.mno deleted file mode 100755 index bfd0c35c86..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paint-brush.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paper-clip.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paper-clip.png.mno deleted file mode 100755 index ae32393e14..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paper-clip.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paste.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paste.png.mno deleted file mode 100755 index 288d313328..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/paste.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pen.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pen.png.mno deleted file mode 100755 index 3e908c6511..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pen.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pencil.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pencil.png.mno deleted file mode 100755 index 9ec7a1ceef..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pencil.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-classic.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-classic.png.mno deleted file mode 100755 index 1fcf73027a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-classic.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-mobile.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-mobile.png.mno deleted file mode 100755 index 0a863c01c6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone-mobile.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone.png.mno deleted file mode 100755 index 55eee0e26e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/phone.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/picture.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/picture.png.mno deleted file mode 100755 index d455bf0bb5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/picture.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pie-chart.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pie-chart.png.mno deleted file mode 100755 index 8a63b519e7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pie-chart.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pin.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pin.png.mno deleted file mode 100755 index 969f0b1c61..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/pin.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/plugin.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/plugin.png.mno deleted file mode 100755 index c719607e72..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/plugin.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/podcast.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/podcast.png.mno deleted file mode 100755 index a8a9ca23d3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/podcast.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/power.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/power.png.mno deleted file mode 100755 index 8bd7084387..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/power.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/presentation.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/presentation.png.mno deleted file mode 100755 index 83ee9de7c9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/presentation.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/print.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/print.png.mno deleted file mode 100755 index 8cfb7bc860..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/print.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/puzzle.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/puzzle.png.mno deleted file mode 100755 index 49d83ae1b0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/puzzle.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/quote.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/quote.png.mno deleted file mode 100755 index 2bbd0ff03e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/quote.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/radio.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/radio.png.mno deleted file mode 100755 index c22f82af4b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/radio.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/recycle.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/recycle.png.mno deleted file mode 100755 index 5c7c8f152d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/recycle.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/redo.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/redo.png.mno deleted file mode 100755 index d8053c896e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/redo.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/reload.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/reload.png.mno deleted file mode 100755 index d7fe988823..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/reload.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/remote-control.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/remote-control.png.mno deleted file mode 100755 index 6e0d78ebe0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/remote-control.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/repeat.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/repeat.png.mno deleted file mode 100755 index 0ddc45aafe..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/repeat.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/replay.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/replay.png.mno deleted file mode 100755 index b0084e189c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/replay.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/restrict.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/restrict.png.mno deleted file mode 100755 index 54f03bb5a9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/restrict.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rocket.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rocket.png.mno deleted file mode 100755 index e740fe57c8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rocket.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rss.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rss.png.mno deleted file mode 100755 index 00002d33d0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/rss.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/satellite.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/satellite.png.mno deleted file mode 100755 index eb5c9ef89d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/satellite.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/save.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/save.png.mno deleted file mode 100755 index 639d7e617d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/save.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/script.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/script.png.mno deleted file mode 100755 index 91ef1a2172..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/script.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/search.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/search.png.mno deleted file mode 100755 index 3ec0bb064a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/search.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/security.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/security.png.mno deleted file mode 100755 index e2628cf499..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/security.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/setting.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/setting.png.mno deleted file mode 100755 index 9a8474d0e5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/setting.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/share.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/share.png.mno deleted file mode 100755 index cdcd37defa..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/share.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-bag.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-bag.png.mno deleted file mode 100755 index d2b3924d50..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-bag.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-basket.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-basket.png.mno deleted file mode 100755 index 553e9c26b8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-basket.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-cart.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-cart.png.mno deleted file mode 100755 index 2f017ed2c2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shopping-cart.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shovel.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shovel.png.mno deleted file mode 100755 index 1d6106a642..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shovel.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shuffle.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shuffle.png.mno deleted file mode 100755 index 8c0e4eb643..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shuffle.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shutter.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shutter.png.mno deleted file mode 100755 index 6b65793f73..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/shutter.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sign.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sign.png.mno deleted file mode 100755 index 89d2bd11be..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sign.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sitemap.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sitemap.png.mno deleted file mode 100755 index 3ff9a0999a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sitemap.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/slice.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/slice.png.mno deleted file mode 100755 index 48a471513d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/slice.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sofa-chair.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sofa-chair.png.mno deleted file mode 100755 index 5c1e838217..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sofa-chair.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/split.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/split.png.mno deleted file mode 100755 index cfad0257bf..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/split.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sport.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sport.png.mno deleted file mode 100755 index 44c8cf6932..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sport.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sprayer.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sprayer.png.mno deleted file mode 100755 index b48ebe4f22..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/sprayer.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/star.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/star.png.mno deleted file mode 100755 index c7a09ab1e6..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/star.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stock-chart.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stock-chart.png.mno deleted file mode 100755 index c6db00ef6f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stock-chart.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stop.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stop.png.mno deleted file mode 100755 index 5e2eda6508..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/stop.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag-cloud.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag-cloud.png.mno deleted file mode 100755 index 40cd70ae76..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag-cloud.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag.png.mno deleted file mode 100755 index 2f8e7b60d3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tag.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-down.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-down.png.mno deleted file mode 100755 index 44e02cc6c1..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-down.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-up.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-up.png.mno deleted file mode 100755 index 6e2fa63abf..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/thumb-up.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ticket.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ticket.png.mno deleted file mode 100755 index 90c8d10ae5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/ticket.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/timer.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/timer.png.mno deleted file mode 100755 index 2a875f624f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/timer.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool-box.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool-box.png.mno deleted file mode 100755 index b34852a360..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool-box.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool.png.mno deleted file mode 100755 index 7934284af3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tool.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/train.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/train.png.mno deleted file mode 100755 index 74f7cfaae2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/train.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trash.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trash.png.mno deleted file mode 100755 index d5c7ffc228..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trash.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trophy.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trophy.png.mno deleted file mode 100755 index 3357218dfe..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/trophy.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tv.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tv.png.mno deleted file mode 100755 index 24a1b43952..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/tv.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/umbella.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/umbella.png.mno deleted file mode 100755 index ec8dcc5526..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/umbella.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/undo.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/undo.png.mno deleted file mode 100755 index 0dd0dd60f0..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/undo.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/unlock.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/unlock.png.mno deleted file mode 100755 index e0304257b8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/unlock.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/upload.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/upload.png.mno deleted file mode 100755 index 09b8f57a26..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/upload.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/usb.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/usb.png.mno deleted file mode 100755 index 3c51ffe554..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/usb.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-add.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-add.png.mno deleted file mode 100755 index b027c5d5ae..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-add.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-comment.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-comment.png.mno deleted file mode 100755 index fe6cb78dcc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-comment.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-delete.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-delete.png.mno deleted file mode 100755 index 90033dc575..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-delete.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-disable.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-disable.png.mno deleted file mode 100755 index 95c8be9c46..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-disable.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-edit.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-edit.png.mno deleted file mode 100755 index fcd2c42f1c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-edit.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-group.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-group.png.mno deleted file mode 100755 index e7cf3783f8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user-group.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user.png.mno deleted file mode 100755 index 9a0af46d25..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/user.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-camera.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-camera.png.mno deleted file mode 100755 index cea8d01d57..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-camera.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-clapper.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-clapper.png.mno deleted file mode 100755 index 05b2e980e8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-clapper.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-film.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-film.png.mno deleted file mode 100755 index cee0cbf147..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-film.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-reel.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-reel.png.mno deleted file mode 100755 index bb4a763a9b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/video-reel.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command-disable.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command-disable.png.mno deleted file mode 100755 index 66ee60524e..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command-disable.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command.png.mno deleted file mode 100755 index d62f5c7554..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/voice-command.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-high.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-high.png.mno deleted file mode 100755 index 872bb91f6a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-high.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-low.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-low.png.mno deleted file mode 100755 index c750851027..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-low.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-mute.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-mute.png.mno deleted file mode 100755 index d29215100f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/volume-mute.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/walk.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/walk.png.mno deleted file mode 100755 index fe0fbd3673..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/walk.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wallet.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wallet.png.mno deleted file mode 100755 index 02703ccfc5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wallet.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/weather.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/weather.png.mno deleted file mode 100755 index 63f7b3dea7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/weather.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/web.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/web.png.mno deleted file mode 100755 index 3b4a93bca9..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/web.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/webcam.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/webcam.png.mno deleted file mode 100755 index 56f5b8dd64..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/webcam.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wine-glass.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wine-glass.png.mno deleted file mode 100755 index 9bfdd87a55..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wine-glass.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wireless.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wireless.png.mno deleted file mode 100755 index 7dab170957..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/wireless.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/write-note.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/write-note.png.mno deleted file mode 100755 index 080258a934..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/write-note.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-in.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-in.png.mno deleted file mode 100755 index e07daecd7f..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-in.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-out.png.mno b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-out.png.mno deleted file mode 100755 index 145dca8d45..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/_notes/zoom-out.png.mno +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset.png b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset.png deleted file mode 100755 index 37dfc5384c..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset_hover.png b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset_hover.png deleted file mode 100755 index d7f7e4d3c6..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/iconset_hover.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/link.png b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/link.png deleted file mode 100755 index acaefbe938..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/link.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/star_yellow.png b/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/star_yellow.png deleted file mode 100755 index 55a29baa32..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/Rocky32px/star_yellow.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.ChEBICompound.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.ChEBICompound.css deleted file mode 100755 index 7ea560b86d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.ChEBICompound.css +++ /dev/null @@ -1,101 +0,0 @@ -@CHARSET "UTF-8"; - -div.ChEBICompound { - padding: 0px; - margin: 0px; - overflow: hidden; - background-color: white; -} - -div.ChEBICompound_image { - position: relative; - float: right; - width: 65%; - height: 100%; -} - -div.ChEBICompound .noImage { - background-image: url('images/noImage.png') no-repeat; - margin: auto; - width: 48px; - height: 64px -} - - -div.ChEBICompound_tab { - width: 35%; - height: 100%; - position: relative; - float: left; - background-color: #EEF5F5; - background-image: url('images/panel1.png'); - background-repeat: repeat-y; - background-position-x: right; - color: #066; -} - -div.ChEBICompound_image img { - margin-top: auto; - margin-right: auto; - margin-bottom: auto; - margin-left: auto; - display: table-cell; -} - -div.ChEBICompound_tab div.content { - font-family: "Heveltica Neue", Arial, "sans serif"; - font-size: 12px; - color: #066; - word-wrap:break-word; - position:relative; - float: left; -} - -div.ChEBICompound_tab div.content h2 { - font-weight: 600; - margin: 0; - margin: 10px 7px 0 0px; - font-size: 100%; -} - -div.ChEBICompound_tab div.content p { - text-align: left; - font-style: italic; - text-indent: 0; - line-height: 1.2; - padding: 0 7px 0 7px; -} - -div.ChEBICompound_tab div.content div.star { - background-image: url('Rocky32px/star_yellow.png'); - background-size: 16px 16px; - background-repeat: repeat-x; - width: 16px; - height: 16px; - margin: 0 7px 0 7px; -} - -/* Button to hide/show the left panel */ -div.ChEBICompound_tab div.toggle { - width: 24px; - height: 24px; - position:relative; - float: right; - background-image: url('Rocky32px/iconset.png'); -} - -div.ChEBICompound_tab div:hover.toggle { - background-image: url('Rocky32px/iconset_hover.png'); -} - -div.ChEBICompound_tab div.collapse { - background-position: 0 0; -} - -div.ChEBICompound_tab div.expand { - background-position: 0 -24px; -} - - - - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.DNAContentViewer.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.DNAContentViewer.css deleted file mode 100755 index c72da1e5ca..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.DNAContentViewer.css +++ /dev/null @@ -1,17 +0,0 @@ -/* remove label borders in IE6 because IE6 does not support transparency */ -* html .ui-multiselect-checkboxes label { border:none } - -.label{ - overflow: hidden; - text-overflow: ellipsis; -} - -marker-base{ - position:absolute; -} - -.redrawn-path{ - position:absolute; - -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsBundleD3.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsBundleD3.css deleted file mode 100755 index 95724fff40..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsBundleD3.css +++ /dev/null @@ -1,54 +0,0 @@ -.graphCircle { - border: 1px solid #000; - background-color: #E5E5EF; -} - -.graphCircle path.arc { - fill: #fff; -} - -.graphCircle .node { - font-size: 10px; -} - -.graphCircle .node:hover { - fill: #1f77b4; -} - -.graphCircle .link { - fill: none; - stroke: #1f77b4; - stroke-opacity: .4; - pointer-events: none; -} - -.graphCircle .link.source, .graphCircle .link.target { - stroke-opacity: 1; - stroke-width: 2px; -} - -.graphCircle .node.target { - fill: #d62728 !important; -} - -.graphCircle .link.source { - stroke: #d62728; -} - -.graphCircle .node.source { - fill: #2ca02c; -} - -.graphCircle .link.target { - stroke: #2ca02c; -} -.graphCircle .figure { - fill: #46D; -} -.graphCircle .legend { - stroke: transparent; - pointer-events: none; -} -.graphCircle .mainLegend{ - font-size: 70%; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsD3.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsD3.css deleted file mode 100755 index c48926a435..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.InteractionsD3.css +++ /dev/null @@ -1,23 +0,0 @@ -.node { - stroke: #fff; - stroke-width: 1.5px; -} - -.cursor { - fill: none; - stroke: brown; - pointer-events: none; -} -line.link { - stroke: #999; - stroke-opacity: .6; -} - -div.graph { - border: 1px solid #000; - background-color: #E5E5EF; -} - -.figure { - fill: #46D; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.Protein3D.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.Protein3D.css deleted file mode 100755 index 82989dae4d..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.Protein3D.css +++ /dev/null @@ -1,79 +0,0 @@ -@CHARSET "UTF-8"; - -div.Protein3D { - padding: 0px; - margin: 0px; - overflow: hidden; - display: block; -} - -div.Protein3D_loadingImage { - background-image: url('images/ajax-loader-1.gif'); - background-repeat: no-repeat; - background-position: center; - width: 100%; - height: 100%; -} - -div.Protein3D_applet { - position: relative; - float: right; - width: 65%; - height: 100%; -} - -div.Protein3D_tab { - width: 35%; - height: 100%; - position: relative; - float: left; - background-color: #FFF; - background-image: url('images/panel1.png'); - background-repeat: repeat-y; - background-position-x: right; - color: #EEE; -} - -div.Protein3D_tab div.content { - font-family: "Heveltica Neue", Arial, "sans serif"; - font-size: 12px; - position:relative; - float: left; - background-color: #000; -} - -div.Protein3D_tab div.content h1 { - margin: 5px 7px 0 7px; - font-size: 12px; -} - -div.Protein3D_tab div.content input, select { - text-align: left; - line-height: 1.1; - margin: 0 5px 0 7px; -} - -/* Button to hide/show the left panel */ -div.Protein3D_tab div.toggle { - width: 24px; - height: 24px; - position:relative; - float: right; - background-image: url('Rocky32px/iconset.png'); -} - -div.Protein3D_tab div:hover.toggle { - background-image: url('Rocky32px/iconset_hover.png'); -} - -div.Protein3D_tab div.collapse { - background-position: 0 0; -} - -div.Protein3D_tab div.expand { - background-position: 0 -24px; -} - - - - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.ProteinPortafolio.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.ProteinPortafolio.css deleted file mode 100755 index 9bbdd5a39a..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.ProteinPortafolio.css +++ /dev/null @@ -1,71 +0,0 @@ -div.ProteinPortafolio { - width: 900px; - height: 350px; -} - -div.ProteinPortafolio .crop { - width: 100%; - display:table-cell; - position:relative; - vertical-align: middle; -} - -div.ProteinPortafolio .alpha { - float: left; - width: 50%; -} - -div.ProteinPortafolio .beta { - float: right; - width: 50%; -} - -div.ProteinPortafolio .content { - overflow: auto; - height: auto; -} - -div.ProteinPortafolio .header { - height: auto; -} - -div.ProteinPortafolio .toolbar { - -} - -div.ProteinPortafolio ul.features { - list-style: none; - padding-left: 15px; -} - -div.ProteinPortafolio ul.features li span.label { - background: gray; - color: white; - position: relative; - padding: 0.16em; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - margin: 7px 7px 0 0; - text-decoration: none; - left: -10px; - font-family: Helvetica, Arial, sans-serif; -} - -div.ProteinPortafolio ul.features li span.label:after { - display: inline-block; - border: 0.74em solid; - height: 0; - width: 0; - position: absolute; - right: -1.4em; - top: 0; - content: ""; - display: inline-block; - border-color: transparent transparent transparent gray -} - - -div.ProteinPortafolio pre { - padding: 0px; -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.Rheaction.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.Rheaction.css deleted file mode 100755 index 94113a1447..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.Rheaction.css +++ /dev/null @@ -1,35 +0,0 @@ -.scrollpane { - overflow: auto; -} - -.reactionRow { - display: table-row; -} - -div.compound { - display: table-cell; - text-align: center; -} - -.stoichCoef { - font-weight: bold; - padding-left: 0.5em; - padding-right: 0.5em; -} - -.direction { - display: table-cell; - font-weight: bold; - padding-left: 0.5em; - padding-right: 0.5em; -} - -.compoundName { - color: blue; - padding-left: 0.5em; - padding-right: 0.5em; -} - -.compoundStructure { -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.Tooltip.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.Tooltip.css deleted file mode 100755 index dac63d7c03..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.Tooltip.css +++ /dev/null @@ -1,69 +0,0 @@ -@CHARSET "UTF-8"; - -div.Tooltip div.body { - background-color: white; - - border: 1px solid #AAA; - padding: 2px 10px; - word-wrap:break-word; - - min-width: 36px; - min-height: 36px; - - overflow: auto; - - display: table-cell; - vertical-align: middle; - text-align: center; -} - -/* Fancy border */ -div.Tooltip div.body { - -moz-border-radius: 0 7px 0 7px; - -khtml-border-radius: 0 7px 0 7px; - -webkit-border-radius: 0 7px 0 7px; - border-radius: 7px 0 7px 0; - box-shadow: 3px 3px 4px #f3f3f3; - -moz-box-shadow: 3px 3px 4px #f3f3f3; - -khtml-box-shadow: 3px 3px 4px #f3f3f3; - -webkit-box-shadow: 3px 3px 4px #f3f3f3; -} - - - -/* ARROW images */ -div.Tooltip div.arrow { - background: url(images/arrows.png) no-repeat; -} - -div.Tooltip div.left.arrow { - background-position: 0 -1px; - height: 12px; - width: 7px; -} - -div.Tooltip div.right.arrow { - background-position: -12px -1px; - height: 12px; - width: 7px; -} - -div.Tooltip div.top.arrow { - background-position: -37px -1px; - height: 7px; - width: 12px; -} - -div.Tooltip div.bottom.arrow { - background-position: -21px -1px; - height: 7px; - width: 12px; -} - - - - - - - - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.chromosome.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.chromosome.css deleted file mode 100755 index 0cfa0cdcd2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.chromosome.css +++ /dev/null @@ -1,82 +0,0 @@ - -.band { - position: relative; - z-index: 3; - height: 15px; - border: 1px solid #333; - border-right: 0px; - border-left: 0px; - border-image: initial; - cursor: pointer; - float:left; -} -.band:hover { - border-color: #F00; - background-color: #FEE; - -} -.q_acen, .first{ - border-left: 1px solid #333; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - -webkit-top-bottom-left-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-topleft: 4px; -} -.p_acen, .last { - border-right: 1px solid #333; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - -webkit-top-bottom-right-radius: 4px; - -moz-border-radius-bottomright: 4px; - -moz-border-radius-topright: 4px; -} -.p_acen,.q_acen { - background-color: #DDD; -} -.gpos25 { - background-color: rgb(25%, 25%, 25%); -} -.gpos50 { - background-color: rgb(50%, 50%, 50%); -} -.gpos75 { - background-color: rgb(75%, 75%, 75%); -} -.gpos100 { - background-color: #000; -} -.gneg { - background-color: #FFF; -} -.gvar { - background-color: #CCC; -} -.stalk { - background-color: #666; - height: 10px; - top:3px; -} -div.band:before{ - content:attr(title); - display:none; -} -div.band:hover::before{ - width:60px; - display:block; - background:#CCF; - border:1px solid #99C; - padding:4px; - margin: 25px 0 0 -20px; - text-align:center; - border-radius: 3px; - -webkit-radius: 3px; - -moz-border-radius: 3px; -} -div:hover{ - z-index:5; -} -#YourOwnDivId { - padding: 10px; - padding-bottom: 40px; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.detailsFrame.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.detailsFrame.css deleted file mode 100755 index 333f93f8f5..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.detailsFrame.css +++ /dev/null @@ -1,103 +0,0 @@ -.protein ::-webkit-scrollbar { - width: 12px; -} -.protein ::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); - border-radius: 10px; -} -.protein ::-webkit-scrollbar-thumb { - border-radius: 10px; - -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); -} -.protein{ - font-family: "Helvetica Neue", Helvetica, sans-serif; - display: inline-block; - position: relative; - vertical-align: text-top; - text-align: center; - margin: 10px 0 10px 0; - zoom: 1; - -webkit-font-smoothing: antialiased; - background: #E9EEEF; - width: 240px; - border-radius: 10px; - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3),inset 0 1px 1px rgba(255, 255, 255, 0.8); - -moz-box-shadow: 0 1px 3px rgba(0,0,0,0.3),inset 0 1px 1px rgba(255,255,255,0.8); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3),inset 0 1px 1px rgba(255, 255, 255, 0.8); - padding: 10px 10px 10px 10px; -} -header.protein-label { - font-size: 22px; - font-weight: bold; - font-style: normal; - color: #333; - letter-spacing: .8px; - text-align: center; - padding-bottom: 0px; -} -.protein ul { - line-height: 150%; - list-style: none; - text-align: left; - padding: 0px; - margin: 0px; - height: 20em; - overflow: auto; -} - -.protein li { - padding: 0px; - display: block; - margin: 0 auto 0 auto; - color: gray; -} -.protein .protein-description{ - text-align: center; - margin: 0 0 0 auto; -} -.protein .protein-description h2 { - font-weight: normal; - font-variant: normal; - font-style:italic; - line-height: 1.5; - font-size: 14px; - color: #888; - display: inline-block; - padding-bottom: 10px; - margin-top: 0px; - margin-bottom: 5px; - border-bottom: 1px dotted gray; - zoom: 1; -} -.to_minimize{ - background-image:url('images/arrowAR.png'); - background-repeat: no-repeat; -} -.minimized{ - background-image:url('images/arrowDL.png'); - background-repeat: no-repeat; -} -.minimize{ - float: right; - position:relative; - top: 5px; - right: 5px; - width:20px; - height: 20px; -} -.minimize:hover{ - cursor: pointer; -} -.dragger{ - background-image:url('images/draggable.png'); - background-repeat: no-repeat; - width:20px; - height: 20px; - float: left; - position:relative; - top: 5px; - left: 5px; -} -.dragger:hover{ - cursor: move; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.expressionLoader.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.expressionLoader.css deleted file mode 100755 index 40a0823404..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.expressionLoader.css +++ /dev/null @@ -1,47 +0,0 @@ -.ui-dialog table { - background-color:gray; -} -.ui-dialog td, .ui-dialog th { - background-color:white; text-align:center; -} -.button-link { - display:none; -} -.fake-file{ - padding-left:32px; - padding-top:16px; - vertical-align:middle; - background-image:url('images/open-exp.png'); -} -.exp-edit{ - background-image:url('images/pencil-exp.png'); -} -.exp-remove{ - background-image:url('images/off-exp.png'); -} -.fake-file, .exp-edit , .exp-remove{ - min-width:32px; - height:32px; - background-repeat: no-repeat; - float: left; - margin: 5px; - color: #1F77B4; - text-decoration: underline; - font-size: 75%; -} -.fake-file:hover, .exp-edit:hover, .exp-remove:hover { - cursor: pointer; - font-weight:bold; - background-color: #FDD; -} -output { - text-decoration: none; - font-size: 75%; - color: #F55; -} -label[for=color] { - font-size: 75%; - text-decoration: none; - padding-top: 10px; - -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.interactiveInteractionTable.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.interactiveInteractionTable.css deleted file mode 100755 index 4aaea98e58..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.interactiveInteractionTable.css +++ /dev/null @@ -1,38 +0,0 @@ -/* Default style for interativeDataTable */ - -div.dataTables_paginate { - float: right; - -} - -div.dataTables_filter { - float: right; - margin-top:10px; - margin-right:5px; - margin-bottom:5px; -} - -div.dataTables_length { - float: left; - margin-top:10px; - margin-left:5px; - margin-bottom:5px; -} - -.dataTables_cellWrapper { - white-space:nowrap; - text-overflow:ellipsis; - overflow:hidden; - display:block; - width:80px; /*80px*/ - /*text-align: left;*/ - /*background: #91c5d4;*/ -} - -.ellipsis { - white-space:nowrap; - text-overflow:ellipsis; - overflow:hidden; - width:25px; - display:block; -} diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.ruler.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.ruler.css deleted file mode 100755 index 832d774a72..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.ruler.css +++ /dev/null @@ -1,116 +0,0 @@ -.ruler { - height:100%; - line-height:1; - font-family:Helvetica, Arial, sans-serif; - color:#666; - font-size: 12px; -} - -.ruler .active_rules, .rules_editor{ - background-image:url('images/arrow_right_small.png'); - background-repeat: no-repeat; - background-color: transparent; - padding: 7px 10px 10px 40px; -} -.ruler header{ - font-size: 120%; - font-weight:bold; - letter-spacing: -0.04em; -} -.ruler ul{ - list-style-type: none; - padding: 0px; - margin: 0px; -} -.ruler ul li{ - background-color: #F3F3F3; - padding: 6px; - margin-top:8px; - border-radius: 15px; - -webkit-border-radius: 15px; - -moz-border-radius: 15px; - -webkit-box-shadow: rgba(0, 0, 128, 0.246094) 2px 2px 1px; -} -.ruler .active_rules ul.sortable li{ - padding-left: 40px; -} -.ruler .active_rules ul.sortable li:hover{ - background-color: #F3F8F3; - background-image:url('images/draggable.png'); - background-repeat: no-repeat; - background-position: 10px 4px; -} -.rule { - width:80%; -} -.rights { - text-align:right; -} -.affected { - width:9%; - text-align:center; - font-size: 70%; - border: 1px solid #CCC; - padding: 0px 2px 0px 2px; - border-radius: .8em; - -webkit-border-radius: .8em; - -moz-border-radius: .5em; - text-align:right; -} -table { - width:100% -} -.rule_item{ - list-style-type: none; -} -.rule_item td { - background: transparent; - border: 0px; -} -.rule_item table{ - margin: 0px; -} -.action { - width:9%; - text-align:center; - font-size: 85%; - background-color: #E3E3E3; - padding: 2px; - border-radius: 7px; - -webkit-border-radius: 7px; - -moz-border-radius: 7px; - -webkit-box-shadow: rgba(0, 0, 128, 0.246094) 2px 2px 1px; -} -.action:active { - background-color: #F3F3F3; - -webkit-box-shadow: rgba(0, 0, 128, 0.246094) -2px -2px 1px; - -} -.action:hover { - font-weight:bold; - cursor: pointer; -} -.styled-select { - background-color: transparent; - font-family:Helvetica, Arial, sans-serif; - font-size: 12px; - text-decoration: underline; - border: 0px ; - overflow: hidden; - -webkit-appearance: none; -} -.styled-select:hover { - cursor: pointer; -} -.add_rule { - text-align:right; - margin-top:10px; - text-decoration: underline; -} -.add_rule a{ - font-weight:bold; -} -.add_rule a:hover { - color: #898; - cursor: pointer; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.selector.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.selector.css deleted file mode 100755 index 00274af704..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.selector.css +++ /dev/null @@ -1,30 +0,0 @@ -.selector { - border: 1px solid #00F; - position: absolute; - height: 30px; - width: 30px; - z-index: 10; - background-color: rgb(75%, 75%, 100%); - opacity:0.4; - filter:alpha(opacity=40); /* For IE8 and earlier */ -} - -.scaler { - z-index: 11; - position: absolute; - height: 10px; - width: 10px; - border: 0px solid blue; - background-image:url('images/grid2.png'); - background-repeat:repeat; -} - -.left {cursor:w-resize;} -.right {cursor:e-resize;} -.top {cursor:n-resize;} -.bottom {cursor:s-resize;} - - -#YourOwnDivId { - height: 100px; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.table.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.table.css deleted file mode 100755 index 9ef960a630..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.table.css +++ /dev/null @@ -1,227 +0,0 @@ - -/* - * Table - */ -table.dataTable { - margin: 0 auto; - clear: both; - width: 100%; -} - -table.dataTable thead tr th { - padding: 3px 18px 3px 10px; - font-weight: bold; - cursor: pointer; - *cursor: hand; - color: #FFF; - background: #777; - white-space: nowrap; -} - -table.dataTable tfoot th { - padding: 3px 18px 3px 10px; - border-top: 1px solid black; - font-weight: bold; -} - -table.dataTable td { - padding: 3px 10px; - border: 1px solid #EBEBEB; - background-color: inherit; -} - -table.dataTable td.center, -table.dataTable td.dataTables_empty { - text-align: center; -} - -/* - * Rows coloring - */ -table.dataTable tr.selected td { background-color: #fffba4; } - -table.dataTable tr.odd { background-color: white; } -table.dataTable tr.even { background-color: white; } - -table.dataTable tr.odd td.sorting_1 { background-color: #A9C7E0; } -table.dataTable tr.odd td.sorting_2 { background-color: #A9C7E0; } -table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } - -table.dataTable tr.even td.sorting_1 { background-color: #A9C7E0; } -table.dataTable tr.even td.sorting_2 { background-color: #A9C7E0; } -table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } - - -/* - * Table wrapper - */ -.dataTables_wrapper { - position: relative; - clear: both; - *zoom: 1; -} - - -/* - * Page length menu - */ -.dataTables_length { - float: left; -} - - -/* - * Filter - */ -.dataTables_filter { - float: left; - text-align: right; - margin: 0px 0px 5px 0px; -} - -/* - * Table information - */ -.dataTables_info { - clear: both; - float: left; -} - -/* - * Pagination - */ -.dataTables_paginate { - float: right; - text-align: right; -} - -/* Full number pagination */ -.paging_full_numbers { - height: 22px; - line-height: 22px; -} -.paging_full_numbers a:active { - outline: none -} -.paging_full_numbers a:hover { - text-decoration: none; -} - -.paging_full_numbers a.paginate_button, -.paging_full_numbers a.paginate_active { - border: 0px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; - border-radius: 3px; - padding: 2px 5px; - margin: 0 1px; - cursor: pointer; - *cursor: hand; - color: #FFF !important; -} - -.paging_full_numbers a.paginate_button { - background-color: #555544; -} - -.paging_full_numbers a.paginate_button:hover { - background-color: #ccc; - text-decoration: none !important; -} - -.paging_full_numbers a.paginate_active { - background-color: #5D96C5; -} - -.paging_full_numbers a.paginate_active:hover { - background-color: #ccc; -} - -.paging_full_numbers a.first { - -} - - -/* - * Processing indicator - */ -.dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 250px; - height: 30px; - margin-left: -125px; - margin-top: -15px; - padding: 14px 0 2px 0; - border: 1px solid #ddd; - text-align: center; - color: #999; - font-size: 14px; - background-color: white; -} - - -/* - * Sorting - */ -.sorting { background: url('images/sort_both.png') no-repeat center right; } -.sorting_asc { background: url('images/sort_asc.png') no-repeat center right; } -.sorting_desc { background: url('images/sort_desc.png') no-repeat center right; } - -.sorting_asc_disabled { background: url('images/sort_asc_disabled.png') no-repeat center right; } -.sorting_desc_disabled { background: url('images/sort_desc_disabled.png') no-repeat center right; } - -table.dataTable th:active { - outline: none; -} - - -/* - * Scrolling - */ -.dataTables_scroll { - clear: both; -} - -.dataTables_scrollBody { - *margin-top: -1px; -} - - - -/* - * MultiSelect Plugin - */ -.dataTables_settings { - float: right; - width: auto; -} - -.ui-multiselect { padding:0px; text-align:left } -.ui-multiselect span.ui-icon { float:right } -.ui-multiselect-single .ui-multiselect-checkboxes input { position:absolute !important; top: auto !important; left:-9999px; } -.ui-multiselect-single .ui-multiselect-checkboxes label { padding:5px !important } - -.ui-multiselect-header { margin-bottom:3px; padding:3px 0 3px 4px } -.ui-multiselect-header ul { font-size:0.9em } -.ui-multiselect-header ul li { float:left; padding:0 10px 0 0 } -.ui-multiselect-header a { text-decoration:none } -.ui-multiselect-header a:hover { text-decoration:underline } -.ui-multiselect-header span.ui-icon { float:left } -.ui-multiselect-header li.ui-multiselect-close { float:right; text-align:right; padding-right:0 } - -.ui-multiselect-menu { display:none; padding:3px; position:absolute; z-index:10000 } -.ui-multiselect-checkboxes { position:relative /* fixes bug in IE6/7 */; overflow-y:scroll } -.ui-multiselect-checkboxes label { cursor:default; display:block; border:1px solid transparent; padding:3px 1px } -.ui-multiselect-checkboxes label input { position:relative; top:1px } -.ui-multiselect-checkboxes li { clear:both; font-size:0.9em; padding-right:3px } -.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label { text-align:center; font-weight:bold; border-bottom:1px solid } -.ui-multiselect-checkboxes li.ui-multiselect-optgroup-label a { display:block; padding:3px; margin:1px 0; text-decoration:none } - -/* remove label borders in IE6 because IE6 does not support transparency */ -* html .ui-multiselect-checkboxes label { border:none } - - - - diff --git a/src/lib/biojs-1.0/src/main/resources/css/biojs.wigExplorer.css b/src/lib/biojs-1.0/src/main/resources/css/biojs.wigExplorer.css deleted file mode 100755 index da657c15a3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/biojs.wigExplorer.css +++ /dev/null @@ -1,27 +0,0 @@ -/* remove label borders in IE6 because IE6 does not support transparency */ -* html .ui-multiselect-checkboxes label { border:none } - -.label{ - overflow: hidden; - text-overflow: ellipsis; -} - -table { - background-color: #FFFFFF; - border: 5px solid #F1F1F1; - border-collapse: collapse; - margin: 9px auto; - width: 99%; -} - -th, td { - font-size: 93%; -} -th, td { - border: 1px solid #F1F1F1; - border-collapse: collapse; - padding: 8px 5px 5px; - vertical-align: top; -} - - diff --git a/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_page.css b/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_page.css deleted file mode 100755 index 89c62bb785..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_page.css +++ /dev/null @@ -1,107 +0,0 @@ - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * General page setup - */ -#dt_example { - font: 80%/1.45em "Lucida Grande", Verdana, Arial, Helvetica, sans-serif; - margin: 0; - padding: 0; - color: #333; - background-color: #fff; -} - - -#dt_example #container { - width: 800px; - margin: 30px auto; - padding: 0; -} - - -#dt_example #footer { - margin: 50px auto 0 auto; - padding: 0; -} - -#dt_example #demo { - margin: 30px auto 0 auto; -} - -#dt_example .demo_jui { - margin: 30px auto 0 auto; -} - -#dt_example .big { - font-size: 1.3em; - font-weight: bold; - line-height: 1.6em; - color: #4E6CA3; -} - -#dt_example .spacer { - height: 20px; - clear: both; -} - -#dt_example .clear { - clear: both; -} - -#dt_example pre { - padding: 15px; - background-color: #F5F5F5; - border: 1px solid #CCCCCC; -} - -#dt_example h1 { - margin-top: 2em; - font-size: 1.3em; - font-weight: normal; - line-height: 1.6em; - color: #4E6CA3; - border-bottom: 1px solid #B0BED9; - clear: both; -} - -#dt_example h2 { - font-size: 1.2em; - font-weight: normal; - line-height: 1.6em; - color: #4E6CA3; - clear: both; -} - -#dt_example a { - color: #0063DC; - text-decoration: none; -} - -#dt_example a:hover { - text-decoration: underline; -} - -#dt_example ul { - color: #4E6CA3; -} - -.css_right { - float: right; -} - -.css_left { - float: left; -} - -.demo_links { - float: left; - width: 50%; - margin-bottom: 1em; -} - -#demo_info { - padding: 5px; - border: 1px solid #B0BED9; - height: 100px; - width: 100%; - overflow: auto; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_table.css b/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_table.css deleted file mode 100755 index f41a0042d2..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/dataTable/demo_table.css +++ /dev/null @@ -1,576 +0,0 @@ -/* - * File: demo_table.css - * CVS: $Id$ - * Description: CSS descriptions for DataTables demo pages - * Author: Allan Jardine - * Created: Tue May 12 06:47:22 BST 2009 - * Modified: $Date$ by $Author$ - * Language: CSS - * Project: DataTables - * - * Copyright 2009 Allan Jardine. All Rights Reserved. - * - * *************************************************************************** - * DESCRIPTION - * - * The styles given here are suitable for the demos that are used with the standard DataTables - * distribution (see www.datatables.net). You will most likely wish to modify these styles to - * meet the layout requirements of your site. - * - * Common issues: - * 'full_numbers' pagination - I use an extra selector on the body tag to ensure that there is - * no conflict between the two pagination types. If you want to use full_numbers pagination - * ensure that you either have "example_alt_pagination" as a body class name, or better yet, - * modify that selector. - * Note that the path used for Images is relative. All images are by default located in - * ../images/ - relative to this CSS file. - */ - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables features - */ - -.dataTables_wrapper { - position: relative; - clear: both; - zoom: 1; /* Feeling sorry for IE */ -} - -.dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 250px; - height: 30px; - margin-left: -125px; - margin-top: -15px; - padding: 14px 0 2px 0; - border: 1px solid #ddd; - text-align: center; - color: #999; - font-size: 14px; - background-color: white; -} - -.dataTables_length { - width: 40%; - float: left; -} - -.dataTables_filter { - width: 50%; - float: right; - text-align: right; -} - -.dataTables_info { - width: 60%; - float: left; -} - -.dataTables_paginate { - float: right; - text-align: right; -} - -/* Pagination nested */ -.paginate_disabled_previous, .paginate_enabled_previous, -.paginate_disabled_next, .paginate_enabled_next { - height: 19px; - float: left; - cursor: pointer; - *cursor: hand; - color: #111 !important; -} -.paginate_disabled_previous:hover, .paginate_enabled_previous:hover, -.paginate_disabled_next:hover, .paginate_enabled_next:hover { - text-decoration: none !important; -} -.paginate_disabled_previous:active, .paginate_enabled_previous:active, -.paginate_disabled_next:active, .paginate_enabled_next:active { - outline: none; -} - -.paginate_disabled_previous, -.paginate_disabled_next { - color: #666 !important; -} -.paginate_disabled_previous, .paginate_enabled_previous { - padding-left: 23px; -} -.paginate_disabled_next, .paginate_enabled_next { - padding-right: 23px; - margin-left: 10px; -} - -.paginate_disabled_previous { - background: url('../images/back_disabled.png') no-repeat top left; -} - -.paginate_enabled_previous { - background: url('../images/back_enabled.png') no-repeat top left; -} -.paginate_enabled_previous:hover { - background: url('../images/back_enabled_hover.png') no-repeat top left; -} - -.paginate_disabled_next { - background: url('../images/forward_disabled.png') no-repeat top right; -} - -.paginate_enabled_next { - background: url('../images/forward_enabled.png') no-repeat top right; -} -.paginate_enabled_next:hover { - background: url('../images/forward_enabled_hover.png') no-repeat top right; -} - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables display - */ -table.display { - margin: 0 auto; - clear: both; - width: 100%; - - /* Note Firefox 3.5 and before have a bug with border-collapse - * ( https://bugzilla.mozilla.org/show%5Fbug.cgi?id=155955 ) - * border-spacing: 0; is one possible option. Conditional-css.com is - * useful for this kind of thing - * - * Further note IE 6/7 has problems when calculating widths with border width. - * It subtracts one px relative to the other browsers from the first column, and - * adds one to the end... - * - * If you want that effect I'd suggest setting a border-top/left on th/td's and - * then filling in the gaps with other borders. - */ -} - -table.display thead th { - padding: 3px 18px 3px 10px; - border-bottom: 1px solid black; - font-weight: bold; - cursor: pointer; - * cursor: hand; -} - -table.display tfoot th { - padding: 3px 18px 3px 10px; - border-top: 1px solid black; - font-weight: bold; -} - -table.display tr.heading2 td { - border-bottom: 1px solid #aaa; -} - -table.display td { - padding: 3px 10px; -} - -table.display td.center { - text-align: center; -} - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables sorting - */ - -.sorting_asc { - background: url('../images/sort_asc.png') no-repeat center right; -} - -.sorting_desc { - background: url('../images/sort_desc.png') no-repeat center right; -} - -.sorting { - background: url('../images/sort_both.png') no-repeat center right; -} - -.sorting_asc_disabled { - background: url('../images/sort_asc_disabled.png') no-repeat center right; -} - -.sorting_desc_disabled { - background: url('../images/sort_desc_disabled.png') no-repeat center right; -} - -th:active { - outline: none; -} - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * DataTables row classes - */ -table.display tr.odd.gradeA { - background-color: #ddffdd; -} - -table.display tr.even.gradeA { - background-color: #eeffee; -} - -table.display tr.odd.gradeC { - background-color: #ddddff; -} - -table.display tr.even.gradeC { - background-color: #eeeeff; -} - -table.display tr.odd.gradeX { - background-color: #ffdddd; -} - -table.display tr.even.gradeX { - background-color: #ffeeee; -} - -table.display tr.odd.gradeU { - background-color: #ddd; -} - -table.display tr.even.gradeU { - background-color: #eee; -} - - -tr.odd { - background-color: #E2E4FF; -} - -tr.even { - background-color: white; -} - - - - - -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Misc - */ -.dataTables_scroll { - clear: both; -} - -.dataTables_scrollBody { - *margin-top: -1px; - -webkit-overflow-scrolling: touch; -} - -.top, .bottom { - padding: 15px; - background-color: #F5F5F5; - border: 1px solid #CCCCCC; -} - -.top .dataTables_info { - float: none; -} - -.clear { - clear: both; -} - -.dataTables_empty { - text-align: center; -} - -tfoot input { - margin: 0.5em 0; - width: 100%; - color: #444; -} - -tfoot input.search_init { - color: #999; -} - -td.group { - background-color: #d1cfd0; - border-bottom: 2px solid #A19B9E; - border-top: 2px solid #A19B9E; -} - -td.details { - background-color: #d1cfd0; - border: 2px solid #A19B9E; -} - - -.example_alt_pagination div.dataTables_info { - width: 40%; -} - -.paging_full_numbers { - width: 400px; - height: 22px; - line-height: 22px; -} - -.paging_full_numbers a:active { - outline: none -} - -.paging_full_numbers a:hover { - text-decoration: none; -} - -.paging_full_numbers a.paginate_button, - .paging_full_numbers a.paginate_active { - border: 1px solid #aaa; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - padding: 2px 5px; - margin: 0 3px; - cursor: pointer; - *cursor: hand; - color: #333 !important; -} - -.paging_full_numbers a.paginate_button { - background-color: #ddd; -} - -.paging_full_numbers a.paginate_button:hover { - background-color: #ccc; - text-decoration: none !important; -} - -.paging_full_numbers a.paginate_active { - background-color: #99B3FF; -} - -table.display tr.even.row_selected td { - background-color: #B0BED9; -} - -table.display tr.odd.row_selected td { - background-color: #9FAFD1; -} - - -/* - * Sorting classes for columns - */ -/* For the standard odd/even */ -tr.odd td.sorting_1 { - background-color: #D3D6FF; -} - -tr.odd td.sorting_2 { - background-color: #DADCFF; -} - -tr.odd td.sorting_3 { - background-color: #E0E2FF; -} - -tr.even td.sorting_1 { - background-color: #EAEBFF; -} - -tr.even td.sorting_2 { - background-color: #F2F3FF; -} - -tr.even td.sorting_3 { - background-color: #F9F9FF; -} - - -/* For the Conditional-CSS grading rows */ -/* - Colour calculations (based off the main row colours) - Level 1: - dd > c4 - ee > d5 - Level 2: - dd > d1 - ee > e2 - */ -tr.odd.gradeA td.sorting_1 { - background-color: #c4ffc4; -} - -tr.odd.gradeA td.sorting_2 { - background-color: #d1ffd1; -} - -tr.odd.gradeA td.sorting_3 { - background-color: #d1ffd1; -} - -tr.even.gradeA td.sorting_1 { - background-color: #d5ffd5; -} - -tr.even.gradeA td.sorting_2 { - background-color: #e2ffe2; -} - -tr.even.gradeA td.sorting_3 { - background-color: #e2ffe2; -} - -tr.odd.gradeC td.sorting_1 { - background-color: #c4c4ff; -} - -tr.odd.gradeC td.sorting_2 { - background-color: #d1d1ff; -} - -tr.odd.gradeC td.sorting_3 { - background-color: #d1d1ff; -} - -tr.even.gradeC td.sorting_1 { - background-color: #d5d5ff; -} - -tr.even.gradeC td.sorting_2 { - background-color: #e2e2ff; -} - -tr.even.gradeC td.sorting_3 { - background-color: #e2e2ff; -} - -tr.odd.gradeX td.sorting_1 { - background-color: #ffc4c4; -} - -tr.odd.gradeX td.sorting_2 { - background-color: #ffd1d1; -} - -tr.odd.gradeX td.sorting_3 { - background-color: #ffd1d1; -} - -tr.even.gradeX td.sorting_1 { - background-color: #ffd5d5; -} - -tr.even.gradeX td.sorting_2 { - background-color: #ffe2e2; -} - -tr.even.gradeX td.sorting_3 { - background-color: #ffe2e2; -} - -tr.odd.gradeU td.sorting_1 { - background-color: #c4c4c4; -} - -tr.odd.gradeU td.sorting_2 { - background-color: #d1d1d1; -} - -tr.odd.gradeU td.sorting_3 { - background-color: #d1d1d1; -} - -tr.even.gradeU td.sorting_1 { - background-color: #d5d5d5; -} - -tr.even.gradeU td.sorting_2 { - background-color: #e2e2e2; -} - -tr.even.gradeU td.sorting_3 { - background-color: #e2e2e2; -} - - -/* - * Row highlighting example - */ -.ex_highlight #example tbody tr.even:hover, #example tbody tr.even td.highlighted { - background-color: #ECFFB3; -} - -.ex_highlight #example tbody tr.odd:hover, #example tbody tr.odd td.highlighted { - background-color: #E6FF99; -} - -.ex_highlight_row #example tr.even:hover { - background-color: #ECFFB3; -} - -.ex_highlight_row #example tr.even:hover td.sorting_1 { - background-color: #DDFF75; -} - -.ex_highlight_row #example tr.even:hover td.sorting_2 { - background-color: #E7FF9E; -} - -.ex_highlight_row #example tr.even:hover td.sorting_3 { - background-color: #E2FF89; -} - -.ex_highlight_row #example tr.odd:hover { - background-color: #E6FF99; -} - -.ex_highlight_row #example tr.odd:hover td.sorting_1 { - background-color: #D6FF5C; -} - -.ex_highlight_row #example tr.odd:hover td.sorting_2 { - background-color: #E0FF84; -} - -.ex_highlight_row #example tr.odd:hover td.sorting_3 { - background-color: #DBFF70; -} - - -/* - * KeyTable - */ -table.KeyTable td { - border: 3px solid transparent; -} - -table.KeyTable td.focus { - border: 3px solid #3366FF; -} - -table.display tr.gradeA { - background-color: #eeffee; -} - -table.display tr.gradeC { - background-color: #ddddff; -} - -table.display tr.gradeX { - background-color: #ffdddd; -} - -table.display tr.gradeU { - background-color: #ddd; -} - -div.box { - height: 100px; - padding: 10px; - overflow: auto; - border: 1px solid #8080FF; - background-color: #E5E5FF; -} diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/ajax-loader-1.gif b/src/lib/biojs-1.0/src/main/resources/css/images/ajax-loader-1.gif deleted file mode 100755 index 597ddf0603..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/ajax-loader-1.gif and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/arrowAR.png b/src/lib/biojs-1.0/src/main/resources/css/images/arrowAR.png deleted file mode 100755 index 4c89cefb07..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/arrowAR.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/arrowDL.png b/src/lib/biojs-1.0/src/main/resources/css/images/arrowDL.png deleted file mode 100755 index 7bc1e1bdba..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/arrowDL.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/arrow_right_small.png b/src/lib/biojs-1.0/src/main/resources/css/images/arrow_right_small.png deleted file mode 100755 index a137531437..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/arrow_right_small.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/arrows.png b/src/lib/biojs-1.0/src/main/resources/css/images/arrows.png deleted file mode 100755 index 61a756c6d6..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/arrows.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/back_disabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/back_disabled.png deleted file mode 100755 index 881de7976f..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/back_disabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled.png deleted file mode 100755 index c608682b04..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled_hover.png b/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled_hover.png deleted file mode 100755 index d300f1064b..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/back_enabled_hover.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/circle.gif b/src/lib/biojs-1.0/src/main/resources/css/images/circle.gif deleted file mode 100755 index 599f7f13a6..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/circle.gif and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/draggable.png b/src/lib/biojs-1.0/src/main/resources/css/images/draggable.png deleted file mode 100755 index 1e1c662304..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/draggable.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/forward_disabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/forward_disabled.png deleted file mode 100755 index 6a6ded7de8..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/forward_disabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled.png deleted file mode 100755 index a4e6b5384b..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled_hover.png b/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled_hover.png deleted file mode 100755 index fc46c5ebf0..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/forward_enabled_hover.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/gradient.png b/src/lib/biojs-1.0/src/main/resources/css/images/gradient.png deleted file mode 100755 index 561cdd9c59..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/gradient.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/grid2.png b/src/lib/biojs-1.0/src/main/resources/css/images/grid2.png deleted file mode 100755 index ec7d3b51d1..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/grid2.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/line.gif b/src/lib/biojs-1.0/src/main/resources/css/images/line.gif deleted file mode 100755 index 9eb1983788..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/line.gif and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/off-exp.png b/src/lib/biojs-1.0/src/main/resources/css/images/off-exp.png deleted file mode 100755 index 4ebb871c0c..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/off-exp.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/open-exp.png b/src/lib/biojs-1.0/src/main/resources/css/images/open-exp.png deleted file mode 100755 index 05ab6459e2..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/open-exp.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/panel1.png b/src/lib/biojs-1.0/src/main/resources/css/images/panel1.png deleted file mode 100755 index 235b489468..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/panel1.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/pencil-exp.png b/src/lib/biojs-1.0/src/main/resources/css/images/pencil-exp.png deleted file mode 100755 index b2d3454c80..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/pencil-exp.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/rainbow.png b/src/lib/biojs-1.0/src/main/resources/css/images/rainbow.png deleted file mode 100755 index 8d6c71bf95..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/rainbow.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc.png b/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc.png deleted file mode 100755 index a88d7975fe..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc_disabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc_disabled.png deleted file mode 100755 index 4e144cf0b1..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/sort_asc_disabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/sort_both.png b/src/lib/biojs-1.0/src/main/resources/css/images/sort_both.png deleted file mode 100755 index 18670406bc..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/sort_both.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc.png b/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc.png deleted file mode 100755 index def071ed5a..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc_disabled.png b/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc_disabled.png deleted file mode 100755 index 7824973cc6..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/sort_desc_disabled.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/images/trigger.png b/src/lib/biojs-1.0/src/main/resources/css/images/trigger.png deleted file mode 100755 index 8c169fd605..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/images/trigger.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/jquery.miniColors.css b/src/lib/biojs-1.0/src/main/resources/css/jquery.miniColors.css deleted file mode 100755 index 0ba19761cc..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/jquery.miniColors.css +++ /dev/null @@ -1,65 +0,0 @@ -.miniColors-trigger { - height: 22px; - width: 22px; - background: url(images/trigger.png) center no-repeat; - vertical-align: middle; - margin: 0 .25em; - display: inline-block; - outline: none; -} - -.miniColors-selector { - position: absolute; - width: 175px; - height: 150px; - background: #FFF; - border: solid 1px #BBB; - -moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25); - -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25); - box-shadow: 0 0 6px rgba(0, 0, 0, .25); - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; - padding: 5px; - z-index: 999999; -} - -.miniColors-selector.black { - background: #000; - border-color: #000; -} - -.miniColors-colors { - position: absolute; - top: 5px; - left: 5px; - width: 150px; - height: 150px; - background: url(images/gradient.png) center no-repeat; - cursor: crosshair; -} - -.miniColors-hues { - position: absolute; - top: 5px; - left: 160px; - width: 20px; - height: 150px; - background: url(images/rainbow.png) center no-repeat; - cursor: crosshair; -} - -.miniColors-colorPicker { - position: absolute; - width: 11px; - height: 11px; - background: url(images/circle.gif) center no-repeat; -} - -.miniColors-huePicker { - position: absolute; - left: -3px; - width: 26px; - height: 3px; - background: url(images/line.gif) center no-repeat; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/jquery.qtip.css b/src/lib/biojs-1.0/src/main/resources/css/jquery.qtip.css deleted file mode 100755 index 9dc13b4b86..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/jquery.qtip.css +++ /dev/null @@ -1,567 +0,0 @@ -/*! -* qTip2 - Pretty powerful tooltips -* http://craigsworks.com/projects/qtip2/ -* -* Version: nightly -* Copyright 2009-2010 Craig Michael Thompson - http://craigsworks.com -* -* Dual licensed under MIT or GPLv2 licenses -* http://en.wikipedia.org/wiki/MIT_License -* http://en.wikipedia.org/wiki/GNU_General_Public_License -* -* Date: Tue Jul 3 15:45:43.0000000000 2012 -*/ - -/* Core qTip styles */ -.ui-tooltip, .qtip{ - position: absolute; - left: -28000px; - top: -28000px; - display: none; - - max-width: 280px; - min-width: 50px; - - font-size: 10.5px; - line-height: 12px; - - border-width: 1px; - border-style: solid; -} - - /* Fluid class for determining actual width in IE */ - .ui-tooltip-fluid{ - display: block; - visibility: hidden; - position: static !important; - float: left !important; - } - - .ui-tooltip-content{ - position: relative; - padding: 5px 9px; - overflow: hidden; - - text-align: left; - word-wrap: break-word; - overflow: hidden; - } - - .ui-tooltip-titlebar{ - position: relative; - min-height: 14px; - padding: 5px 35px 5px 10px; - overflow: hidden; - - border-width: 0 0 1px; - font-weight: bold; - } - - .ui-tooltip-titlebar + .ui-tooltip-content{ border-top-width: 0px !important; } - - /*! Default close button class */ - .ui-tooltip-titlebar .ui-state-default{ - position: absolute; - right: 4px; - top: 50%; - margin-top: -9px; - - cursor: pointer; - outline: medium none; - - border-width: 1px; - border-style: solid; - } - - * html .ui-tooltip-titlebar .ui-state-default{ top: 16px; } /* IE fix */ - - .ui-tooltip-titlebar .ui-icon, - .ui-tooltip-icon .ui-icon{ - display: block; - text-indent: -1000em; - } - - .ui-tooltip-icon, .ui-tooltip-icon .ui-icon{ - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - text-decoration: none; - } - - .ui-tooltip-icon .ui-icon{ - width: 18px; - height: 14px; - - text-align: center; - text-indent: 0; - font: normal bold 10px/13px Tahoma,sans-serif; - - color: inherit; - background: transparent none no-repeat -100em -100em; - } - - -/* Applied to 'focused' tooltips e.g. most recently displayed/interacted with */ -.ui-tooltip-focus{ - -} - -/* Applied on hover of tooltips i.e. added/removed on mouseenter/mouseleave respectively */ -.ui-tooltip-hover{ - -} - - -/*! Default tooltip style */ -.ui-tooltip-default{ - border-color: #F1D031; - background-color: #FFFFA3; - color: #555; -} - - .ui-tooltip-default .ui-tooltip-titlebar{ - background-color: #FFEF93; - } - - .ui-tooltip-default .ui-tooltip-icon{ - border-color: #CCC; - background: #F1F1F1; - color: #777; - } - - .ui-tooltip-default .ui-tooltip-titlebar .ui-state-hover{ - border-color: #AAA; - color: #111; - } - -/* Tips plugin */ -.ui-tooltip .ui-tooltip-tip{ - margin: 0 auto; - overflow: hidden; - z-index: 10; -} - - .ui-tooltip .ui-tooltip-tip, - .ui-tooltip .ui-tooltip-tip *{ - position: absolute; - - line-height: 0.1px !important; - font-size: 0.1px !important; - color: #123456; - - background: transparent; - border: 0px dashed transparent; - } - - .ui-tooltip .ui-tooltip-tip canvas{ top: 0; left: 0; } - - -/* Modal plugin */ -#qtip-overlay{ - position: fixed; - left: -10000em; - top: -10000em; -} - - /* Applied to modals with show.modal.blur set to true */ - #qtip-overlay.blurs{ cursor: pointer; } - - /* Change opacity of overlay here */ - #qtip-overlay div{ - position: absolute; - left: 0; top: 0; - width: 100%; height: 100%; - - background-color: black; - - opacity: 0.7; - filter:alpha(opacity=70); - -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)"; - } - -/*! Light tooltip style */ -.ui-tooltip-light{ - background-color: white; - border-color: #E2E2E2; - color: #454545; -} - - .ui-tooltip-light .ui-tooltip-titlebar{ - background-color: #f1f1f1; - } - - -/*! Dark tooltip style */ -.ui-tooltip-dark{ - background-color: #505050; - border-color: #303030; - color: #f3f3f3; -} - - .ui-tooltip-dark .ui-tooltip-titlebar{ - background-color: #404040; - } - - .ui-tooltip-dark .ui-tooltip-icon{ - border-color: #444; - } - - .ui-tooltip-dark .ui-tooltip-titlebar .ui-state-hover{ - border-color: #303030; - } - - -/*! Cream tooltip style */ -.ui-tooltip-cream{ - background-color: #FBF7AA; - border-color: #F9E98E; - color: #A27D35; -} - - .ui-tooltip-cream .ui-tooltip-titlebar{ - background-color: #F0DE7D; - } - - .ui-tooltip-cream .ui-state-default .ui-tooltip-icon{ - background-position: -82px 0; - } - - -/*! Red tooltip style */ -.ui-tooltip-red{ - background-color: #F78B83; - border-color: #D95252; - color: #912323; -} - - .ui-tooltip-red .ui-tooltip-titlebar{ - background-color: #F06D65; - } - - .ui-tooltip-red .ui-state-default .ui-tooltip-icon{ - background-position: -102px 0; - } - - .ui-tooltip-red .ui-tooltip-icon{ - border-color: #D95252; - } - - .ui-tooltip-red .ui-tooltip-titlebar .ui-state-hover{ - border-color: #D95252; - } - - -/*! Green tooltip style */ -.ui-tooltip-green{ - background-color: #CAED9E; - border-color: #90D93F; - color: #3F6219; -} - - .ui-tooltip-green .ui-tooltip-titlebar{ - background-color: #B0DE78; - } - - .ui-tooltip-green .ui-state-default .ui-tooltip-icon{ - background-position: -42px 0; - } - - -/*! Blue tooltip style */ -.ui-tooltip-blue{ - background-color: #E5F6FE; - border-color: #ADD9ED; - color: #5E99BD; -} - - .ui-tooltip-blue .ui-tooltip-titlebar{ - background-color: #D0E9F5; - } - - .ui-tooltip-blue .ui-state-default .ui-tooltip-icon{ - background-position: -2px 0; - } - -/*! Add shadows to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ -.ui-tooltip-shadow{ - -webkit-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); - -moz-box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); - box-shadow: 1px 1px 3px 1px rgba(0, 0, 0, 0.15); -} - -/*! Add rounded corners to your tooltips in: FF3+, Chrome 2+, Opera 10.6+, IE9+, Safari 2+ */ -.ui-tooltip-rounded, -.ui-tooltip-tipsy, -.ui-tooltip-bootstrap{ - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - border-radius: 5px; -} - -/*! Youtube tooltip style */ -.ui-tooltip-youtube{ - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; - - -webkit-box-shadow: 0 0 3px #333; - -moz-box-shadow: 0 0 3px #333; - box-shadow: 0 0 3px #333; - - color: white; - border-width: 0; - - background: #4A4A4A; - background-image: -moz-linear-gradient(top,#4A4A4A 0,black 100%); - background-image: -ms-linear-gradient(top,#4A4A4A 0,black 100%); - background-image: -o-linear-gradient(top,#4A4A4A 0,black 100%); - background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,black)); - background-image: -webkit-linear-gradient(top,#4A4A4A 0,black 100%); - background-image: linear-gradient(to bottom,#4A4A4A 0,black 100%); -} - - .ui-tooltip-youtube .ui-tooltip-titlebar{ - background-color: #4A4A4A; - background-color: rgba(0,0,0,0); - } - - .ui-tooltip-youtube .ui-tooltip-content{ - padding: .75em; - font: 12px arial,sans-serif; - - filter: progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000); - -ms-filter: "progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"; - } - - .ui-tooltip-youtube .ui-tooltip-icon{ - border-color: #222; - } - - .ui-tooltip-youtube .ui-tooltip-titlebar .ui-state-hover{ - border-color: #303030; - } - - -/* jQuery TOOLS Tooltip style */ -.ui-tooltip-jtools{ - background: #232323; - background: rgba(0, 0, 0, 0.7); - background-image: -moz-linear-gradient(top, #717171, #232323); - background-image: -webkit-gradient(linear, left top, left bottom, from(#717171), to(#232323)); - - border: 2px solid #ddd; - border: 2px solid rgba(241,241,241,1); - - -moz-border-radius: 2px; - -webkit-border-radius: 2px; - border-radius: 2px; - - -webkit-box-shadow: 0 0 12px #333; - -moz-box-shadow: 0 0 12px #333; - box-shadow: 0 0 12px #333; -} - - /* IE Specific */ - .ui-tooltip-jtools .ui-tooltip-titlebar{ - background-color: transparent; - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"; - } - .ui-tooltip-jtools .ui-tooltip-content{ - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"; - } - - .ui-tooltip-jtools .ui-tooltip-titlebar, - .ui-tooltip-jtools .ui-tooltip-content{ - background: transparent; - color: white; - border: 0 dashed transparent; - } - - .ui-tooltip-jtools .ui-tooltip-icon{ - border-color: #555; - } - - .ui-tooltip-jtools .ui-tooltip-titlebar .ui-state-hover{ - border-color: #333; - } - - -/* Cluetip style */ -.ui-tooltip-cluetip{ - -webkit-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); - -moz-box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); - box-shadow: 4px 4px 5px rgba(0, 0, 0, 0.4); - - background-color: #D9D9C2; - color: #111; - border: 0 dashed transparent; -} - - .ui-tooltip-cluetip .ui-tooltip-titlebar{ - background-color: #87876A; - color: white; - border: 0 dashed transparent; - } - - .ui-tooltip-cluetip .ui-tooltip-icon{ - border-color: #808064; - } - - .ui-tooltip-cluetip .ui-tooltip-titlebar .ui-state-hover{ - border-color: #696952; - color: #696952; - } - - -/* Tipsy style */ -.ui-tooltip-tipsy{ - background: black; - background: rgba(0, 0, 0, .87); - - color: white; - border: 0px solid transparent; - - font-size: 11px; - font-family: 'Lucida Grande', sans-serif; - font-weight: bold; - line-height: 16px; - text-shadow: 0 1px black; -} - - .ui-tooltip-tipsy .ui-tooltip-titlebar{ - padding: 6px 35px 0 10; - background-color: transparent; - } - - .ui-tooltip-tipsy .ui-tooltip-content{ - padding: 6px 10; - } - - .ui-tooltip-tipsy .ui-tooltip-icon{ - border-color: #222; - text-shadow: none; - } - - .ui-tooltip-tipsy .ui-tooltip-titlebar .ui-state-hover{ - border-color: #303030; - } - - -/* Tipped style */ -.ui-tooltip-tipped{ - border: 3px solid #959FA9; - - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-radius: 3px; - - background-color: #F9F9F9; - color: #454545; - - font-weight: normal; - font-family: serif; -} - - .ui-tooltip-tipped .ui-tooltip-titlebar{ - border-bottom-width: 0; - - color: white; - background: #3A79B8; - background-image: -moz-linear-gradient(top, #3A79B8, #2E629D); - background-image: -webkit-gradient(linear, left top, left bottom, from(#3A79B8), to(#2E629D)); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"; - } - - .ui-tooltip-tipped .ui-tooltip-icon{ - border: 2px solid #285589; - background: #285589; - } - - .ui-tooltip-tipped .ui-tooltip-icon .ui-icon{ - background-color: #FBFBFB; - color: #555; - } - - -/** - * Twitter Bootstrap style. - * - * Tested with IE 8, IE 9, Chrome 18, Firefox 9, Opera 11. - * Does not work with IE 7. - */ -.ui-tooltip-bootstrap{ - font-size: 13px; - line-height: 18px; - - color: #333333; - background-color: #ffffff; - - - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - - *border-right-width: 2px; - *border-bottom-width: 2px; - - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - - -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); - - -webkit-background-clip: padding-box; - -moz-background-clip: padding; - background-clip: padding-box; -} - - .ui-tooltip-bootstrap .ui-tooltip-titlebar{ - font-size: 18px; - line-height: 22px; - - border-bottom: 1px solid #ccc; - background-color: transparent; - } - - .ui-tooltip-bootstrap .ui-tooltip-titlebar .ui-state-default{ - right: 9px; top: 49%; - border-style: none; - } - - .ui-tooltip-bootstrap .ui-tooltip-icon{ - background: white; - } - - .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon{ - width: auto; - height: auto; - float: right; - font-size: 20px; - font-weight: bold; - line-height: 18px; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); - } - - .ui-tooltip-bootstrap .ui-tooltip-icon .ui-icon:hover{ - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.4; - filter: alpha(opacity=40); - } - - -/* IE9 fix - removes all filters */ -.ui-tooltip:not(.ie9haxors) div.ui-tooltip-content, -.ui-tooltip:not(.ie9haxors) div.ui-tooltip-titlebar{ - filter: none; - -ms-filter: none; -} - diff --git a/src/lib/biojs-1.0/src/main/resources/css/jquery/tipsy.css b/src/lib/biojs-1.0/src/main/resources/css/jquery/tipsy.css deleted file mode 100755 index 2302b0e459..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/jquery/tipsy.css +++ /dev/null @@ -1,26 +0,0 @@ -.tipsy { font-size: 12px; position: absolute; padding: 5px; z-index: 100000; } - .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; } - - /* Rounded corners */ - .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } - - /* Uncomment for shadow */ - /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ - - .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } - - /* Rules to colour arrows */ - .tipsy-arrow-n { border-bottom-color: #000; } - .tipsy-arrow-s { border-top-color: #000; } - .tipsy-arrow-e { border-left-color: #000; } - .tipsy-arrow-w { border-right-color: #000; } - - .tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} - .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } - .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } - .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } - \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/olstreeview/ae-common-1.0.131017.css b/src/lib/biojs-1.0/src/main/resources/css/olstreeview/ae-common-1.0.131017.css deleted file mode 100755 index 2f68a9fd21..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/olstreeview/ae-common-1.0.131017.css +++ /dev/null @@ -1,950 +0,0 @@ -/* - Mitigating ugliness of ebi-visual.css - */ - -* { - text-align: inherit; - font-weight: inherit -} - - -#content section img { - margin: 0 -} - -#content form { - font-size: 100% -} - -#content form input -, #content form textarea { - font-family: inherit -} - -#content table { - width: auto; - margin: 0; - padding: 0; - border: 0 none -} - -#content th, #content td { - padding: 0; - border: 0 none; - border-collapse: collapse; - vertical-align: middle -} - -.container_24 { - min-width: 984px -} - -.logo-title { - display: inline-block -} - -span.searchterm { - padding: 0.1em 0.4em 0.1em 0.2em -} - -.icon-awesome:before { - font-family: 'FontAwesome'; - font-size: 100%; - color: #bbb; - content: attr(data-icon); - margin: 0 0.3em 0 0 -} - -ul#secondary-nav li.active a { - font-weight: normal -} - -ul#secondary-nav li.active > a { - font-weight: bold !important -} - -/* - Palette color codes - - Palette URL: http://colorschemedesigner.com/#3B61ThNE8w0w0 - */ - -.primary-1 { background-color: #5E8CC0 } -.primary-2 { background-color: #597390 } -.primary-3 { background-color: #1E4B7D } -.primary-4 { background-color: #8AB2DF } -.primary-5 { background-color: #A1BEDF } - -.secondary-a-1 { background-color: #7068C8 } -.secondary-a-2 { background-color: #656096 } -.secondary-a-3 { background-color: #2A2282 } -.secondary-a-4 { background-color: #9991E3 } -.secondary-a-5 { background-color: #ADA7E3 } - -.secondary-b-1 { background-color: #56C1A1 } -.secondary-b-2 { background-color: #54917F } -.secondary-b-3 { background-color: #1C7E60 } -.secondary-b-4 { background-color: #83E0C4 } -.secondary-b-5 { background-color: #9CE0CB } - -.complement-1 { background-color: #FFC771 } -.complement-2 { background-color: #BFA070 } -.complement-3 { background-color: #A67325 } -.complement-4 { background-color: #FFD595 } -.complement-5 { background-color: #FFE0B1 } - -/* EBI template colour substitutions */ - -/* These style rules will over-ride the core EBI styles and apply - your custom colour palette in a consistent manner */ - -/* Links */ -a:link, -a:visited { border-bottom-color: #5E8CC0; } - -a:hover, -a:focus, -a:active { - color: #5E8CC0; - border-bottom: 1px solid #5E8CC0; -} - -a.special:hover, -a.special:focus, -a.special:active { - color: #5E8CC0; - border-bottom: 3px double #5E8CC0; -} - - -a:link { color: #2A2282; } - -a:hover, -a:focus, -a:active { color: #1C7E60; } - -a.special { background-color: #9CE0CB; } - - -/* Headings */ -h1, h2, h3, h4, h5, h6 { color: #222222; } - -h1 { color: #5E8CC0; } - -h2 { color: #1E4B7D; } - -h3 { color: #BFA070; } - -h1 a:link, -h2 a:link, -h3 a:link, -h4 a:link, -h5 a:link, -h6 a:link, -h1 a:visited, -h2 a:visited, -h3 a:visited, -h4 a:visited, -h5 a:visited, -h6 a:visited { - border-bottom-color: #5E8CC0; -} - - -/* Table heading cells */ -th { background-color: #EEEEEE; } - - -/* Form submission button */ -form input.submit { - /* colours */ - color: #fff; - text-shadow: #1E4B7D 1px 1px; - border-top: 1px solid #A1BEDF; - border-left: 1px solid #A1BEDF; - border-right: 1px solid #1E4B7D; - border-bottom: 1px solid #1E4B7D; - - background-image: -moz-linear-gradient(top, #5E8CC0, #597390); - background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #ccc),color-stop(1, #597390)); - background-image: -webkit-linear-gradient(#5E8CC0, #597390); - background-image: linear-gradient(top, #5E8CC0, #597390); - filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#5E8CC0', EndColorStr='#597390'); -} - -/* Define the basic colour your local masthead */ -div#local-masthead { background-color: #A1BEDF; } - -/* Colour the faux-underline for local menu items */ -div#local-masthead ul li a:hover, -div#local-masthead ul li a:focus, -div#local-masthead ul li a:active { - border-bottom: 3px solid #5E8CC0; -} - -/* --------------------------------- */ - -::-webkit-input-placeholder { - font-style: italic; - color: #999 -} -:-moz-placeholder { - font-style: italic; - color: #999 -} -::-moz-placeholder { - font-style: italic; - color: #999 -} -:-ms-input-placeholder { - font-style: italic; - color: #999 -} - -/* --------------------------------- */ - -#ae-login * -, #ae-feedback * { - box-sizing: border-box; - -moz-box-sizing: border-box -} - -#ae-login -, #ae-feedback { - position: absolute; - top: 2px; - right: 5px; - background-color: #EEE; - color: #000; - border-radius: 5px; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - padding: 0; - z-index: 40001 -} - -#ae-login { - left: 55% -} - -#ae-feedback { - left: 50%; - background-color: #FFE0B1 -} - -#ae-login > h3 -, #ae-feedback > h3 { - font-size: 123.1%; - color: black; - background-color: rgba(0, 0, 0, 0.1); - margin: 0; - padding: 7px 9px 2px; - border-top-left-radius: 5px; - -webkit-border-top-left-radius: 5px; - -moz-border-radius-topleft: 5px; - border-top-right-radius: 5px; - -webkit-border-top-right-radius: 5px; - -moz-border-radius-topright: 5px -} - -#ae-login > h3 a -, #ae-feedback > h3 a { - float: right; - font-size: 87%; - border-bottom-style: none -} - -#ae-login .icon-functional:hover:before -, #ae-feedback .icon-functional:hover:before { - color: #444 -} - -#ae-login .icon-functional:before -, #ae-feedback .icon-functional:before { - margin: 0 -} - -#ae-login form -, #ae-feedback form { - position: relative; - margin: 0; - padding: 20px 20px 10px; - width: 100%; - overflow: auto -} - -#ae-login form { - padding: 20px 20px 10px -} - -#ae-login form -, #ae-login form * -, #ae-feedback form -, #ae-feedback form * { - font-size: 100% -} - -#ae-login-form fieldset -, #ae-forgot-form fieldset -, #ae-feedback fieldset { - padding: 0; - margin: 0; - border: 0 none; - width: 100% -} - -#ae-login-form fieldset { - float: left; - width: 50% -} - -#ae-login input[type = 'checkbox'] { - vertical-align: baseline; - margin: 0 3px -} - -#ae-login input[type = 'checkbox'] + label { - font-size: 93%; - vertical-align: middle -} - -#ae-login fieldset -, #ae-feedback fieldset -, #ae-feedback span { - background-color: transparent; - color: inherit -} - -#ae-login-form fieldset:first-child { - padding: 0 10px 0 0 -} - -#ae-feedback fieldset:first-child -, #ae-forgot-form fieldset:first-child { - padding: 0; - margin-bottom: 10px -} - -#ae-forgot-form div { - margin-top: 10px -} - -#ae-login fieldset label -, #ae-feedback fieldset label { - width: 100%; - margin: 0; - padding: 0; - font-size: 100%; - display: inline-block -} - -#ae-login fieldset label a.forgot { - font-style: italic -} - -#ae-login fieldset input -, #ae-feedback fieldset input { - width: 100%; - margin: 0 0 5px 0; - padding: 0; - font-size: 100% -} - -#ae-feedback fieldset textarea { - width: 100%; - margin: 0 0 5px 0; - padding: 0; - font-size: 100%; - height: 10em -} - -#ae-login input[type='submit'] -, #ae-feedback input[type='submit'] { - float: right -} - -#ae-login input[type='submit']:last-child { - position: absolute; - bottom: 10px; - right: 20px -} - -#ae-login-remember-option { - float: left; - margin: 8px 0 0 -} - -#ae-login-forgot { - clear: both; - text-align: center -} - -#ae-login .ae-login-status { - clear: both; - padding: 5px 0; - text-align: center -} - -#ae-accession-field { - width: 150px !important -} - -/* --------------------------------- */ - -#ae-content { -} - -#ae-content h4 { - border-bottom: 1px solid #CCC; - margin-bottom: 10px; -} - -#ae-content span.icon::before { - color: inherit !important; - margin: 0; -} - -/* --------------------------------- */ - -#ae-infotext { - font-size: 108%; - text-align: center; -} - -.text-hit { - background-color: #FFFF00; -} - -.text-syn { - background-color: #CCFFAA; -} - -.text-efo { - background-color: #FFCCAA; -} - -/* home page stuff */ - -#ae-news { - background-image: url(../images/bg-news.gif); - padding: 10px 0; - margin: 10px 0 -} - -p.intro { - font-size: 108%; -} - -p.justify { - text-align: justify; -} - -/* browse page stuff */ - -#ae-filters * -, #ae-query * { - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; -} - -#ae-filters form -, #ae-query form { - margin: 0; - padding: 0 -} - -#ae-filters form fieldset { - padding: 10px; - margin: 0 0 9px; - border: 0 none; - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - background-color: #E3E1F2 !important -} - -#ae-filters legend { - padding: 0.25em 0.5em; - background-color: #C7C4D7; - border: 0 none; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px -} - -#ae-filters label, -#ae-filters input[type='text'], -#ae-filters select { - margin: 3px 0 -} - -#ae-filters label, -#ae-query label { - font-size: 100%; - display: inline-block -} - -#ae-filters input[type = 'checkbox'] -, #ae-query input[type = 'checkbox'] { - vertical-align: baseline; - margin: 0 3px -} - -#ae-filters input[type = 'checkbox'] + label -, #ae-query input[type = 'checkbox'] + label { - font-size: 93%; - vertical-align: middle -} - -/* -#ae-filters select { - font-family: Verdana,sans-serif; - font-size: 12px; -} -*/ - -#ae-filters .option -, #ae-query .option { - float: left; - margin-right: 10px; - font-size: 100% -} - -#ae-filters input[type='submit'] -, #ae-query input[type='submit'] { - float: right -} - -#ae-query { - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - background-color: #E3E1F2; - padding: 10px; - margin: 0 9px 9px -} - -#ae-query fieldset { - padding: 0; - margin: 0; - border: 0 none; - background-color: inherit; -} - -#ae-query input[type='text'] { - width: 100%; - font-size: 100%; - margin: 3px 0 8px 0; -} - -/* browse table stuff */ - -#ae-browse { - margin: 0 9px; -} - -#ae-browse table { - table-layout: fixed; - width: 100%; - padding: 0; - margin: 0; - border: 0 none; -} - -#ae-browse th { - font-size: 108%; - font-weight: normal; - vertical-align: bottom; - white-space: nowrap; - background-color: #EEEEEE; - border-bottom: 2px solid #5E8CC0; -} - -#ae-browse table.floating-header th.col_pager { - /* border-top: 1px solid #CCCCCC; */ -} - -#ae-browse th.sortable a:link, -#ae-browse th.sortable a:visited, -#ae-browse th { - color: #666 -} - -#ae-browse th.sortable a:hover, -#ae-browse th.sortable a:focus, -#ae-browse th.sortable a:active { - color: #1C7E60; -} - -#ae-browse th.sortable i { - margin: 0 0 0 2px -} - -#ae-browse tbody tr:nth-child(odd) { - background-color: #E8F1FC -} - -#ae-browse tbody tr:nth-child(even) { - background-color: #FFF -} - -#ae-browse td { - vertical-align: bottom; - font-size: 93%; -} - -#ae-browse th -, #ae-browse td { - padding: 3px 5px -} - -#ae-browse .experiments td { - vertical-align: top; -} - -#ae-browse td div { - white-space: nowrap; - width: 100%; - overflow: hidden; - text-overflow: ellipsis; - -moz-text-overflow: ellipsis; - -o-text-overflow: ellipsis; - -webkit-text-overflow: ellipsis; -} - -#ae-browse .experiments td div { - white-space: normal; -} - -#ae-browse td.col_accession span.icon { - float: right; -} - -#ae-browse .floating-header { - position: fixed; - top: 0; - box-shadow: 0 3px 5px #CCC; - -moz-box-shadow: 0 3px 5px #CCC; - -webkit-box-shadow: 0 3px 5px #CCC; - visibility: hidden; -} - -#ae-browse .col_pager { - font-size: 100%; - padding: 3px 5px; - border-bottom: 2px solid #FFF; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - -moz-border-radius-topleft: 5px; - -moz-border-radius-topright: 5px; - -webkit-border-top-left-radius: 5px; - -webkit-border-top-right-radius: 5px; -} - -#ae-browse .ae-stats { - position: relative; - text-align: center; - pointer-events: none; - margin: 0 -} - -#ae-browse .ae-pager { - float: left; - text-align: left -} - -#ae-browse .ae-page-size { - float: right; - text-align: right -} - -#ae-browse .ae-pager, -#ae-browse .ae-page-size { - width: 33% -} - -#ae-browse .col_pager div { - color: #A67325; -} - -#ae-browse .col_pager a { - padding: 2px 3px 0 3px; - margin: 0 2px; - color: #A67325; -} - -#ae-browse .col_pager span { - padding: 2px 3px; - margin: 0 2px; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; -} - -#ae-browse .col_pager a:link, -#ae-browse .col_pager a:visited { -} - -#ae-browse .col_pager a:hover, -#ae-browse .col_pager a:focus, -#ae-browse .col_pager a:active { - padding: 2px 3px; - margin: 0 2px; - border-radius: 3px; - -moz-border-radius: 3px; - -webkit-border-radius: 3px; - border-bottom: 0 none; - background-color: #A67325; - color: #FFF; -} - -#ae-browse .col_pager span { - background-color: #68798D; - color: #FFF; -} - -#ae-browse .col_footer { - font-size: 93%; - text-align: center; - padding: 0 5px 3px 5px; - border-top: 2px solid #FFF; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - -moz-border-radius-bottomleft: 5px; - -moz-border-radius-bottomleft: 5px; - -webkit-border-bottom-left-radius: 5px; - -webkit-border-bottom-right-radius: 5px; - background-color: #EEE; -} - -#ae-browse .col_footer a { - padding: 0; - margin: 0 0 0 20px; -} - -#ae-browse .col_footer a:first-child { - margin: 0; -} - -/* detailed entity */ - -#ae-detail { - margin: 0 9px; -} - -#ae-detail * { - font-style: inherit; -} - -#ae-detail table { - width: 100%; - table-layout: fixed; -} - -#ae-detail tr:nth-child(odd) { - background-color: #E8F1FC -} - -#ae-detail tr:nth-child(even) { - background-color: #FFF -} - -#ae-detail tr table -, #ae-detail tr tr:nth-child(n) { - background-color: transparent -} - -#ae-detail th -, #ae-detail td { - font-size: 100% -} - -#ae-detail td { - vertical-align: top -} - -#ae-detail td.name { - white-space: nowrap; - font-size: 108%; - color: #666; - background-image: url(../images/bg-ltgray.gif); - text-align: right; - vertical-align: top; - padding: 5px 10px; - width: 150px; -} - -#ae-detail td.value { - text-align: justify; - vertical-align: top; - padding: 7px 10px; -} - -#ae-detail td.value > div { - padding: 0 0 0.5em 0; -} - -#ae-detail td.value > div:last-child { - padding-bottom: 0; -} - -#ae-detail td em { - font-style: italic -} - -#ae-detail td th { - font-size: 100%; - font-weight: normal; - color: #666; - background-color: transparent -} - -#ae-detail td th.name -, #ae-detail td td.name { - font-size: 100%; - text-align: left; - background-image: none; - padding: 0 10px 0 0; - width: 30% -} - -#ae-detail td td.name { - color: #000; -} - -#ae-detail td th.value -, #ae-detail td td.value { - text-align: left; - padding: 0; - width: 70% -} - -#ae-detail td i { - padding: 0 3px -} - -#ae-detail a img { - vertical-align: top -} - -/* help pages stuff */ - -#ae-help table { - width: 99%; - padding: 0 9px; - margin: 9px auto; - border: 5px solid #EEEEEE; -} - -#ae-help th, #ae-help td { - padding: 1px 5px 5px 5px; - border: 1px solid #EEEEEE; - border-collapse: collapse; - vertical-align: top; -} - -#ae-help p { - overflow: auto; - clear: both -} - -#ae-help a > img { - float: left -} - -/* autocomplete-related classes */ -.ac_results { - padding: 0; - background-color: #FFF; - overflow: hidden; - z-index: 99999; - font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; - font-size: 11px; -} - -.ac_results ul { - width: 100%; - list-style-position: outside; - list-style: none; - padding: 0; - margin: 0; -} - -.ac_results li { - margin: 0; - padding: 0 3px; - cursor: default; - display: block; - height: 16px; - overflow: hidden; - position: relative; -} - -.ac_tree_level -, .ac_tree_control { - float: left; - width: 16px; - height: 16px; -} - -.ac_tree_control div { - width: 9px; - height: 9px; - margin: 3px 3px 3px 3px; - overflow: hidden; -} - -.ac_tree_collapsed .ac_tree_control div { - background: url(../images/_old_/tminmax.gif) 0 0 no-repeat; -} - -.ac_tree_expanded .ac_tree_control div { - background: url(../images/_old_/tminmax.gif) 0 -9px no-repeat; -} - -.ac_loading { - background: #FFF url('../images/busy.gif') right center no-repeat; -} - -.ac_over { - background-color: #5E8CC0; - color: #FFF; -} - -.ac_over .ac_efo -, .ac_over .ac_field { - color: #FFF; -} - -.ac_outer { - background-color: #FFF; - color: #000; - cursor: default; - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -moz-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); -} - -.ac_outer > div { - padding: 1px; -} - -.ac_field -, .ac_efo { - position: absolute; - top: 0; - right: 2px; - color: #5E8CC0; -} - -.ac_field { - font-style: italic; -} - -.ac_efo { - font-weight: bold; -} \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png deleted file mode 100755 index 5b5dab2ab7..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png deleted file mode 100755 index ac8b229af9..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png deleted file mode 100755 index ad3d6346e0..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png deleted file mode 100755 index 42ccba269b..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png deleted file mode 100755 index 5a46b47cb1..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png deleted file mode 100755 index 86c2baa655..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png deleted file mode 100755 index 4443fdc1a1..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png deleted file mode 100755 index 7c9fa6c6ed..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_222222_256x240.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_222222_256x240.png deleted file mode 100755 index b273ff111d..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_222222_256x240.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_2e83ff_256x240.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_2e83ff_256x240.png deleted file mode 100755 index 09d1cdc856..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_2e83ff_256x240.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_454545_256x240.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_454545_256x240.png deleted file mode 100755 index 59bd45b907..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_454545_256x240.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_888888_256x240.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_888888_256x240.png deleted file mode 100755 index 6d02426c11..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_888888_256x240.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_cd0a0a_256x240.png b/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_cd0a0a_256x240.png deleted file mode 100755 index 2ab019b73e..0000000000 Binary files a/src/lib/biojs-1.0/src/main/resources/css/smoothness/images/ui-icons_cd0a0a_256x240.png and /dev/null differ diff --git a/src/lib/biojs-1.0/src/main/resources/css/smoothness/jquery-ui-1.8.18.custom.css b/src/lib/biojs-1.0/src/main/resources/css/smoothness/jquery-ui-1.8.18.custom.css deleted file mode 100755 index 4cfb50a4a3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/css/smoothness/jquery-ui-1.8.18.custom.css +++ /dev/null @@ -1,565 +0,0 @@ -/* - * jQuery UI CSS Framework 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - */ - -/* Layout helpers -----------------------------------*/ -.ui-helper-hidden { display: none; } -.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } -.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } -.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } -.ui-helper-clearfix:after { clear: both; } -.ui-helper-clearfix { zoom: 1; } -.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } - - -/* Interaction Cues -----------------------------------*/ -.ui-state-disabled { cursor: default !important; } - - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } - - -/* Misc visuals -----------------------------------*/ - -/* Overlays */ -.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } - - -/* - * jQuery UI CSS Framework 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Theming/API - * - * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana,Arial,sans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px - */ - - -/* Component containers -----------------------------------*/ -.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 1.1em; } -.ui-widget .ui-widget { font-size: 1em; } -.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } -.ui-widget-content { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_flat_75_ffffff_40x100.png) 50% 50% repeat-x; color: #222222; } -.ui-widget-content a { color: #222222; } -.ui-widget-header { border: 1px solid #aaaaaa; background: #cccccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x; color: #222222; font-weight: bold; } -.ui-widget-header a { color: #222222; } - -/* Interaction states -----------------------------------*/ -.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } -.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } -.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-hover a, .ui-state-hover a:hover { color: #212121; text-decoration: none; } -.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } -.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } -.ui-widget :active { outline: none; } - -/* Interaction Cues -----------------------------------*/ -.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } -.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } -.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } -.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } -.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } -.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } -.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } -.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } - -/* Icons -----------------------------------*/ - -/* states and images */ -.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } -.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } -.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } -.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } -.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } - -/* positioning */ -.ui-icon-carat-1-n { background-position: 0 0; } -.ui-icon-carat-1-ne { background-position: -16px 0; } -.ui-icon-carat-1-e { background-position: -32px 0; } -.ui-icon-carat-1-se { background-position: -48px 0; } -.ui-icon-carat-1-s { background-position: -64px 0; } -.ui-icon-carat-1-sw { background-position: -80px 0; } -.ui-icon-carat-1-w { background-position: -96px 0; } -.ui-icon-carat-1-nw { background-position: -112px 0; } -.ui-icon-carat-2-n-s { background-position: -128px 0; } -.ui-icon-carat-2-e-w { background-position: -144px 0; } -.ui-icon-triangle-1-n { background-position: 0 -16px; } -.ui-icon-triangle-1-ne { background-position: -16px -16px; } -.ui-icon-triangle-1-e { background-position: -32px -16px; } -.ui-icon-triangle-1-se { background-position: -48px -16px; } -.ui-icon-triangle-1-s { background-position: -64px -16px; } -.ui-icon-triangle-1-sw { background-position: -80px -16px; } -.ui-icon-triangle-1-w { background-position: -96px -16px; } -.ui-icon-triangle-1-nw { background-position: -112px -16px; } -.ui-icon-triangle-2-n-s { background-position: -128px -16px; } -.ui-icon-triangle-2-e-w { background-position: -144px -16px; } -.ui-icon-arrow-1-n { background-position: 0 -32px; } -.ui-icon-arrow-1-ne { background-position: -16px -32px; } -.ui-icon-arrow-1-e { background-position: -32px -32px; } -.ui-icon-arrow-1-se { background-position: -48px -32px; } -.ui-icon-arrow-1-s { background-position: -64px -32px; } -.ui-icon-arrow-1-sw { background-position: -80px -32px; } -.ui-icon-arrow-1-w { background-position: -96px -32px; } -.ui-icon-arrow-1-nw { background-position: -112px -32px; } -.ui-icon-arrow-2-n-s { background-position: -128px -32px; } -.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } -.ui-icon-arrow-2-e-w { background-position: -160px -32px; } -.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } -.ui-icon-arrowstop-1-n { background-position: -192px -32px; } -.ui-icon-arrowstop-1-e { background-position: -208px -32px; } -.ui-icon-arrowstop-1-s { background-position: -224px -32px; } -.ui-icon-arrowstop-1-w { background-position: -240px -32px; } -.ui-icon-arrowthick-1-n { background-position: 0 -48px; } -.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } -.ui-icon-arrowthick-1-e { background-position: -32px -48px; } -.ui-icon-arrowthick-1-se { background-position: -48px -48px; } -.ui-icon-arrowthick-1-s { background-position: -64px -48px; } -.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } -.ui-icon-arrowthick-1-w { background-position: -96px -48px; } -.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } -.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } -.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } -.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } -.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } -.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } -.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } -.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } -.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } -.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } -.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } -.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } -.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } -.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } -.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } -.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } -.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } -.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } -.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } -.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } -.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } -.ui-icon-arrow-4 { background-position: 0 -80px; } -.ui-icon-arrow-4-diag { background-position: -16px -80px; } -.ui-icon-extlink { background-position: -32px -80px; } -.ui-icon-newwin { background-position: -48px -80px; } -.ui-icon-refresh { background-position: -64px -80px; } -.ui-icon-shuffle { background-position: -80px -80px; } -.ui-icon-transfer-e-w { background-position: -96px -80px; } -.ui-icon-transferthick-e-w { background-position: -112px -80px; } -.ui-icon-folder-collapsed { background-position: 0 -96px; } -.ui-icon-folder-open { background-position: -16px -96px; } -.ui-icon-document { background-position: -32px -96px; } -.ui-icon-document-b { background-position: -48px -96px; } -.ui-icon-note { background-position: -64px -96px; } -.ui-icon-mail-closed { background-position: -80px -96px; } -.ui-icon-mail-open { background-position: -96px -96px; } -.ui-icon-suitcase { background-position: -112px -96px; } -.ui-icon-comment { background-position: -128px -96px; } -.ui-icon-person { background-position: -144px -96px; } -.ui-icon-print { background-position: -160px -96px; } -.ui-icon-trash { background-position: -176px -96px; } -.ui-icon-locked { background-position: -192px -96px; } -.ui-icon-unlocked { background-position: -208px -96px; } -.ui-icon-bookmark { background-position: -224px -96px; } -.ui-icon-tag { background-position: -240px -96px; } -.ui-icon-home { background-position: 0 -112px; } -.ui-icon-flag { background-position: -16px -112px; } -.ui-icon-calendar { background-position: -32px -112px; } -.ui-icon-cart { background-position: -48px -112px; } -.ui-icon-pencil { background-position: -64px -112px; } -.ui-icon-clock { background-position: -80px -112px; } -.ui-icon-disk { background-position: -96px -112px; } -.ui-icon-calculator { background-position: -112px -112px; } -.ui-icon-zoomin { background-position: -128px -112px; } -.ui-icon-zoomout { background-position: -144px -112px; } -.ui-icon-search { background-position: -160px -112px; } -.ui-icon-wrench { background-position: -176px -112px; } -.ui-icon-gear { background-position: -192px -112px; } -.ui-icon-heart { background-position: -208px -112px; } -.ui-icon-star { background-position: -224px -112px; } -.ui-icon-link { background-position: -240px -112px; } -.ui-icon-cancel { background-position: 0 -128px; } -.ui-icon-plus { background-position: -16px -128px; } -.ui-icon-plusthick { background-position: -32px -128px; } -.ui-icon-minus { background-position: -48px -128px; } -.ui-icon-minusthick { background-position: -64px -128px; } -.ui-icon-close { background-position: -80px -128px; } -.ui-icon-closethick { background-position: -96px -128px; } -.ui-icon-key { background-position: -112px -128px; } -.ui-icon-lightbulb { background-position: -128px -128px; } -.ui-icon-scissors { background-position: -144px -128px; } -.ui-icon-clipboard { background-position: -160px -128px; } -.ui-icon-copy { background-position: -176px -128px; } -.ui-icon-contact { background-position: -192px -128px; } -.ui-icon-image { background-position: -208px -128px; } -.ui-icon-video { background-position: -224px -128px; } -.ui-icon-script { background-position: -240px -128px; } -.ui-icon-alert { background-position: 0 -144px; } -.ui-icon-info { background-position: -16px -144px; } -.ui-icon-notice { background-position: -32px -144px; } -.ui-icon-help { background-position: -48px -144px; } -.ui-icon-check { background-position: -64px -144px; } -.ui-icon-bullet { background-position: -80px -144px; } -.ui-icon-radio-off { background-position: -96px -144px; } -.ui-icon-radio-on { background-position: -112px -144px; } -.ui-icon-pin-w { background-position: -128px -144px; } -.ui-icon-pin-s { background-position: -144px -144px; } -.ui-icon-play { background-position: 0 -160px; } -.ui-icon-pause { background-position: -16px -160px; } -.ui-icon-seek-next { background-position: -32px -160px; } -.ui-icon-seek-prev { background-position: -48px -160px; } -.ui-icon-seek-end { background-position: -64px -160px; } -.ui-icon-seek-start { background-position: -80px -160px; } -/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ -.ui-icon-seek-first { background-position: -80px -160px; } -.ui-icon-stop { background-position: -96px -160px; } -.ui-icon-eject { background-position: -112px -160px; } -.ui-icon-volume-off { background-position: -128px -160px; } -.ui-icon-volume-on { background-position: -144px -160px; } -.ui-icon-power { background-position: 0 -176px; } -.ui-icon-signal-diag { background-position: -16px -176px; } -.ui-icon-signal { background-position: -32px -176px; } -.ui-icon-battery-0 { background-position: -48px -176px; } -.ui-icon-battery-1 { background-position: -64px -176px; } -.ui-icon-battery-2 { background-position: -80px -176px; } -.ui-icon-battery-3 { background-position: -96px -176px; } -.ui-icon-circle-plus { background-position: 0 -192px; } -.ui-icon-circle-minus { background-position: -16px -192px; } -.ui-icon-circle-close { background-position: -32px -192px; } -.ui-icon-circle-triangle-e { background-position: -48px -192px; } -.ui-icon-circle-triangle-s { background-position: -64px -192px; } -.ui-icon-circle-triangle-w { background-position: -80px -192px; } -.ui-icon-circle-triangle-n { background-position: -96px -192px; } -.ui-icon-circle-arrow-e { background-position: -112px -192px; } -.ui-icon-circle-arrow-s { background-position: -128px -192px; } -.ui-icon-circle-arrow-w { background-position: -144px -192px; } -.ui-icon-circle-arrow-n { background-position: -160px -192px; } -.ui-icon-circle-zoomin { background-position: -176px -192px; } -.ui-icon-circle-zoomout { background-position: -192px -192px; } -.ui-icon-circle-check { background-position: -208px -192px; } -.ui-icon-circlesmall-plus { background-position: 0 -208px; } -.ui-icon-circlesmall-minus { background-position: -16px -208px; } -.ui-icon-circlesmall-close { background-position: -32px -208px; } -.ui-icon-squaresmall-plus { background-position: -48px -208px; } -.ui-icon-squaresmall-minus { background-position: -64px -208px; } -.ui-icon-squaresmall-close { background-position: -80px -208px; } -.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } -.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } -.ui-icon-grip-solid-vertical { background-position: -32px -224px; } -.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } -.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } -.ui-icon-grip-diagonal-se { background-position: -80px -224px; } - - -/* Misc visuals -----------------------------------*/ - -/* Corner radius */ -.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } -.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } -.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } - -/* Overlays */ -.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } -.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* - * jQuery UI Resizable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Resizable#theming - */ -.ui-resizable { position: relative;} -.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block; } -.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } -.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } -.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } -.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } -.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } -.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } -.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } -.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } -.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* - * jQuery UI Selectable 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Selectable#theming - */ -.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } -/* - * jQuery UI Accordion 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Accordion#theming - */ -/* IE/Win - Fix animation bug - #4615 */ -.ui-accordion { width: 100%; } -.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; } -.ui-accordion .ui-accordion-li-fix { display: inline; } -.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; } -.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; } -.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; } -.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } -.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; } -.ui-accordion .ui-accordion-content-active { display: block; } -/* - * jQuery UI Autocomplete 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Autocomplete#theming - */ -.ui-autocomplete { position: absolute; cursor: default; } - -/* workarounds */ -* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ - -/* - * jQuery UI Menu 1.8.18 - * - * Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Menu#theming - */ -.ui-menu { - list-style:none; - padding: 2px; - margin: 0; - display:block; - float: left; -} -.ui-menu .ui-menu { - margin-top: -3px; -} -.ui-menu .ui-menu-item { - margin:0; - padding: 0; - zoom: 1; - float: left; - clear: left; - width: 100%; -} -.ui-menu .ui-menu-item a { - text-decoration:none; - display:block; - padding:.2em .4em; - line-height:1.5; - zoom:1; -} -.ui-menu .ui-menu-item a.ui-state-hover, -.ui-menu .ui-menu-item a.ui-state-active { - font-weight: normal; - margin: -1px; -} -/* - * jQuery UI Button 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Button#theming - */ -.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: hidden; *overflow: visible; } /* the overflow property removes extra width in IE */ -.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ -button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ -.ui-button-icons-only { width: 3.4em; } -button.ui-button-icons-only { width: 3.7em; } - -/*button text element */ -.ui-button .ui-button-text { display: block; line-height: 1.4; } -.ui-button-text-only .ui-button-text { padding: .4em 1em; } -.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } -.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } -.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } -.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } -/* no icon support for input elements, provide padding by default */ -input.ui-button { padding: .4em 1em; } - -/*button icon element(s) */ -.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } -.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } -.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } -.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } -.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } - -/*button sets*/ -.ui-buttonset { margin-right: 7px; } -.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } - -/* workarounds */ -button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ -/* - * jQuery UI Dialog 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Dialog#theming - */ -.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } -.ui-dialog .ui-dialog-titlebar { padding: .4em 1em; position: relative; } -.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } -.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } -.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } -.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } -.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } -.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } -.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } -.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } -.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } -.ui-draggable .ui-dialog-titlebar { cursor: move; } -/* - * jQuery UI Slider 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Slider#theming - */ -.ui-slider { position: relative; text-align: left; } -.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; } -.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } - -.ui-slider-horizontal { height: .8em; } -.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; } -.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } -.ui-slider-horizontal .ui-slider-range-min { left: 0; } -.ui-slider-horizontal .ui-slider-range-max { right: 0; } - -.ui-slider-vertical { width: .8em; height: 100px; } -.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } -.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } -.ui-slider-vertical .ui-slider-range-min { bottom: 0; } -.ui-slider-vertical .ui-slider-range-max { top: 0; }/* - * jQuery UI Tabs 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Tabs#theming - */ -.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ -.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } -.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } -.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } -.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } -.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ -.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } -.ui-tabs .ui-tabs-hide { display: none !important; } -/* - * jQuery UI Datepicker 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Datepicker#theming - */ -.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } -.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } -.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } -.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } -.ui-datepicker .ui-datepicker-prev { left:2px; } -.ui-datepicker .ui-datepicker-next { right:2px; } -.ui-datepicker .ui-datepicker-prev-hover { left:1px; } -.ui-datepicker .ui-datepicker-next-hover { right:1px; } -.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } -.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } -.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } -.ui-datepicker select.ui-datepicker-month-year {width: 100%;} -.ui-datepicker select.ui-datepicker-month, -.ui-datepicker select.ui-datepicker-year { width: 49%;} -.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } -.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } -.ui-datepicker td { border: 0; padding: 1px; } -.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } -.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } -.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } -.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } - -/* with multiple calendars */ -.ui-datepicker.ui-datepicker-multi { width:auto; } -.ui-datepicker-multi .ui-datepicker-group { float:left; } -.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } -.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } -.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } -.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } -.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } -.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } -.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } - -/* RTL support */ -.ui-datepicker-rtl { direction: rtl; } -.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } -.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } -.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } -.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } -.ui-datepicker-rtl .ui-datepicker-group { float:right; } -.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } -.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } - -/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ -.ui-datepicker-cover { - display: none; /*sorry for IE5*/ - display/**/: block; /*sorry for IE5*/ - position: absolute; /*must have*/ - z-index: -1; /*must have*/ - filter: mask(); /*must have*/ - top: -4px; /*must have*/ - left: -4px; /*must have*/ - width: 200px; /*must have*/ - height: 200px; /*must have*/ -}/* - * jQuery UI Progressbar 1.8.18 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar#theming - */ -.ui-progressbar { height:2em; text-align: left; overflow: hidden; } -.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; } \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/LGPL-LICENSE.txt b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/LGPL-LICENSE.txt deleted file mode 100755 index 02bbb60bc4..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/LGPL-LICENSE.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/arbor.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/arbor.js deleted file mode 100755 index b6ae116d31..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/arbor.js +++ /dev/null @@ -1,67 +0,0 @@ -// -// arbor.js - version 0.91 -// a graph vizualization toolkit -// -// Copyright (c) 2011 Samizdat Drafting Co. -// Physics code derived from springy.js, copyright (c) 2010 Dennis Hotson -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -(function($){ - - /* etc.js */ var trace=function(msg){if(typeof(window)=="undefined"||!window.console){return}var len=arguments.length;var args=[];for(var i=0;i0){return a[0]}else{return null}}; - /* kernel.js */ var Kernel=function(b){var k=window.location.protocol=="file:"&&navigator.userAgent.toLowerCase().indexOf("chrome")>-1;var a=(window.Worker!==undefined&&!k);var i=null;var c=null;var f=[];f.last=new Date();var l=null;var e=null;var d=null;var h=null;var g=false;var j={system:b,tween:null,nodes:{},init:function(){if(typeof(Tween)!="undefined"){c=Tween()}else{if(typeof(arbor.Tween)!="undefined"){c=arbor.Tween()}else{c={busy:function(){return false},tick:function(){return true},to:function(){trace("Please include arbor-tween.js to enable tweens");c.to=function(){};return}}}}j.tween=c;var m=b.parameters();if(a){trace("using web workers");l=setInterval(j.screenUpdate,m.timeout);i=new Worker(arbor_path()+"arbor.js");i.onmessage=j.workerMsg;i.onerror=function(n){trace("physics:",n)};i.postMessage({type:"physics",physics:objmerge(m,{timeout:Math.ceil(m.timeout)})})}else{trace("couldn't use web workers, be careful...");i=Physics(m.dt,m.stiffness,m.repulsion,m.friction,j.system._updateGeometry);j.start()}return j},graphChanged:function(m){if(a){i.postMessage({type:"changes",changes:m})}else{i._update(m)}j.start()},particleModified:function(n,m){if(a){i.postMessage({type:"modify",id:n,mods:m})}else{i.modifyNode(n,m)}j.start()},physicsModified:function(m){if(!isNaN(m.timeout)){if(a){clearInterval(l);l=setInterval(j.screenUpdate,m.timeout)}else{clearInterval(d);d=null}}if(a){i.postMessage({type:"sys",param:m})}else{i.modifyPhysics(m)}j.start()},workerMsg:function(n){var m=n.data.type;if(m=="geometry"){j.workerUpdate(n.data)}else{trace("physics:",n.data)}},_lastPositions:null,workerUpdate:function(m){j._lastPositions=m;j._lastBounds=m.bounds},_lastFrametime:new Date().valueOf(),_lastBounds:null,_currentRenderer:null,screenUpdate:function(){var n=new Date().valueOf();var m=false;if(j._lastPositions!==null){j.system._updateGeometry(j._lastPositions);j._lastPositions=null;m=true}if(c&&c.busy()){m=true}if(j.system._updateBounds(j._lastBounds)){m=true}if(m){var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}if(c){c.tick()}o.redraw();var p=f.last;f.last=new Date();f.push(f.last-p);if(f.length>50){f.shift()}}}},physicsUpdate:function(){if(c){c.tick()}i.tick();var n=j.system._updateBounds();if(c&&c.busy()){n=true}var o=j.system.renderer;var m=new Date();var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}o.redraw({timestamp:m})}var q=f.last;f.last=m;f.push(f.last-q);if(f.length>50){f.shift()}var p=i.systemEnergy();if((p.mean+p.max)/2<0.05){if(h===null){h=new Date().valueOf()}if(new Date().valueOf()-h>1000){clearInterval(d);d=null}else{}}else{h=null}},fps:function(n){if(n!==undefined){var q=1000/Math.max(1,targetFps);j.physicsModified({timeout:q})}var r=0;for(var p=0,o=f.length;p0);if(y){$.extend(c.adjacency[D][E].data,z.data);return}else{c.edges[z._id]=z;c.adjacency[D][E].push(z);var x=(z.length!==undefined)?z.length:1;k.push({t:"addSpring",id:z._id,fm:D,to:E,l:x});h._notify()}return z},pruneEdge:function(C){k.push({t:"dropSpring",id:C._id});delete c.edges[C._id];for(var z in c.adjacency){for(var D in c.adjacency[z]){var A=c.adjacency[z][D];for(var B=A.length-1;B>=0;B--){if(c.adjacency[z][D][B]._id===C._id){c.adjacency[z][D].splice(B,1)}}}}h._notify()},getEdges:function(y,x){y=h.getNode(y);x=h.getNode(x);if(!y||!x){return[]}if(typeof(c.adjacency[y._id])!=="undefined"&&typeof(c.adjacency[y._id][x._id])!=="undefined"){return c.adjacency[y._id][x._id]}return[]},getEdgesFrom:function(x){x=h.getNode(x);if(!x){return[]}if(typeof(c.adjacency[x._id])!=="undefined"){var y=[];$.each(c.adjacency[x._id],function(A,z){y=y.concat(z)});return y}return[]},getEdgesTo:function(x){x=h.getNode(x);if(!x){return[]}var y=[];$.each(c.edges,function(A,z){if(z.target==x){y.push(z)}});return y},eachEdge:function(x){$.each(c.edges,function(B,z){var A=c.nodes[z.source._id]._p;var y=c.nodes[z.target._id]._p;if(A.x==null||y.x==null){return}A=(w!==null)?h.toScreen(A):A;y=(w!==null)?h.toScreen(y):y;if(A&&y){x.call(h,z,A,y)}})},prune:function(y){var x={dropped:{nodes:[],edges:[]}};if(y===undefined){$.each(c.nodes,function(A,z){x.dropped.nodes.push(z);h.pruneNode(z)})}else{h.eachNode(function(A){var z=y.call(h,A,{from:h.getEdgesFrom(A),to:h.getEdgesTo(A)});if(z){x.dropped.nodes.push(A);h.pruneNode(A)}})}return x},graft:function(y){var x={added:{nodes:[],edges:[]}};if(y.nodes){$.each(y.nodes,function(A,z){var B=h.getNode(A);if(B){B.data=z}else{x.added.nodes.push(h.addNode(A,z))}c.kernel.start()})}if(y.edges){$.each(y.edges,function(B,z){var A=h.getNode(B);if(!A){x.added.nodes.push(h.addNode(B,{}))}$.each(z,function(F,C){var E=h.getNode(F);if(!E){x.added.nodes.push(h.addNode(F,{}))}var D=h.getEdges(B,F);if(D.length>0){D[0].data=C}else{x.added.edges.push(h.addEdge(B,F,C))}})})}return x},merge:function(y){var x={added:{nodes:[],edges:[]},dropped:{nodes:[],edges:[]}};$.each(c.edges,function(C,B){if((y.edges[B.source.name]===undefined||y.edges[B.source.name][B.target.name]===undefined)){h.pruneEdge(B);x.dropped.edges.push(B)}});var A=h.prune(function(C,B){if(y.nodes[C.name]===undefined){x.dropped.nodes.push(C);return true}});var z=h.graft(y);x.added.nodes=x.added.nodes.concat(z.added.nodes);x.added.edges=x.added.edges.concat(z.added.edges);x.dropped.nodes=x.dropped.nodes.concat(A.dropped.nodes);x.dropped.edges=x.dropped.edges.concat(A.dropped.edges);return x},tweenNode:function(A,x,z){var y=h.getNode(A);if(y){c.tween.to(y,x,z)}},tweenEdge:function(y,x,B,A){if(A===undefined){h._tweenEdge(y,x,B)}else{var z=h.getEdges(y,x);$.each(z,function(C,D){h._tweenEdge(D,B,A)})}},_tweenEdge:function(y,x,z){if(y&&y._id!==undefined){c.tween.to(y,x,z)}},_updateGeometry:function(A){if(A!=undefined){var x=(A.epoch1||C.y*w.height>1){p=_newBounds;return true}else{return false}},energy:function(){return a},bounds:function(){var y=null;var x=null;$.each(c.nodes,function(B,A){if(!y){y=new Point(A._p);x=new Point(A._p);return}var z=A._p;if(z.x===null||z.y===null){return}if(z.x>y.x){y.x=z.x}if(z.y>y.y){y.y=z.y}if(z.x0){c.kernel.graphChanged(k);k=[];i=null}}};c.kernel=Kernel(h);c.tween=c.kernel.tween||null;var e=(window.__defineGetter__==null||window.__defineSetter__==null)?function(y,x,z){if(!y.hasOwnProperty(x)){Object.defineProperty(y,x,z)}}:function(y,x,z){if(z.get){y.__defineGetter__(x,z.get)}if(z.set){y.__defineSetter__(x,z.set)}};var n=function(x){this._n=x;this._state=c};n.prototype=new Point();e(n.prototype,"x",{get:function(){return this._n._p.x},set:function(x){this._state.kernel.particleModified(this._n._id,{x:x})}});e(n.prototype,"y",{get:function(){return this._n._p.y},set:function(x){this._state.kernel.particleModified(this._n._id,{y:x})}});e(Node.prototype,"p",{get:function(){return new n(this)},set:function(x){this._p.x=x.x;this._p.y=x.y;this._state.kernel.particleModified(this._id,{x:x.x,y:x.y})}});e(Node.prototype,"mass",{get:function(){return this._mass},set:function(x){this._mass=x;this._state.kernel.particleModified(this._id,{m:x})}});e(Node.prototype,"tempMass",{set:function(x){this._state.kernel.particleModified(this._id,{_m:x})}});e(Node.prototype,"fixed",{get:function(){return this._fixed},set:function(x){this._fixed=x;this._state.kernel.particleModified(this._id,{f:x?1:0})}});return h}; - /* barnes-hut.js */ var BarnesHutTree=function(){var b=[];var a=0;var e=null;var d=0.5;var c={init:function(g,h,f){d=f;a=0;e=c._newBranch();e.origin=g;e.size=h.subtract(g)},insert:function(j){var f=e;var g=[j];while(g.length){var h=g.shift();var m=h._m||h.m;var p=c._whichQuad(h,f);if(f[p]===undefined){f[p]=h;f.mass+=m;if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}}else{if("origin" in f[p]){f.mass+=(m);if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}f=f[p];g.unshift(h)}else{var l=f.size.divide(2);var n=new Point(f.origin);if(p[0]=="s"){n.y+=l.y}if(p[1]=="e"){n.x+=l.x}var o=f[p];f[p]=c._newBranch();f[p].origin=n;f[p].size=l;f.mass=m;f.p=h.p.multiply(m);f=f[p];if(o.p.x===h.p.x&&o.p.y===h.p.y){var k=l.x*0.08;var i=l.y*0.08;o.p.x=Math.min(n.x+l.x,Math.max(n.x,o.p.x-k/2+Math.random()*k));o.p.y=Math.min(n.y+l.y,Math.max(n.y,o.p.y-i/2+Math.random()*i))}g.push(o);g.unshift(h)}}}},applyForces:function(m,g){var f=[e];while(f.length){node=f.shift();if(node===undefined){continue}if(m===node){continue}if("f" in node){var k=m.p.subtract(node.p);var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node._m||node.m)).divide(l*l))}else{var j=m.p.subtract(node.p.divide(node.mass)).magnitude();var h=Math.sqrt(node.size.x*node.size.y);if(h/j>d){f.push(node.ne);f.push(node.nw);f.push(node.se);f.push(node.sw)}else{var k=m.p.subtract(node.p.divide(node.mass));var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node.mass)).divide(l*l))}}}},_whichQuad:function(i,f){if(i.p.exploded()){return null}var h=i.p.subtract(f.origin);var g=f.size.divide(2);if(h.y-1){o.splice(p,1)}delete c.particles[r];delete l.particles[r]},modifyNode:function(r,p){if(r in c.particles){var q=c.particles[r];if("x" in p){q.p.x=p.x}if("y" in p){q.p.y=p.y}if("m" in p){q.m=p.m}if("f" in p){q.fixed=(p.f===1)}if("_m" in p){if(q._m===undefined){q._m=q.m}q.m=p._m}}},addSpring:function(t){var s=t.id;var p=t.l;var r=c.particles[t.fm];var q=c.particles[t.to];if(r!==undefined&&q!==undefined){c.springs[s]=new Spring(r,q,p,i.stiffness);k.push(c.springs[s]);r.connections++;q.connections++;delete l.particles[t.fm];delete l.particles[t.to]}},dropSpring:function(s){var r=s.id;var q=c.springs[r];q.point1.connections--;q.point2.connections--;var p=$.inArray(q,k);if(p>-1){k.splice(p,1)}delete c.springs[r]},_update:function(p){d++;$.each(p,function(q,r){if(r.t in i){i[r.t](r)}});return d},tick:function(){i.tendParticles();i.eulerIntegrator(i.dt);i.tock()},tock:function(){var p=[];$.each(c.particles,function(r,q){p.push(r);p.push(q.p.x);p.push(q.p.y)});if(h){h({geometry:p,epoch:d,energy:b,bounds:g})}},tendParticles:function(){$.each(c.particles,function(q,p){if(p._m!==undefined){if(Math.abs(p.m-p._m)<1){p.m=p._m;delete p._m}else{p.m*=0.98}}p.v.x=p.v.y=0})},eulerIntegrator:function(p){if(i.repulsion>0){if(i.theta>0){i.applyBarnesHutRepulsion()}else{i.applyBruteForceRepulsion()}}if(i.stiffness>0){i.applySprings()}i.applyCenterDrift();if(i.gravity){i.applyCenterGravity()}i.updateVelocity(p);i.updatePosition(p)},applyBruteForceRepulsion:function(){$.each(c.particles,function(q,p){$.each(c.particles,function(s,r){if(p!==r){var u=p.p.subtract(r.p);var v=Math.max(1,u.magnitude());var t=((u.magnitude()>0)?u:Point.random(1)).normalize();p.applyForce(t.multiply(i.repulsion*(r._m||r.m)*0.5).divide(v*v*0.5));r.applyForce(t.multiply(i.repulsion*(p._m||p.m)*0.5).divide(v*v*-0.5))}})})},applyBarnesHutRepulsion:function(){if(!g.topleft||!g.bottomright){return}var q=new Point(g.bottomright);var p=new Point(g.topleft);f.init(p,q,i.theta);$.each(c.particles,function(s,r){f.insert(r)});$.each(c.particles,function(s,r){f.applyForces(r,i.repulsion)})},applySprings:function(){$.each(c.springs,function(t,p){var s=p.point2.p.subtract(p.point1.p);var q=p.length-s.magnitude();var r=((s.magnitude()>0)?s:Point.random(1)).normalize();p.point1.applyForce(r.multiply(p.k*q*-0.5));p.point2.applyForce(r.multiply(p.k*q*0.5))})},applyCenterDrift:function(){var q=0;var r=new Point(0,0);$.each(c.particles,function(t,s){r.add(s.p);q++});if(q==0){return}var p=r.divide(-q);$.each(c.particles,function(t,s){s.applyForce(p)})},applyCenterGravity:function(){$.each(c.particles,function(r,p){var q=p.p.multiply(-1);p.applyForce(q.multiply(i.repulsion/100))})},updateVelocity:function(p){$.each(c.particles,function(t,q){if(q.fixed){q.v=new Point(0,0);q.f=new Point(0,0);return}var s=q.v.magnitude();q.v=q.v.add(q.f.multiply(p)).multiply(1-i.friction);q.f.x=q.f.y=0;var r=q.v.magnitude();if(r>j){q.v=q.v.divide(r*r)}})},updatePosition:function(q){var r=0,p=0,u=0;var t=null;var s=null;$.each(c.particles,function(w,v){v.p=v.p.add(v.v.multiply(q));var x=v.v.magnitude();var z=x*x;r+=z;p=Math.max(z,p);u++;if(!t){t=new Point(v.p.x,v.p.y);s=new Point(v.p.x,v.p.y);return}var y=v.p;if(y.x===null||y.y===null){return}if(y.x>t.x){t.x=y.x}if(y.y>t.y){t.y=y.y}if(y.x1000){e.stop()}else{}}else{c=null}},tock:function(h){h.type="geometry";postMessage(h)},modifyNode:function(i,h){a.modifyNode(i,h);e.go()},modifyPhysics:function(h){a.modifyPhysics(h)},update:function(h){var i=a._update(h)}};return e};var physics=PhysicsWorker();onmessage=function(a){if(!a.data.type){postMessage("ÂżkĂ©rnèl?");return}if(a.data.type=="physics"){var b=a.data.physics;physics.init(a.data.physics);return}switch(a.data.type){case"modify":physics.modifyNode(a.data.id,a.data.mods);break;case"changes":physics.update(a.data.changes);physics.go();break;case"start":physics.go();break;case"stop":physics.stop();break;case"sys":var b=a.data.param||{};if(!isNaN(b.timeout)){physics.timeout(b.timeout)}physics.modifyPhysics(b);physics.go();break}}; - })() - - - arbor = (typeof(arbor)!=='undefined') ? arbor : {} - $.extend(arbor, { - // object constructors (don't use â€new’, just call them) - ParticleSystem:ParticleSystem, - Point:function(x, y){ return new Point(x, y) }, - - // immutable object with useful methods - etc:{ - trace:trace, // Ć’(msg) -> safe console logging - dirname:dirname, // Ć’(path) -> leading part of path - basename:basename, // Ć’(path) -> trailing part of path - ordinalize:ordinalize, // Ć’(num) -> abbrev integers (and add commas) - objcopy:objcopy, // Ć’(old) -> clone an object - objcmp:objcmp, // Ć’(a, b, strict_ordering) -> t/f comparison - objkeys:objkeys, // Ć’(obj) -> array of all keys in obj - objmerge:objmerge, // Ć’(dst, src) -> like $.extend but non-destructive - uniq:uniq, // Ć’(arr) -> array of unique items in arr - arbor_path:arbor_path, // Ć’() -> guess the directory of the lib code - } - }) - -})(this.jQuery) \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.js deleted file mode 100755 index 0fa9f15fdd..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.js +++ /dev/null @@ -1,15934 +0,0 @@ - -/* cytoscape.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - - -// this is put as a global var in the browser -// or it's just a global to this module if commonjs -var cytoscape; - -(function(){ - - // the object iteself is a function that init's an instance of cytoscape - var $$ = cytoscape = function(){ - return cytoscape.init.apply(cytoscape, arguments); - }; - - // allow functional access to cytoscape.js - // e.g. var cyto = $.cytoscape({ selector: "#foo", ... }); - // var nodes = cyto.nodes(); - $$.init = function( options ){ - - // if no options specified, use default - if( options === undefined ){ - options = {}; - } - - // create instance - if( $$.is.plainObject( options ) ){ - return new $$.Core( options ); - } - - // allow for registration of extensions - // e.g. $.cytoscape("renderer", "svg", SvgRenderer); - // e.g. $.cytoscape("renderer", "svg", "nodeshape", "ellipse", SvgEllipseNodeShape); - // e.g. $.cytoscape("core", "doSomething", function(){ /* doSomething code */ }); - // e.g. $.cytoscape("collection", "doSomething", function(){ /* doSomething code */ }); - else if( $$.is.string( options ) ) { - return $$.extension.apply($$.extension, arguments); - } - }; - - // define the function namespace here, since it has members in many places - $$.fn = {}; - - // TODO test that this works: - if( typeof exports !== 'undefined' ){ // expose as a commonjs module - exports = module.exports = cytoscape; - } - - // make sure we always register in the window just in case (e.g. w/ derbyjs) - window.cytoscape = cytoscape; - -})(); - -// type testing utility functions - -;(function($$){ - - $$.is = { - string: function(obj){ - return obj != null && typeof obj == typeof ""; - }, - - fn: function(obj){ - return obj != null && typeof obj === typeof function(){}; - }, - - array: function(obj){ - return obj != null && obj instanceof Array; - }, - - plainObject: function(obj){ - return obj != null && typeof obj === typeof {} && !$$.is.array(obj) && obj.constructor === Object; - }, - - number: function(obj){ - return obj != null && typeof obj === typeof 1 && !isNaN(obj); - }, - - integer: function( obj ){ - return $$.is.number(obj) && Math.floor(obj) === obj; - }, - - color: function(obj){ - return obj != null && typeof obj === typeof "" && $.Color(obj).toString() !== ""; - }, - - bool: function(obj){ - return obj != null && typeof obj === typeof true; - }, - - elementOrCollection: function(obj){ - return $$.is.element(obj) || $$.is.collection(obj); - }, - - element: function(obj){ - return obj instanceof $$.Element && obj._private.single; - }, - - collection: function(obj){ - return obj instanceof $$.Collection && !obj._private.single; - }, - - core: function(obj){ - return obj instanceof $$.Core; - }, - - style: function(obj){ - return obj instanceof $$.Style; - }, - - stylesheet: function(obj){ - return obj instanceof $$.Stylesheet; - }, - - event: function(obj){ - return obj instanceof $$.Event; - }, - - emptyString: function(obj){ - if( !obj ){ // null is empty - return true; - } else if( $$.is.string(obj) ){ - if( obj === "" || obj.match(/^\s+$/) ){ - return true; // empty string is empty - } - } - - return false; // otherwise, we don't know what we've got - }, - - nonemptyString: function(obj){ - if( obj && $$.is.string(obj) && obj !== "" && !obj.match(/^\s+$/) ){ - return true; - } - - return false; - }, - - domElement: function(obj){ - if( typeof HTMLElement === 'undefined' ){ - return false; // we're not in a browser so it doesn't matter - } else { - return obj instanceof HTMLElement; - } - - - } - }; - -})( cytoscape ); - -;(function($$){ - - // utility functions only for internal use - - $$.util = { - - // the jquery extend() function - // NB: modified to use $$.is etc since we can't use jquery functions - extend: function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !$$.is.fn(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( $$.is.plainObject(copy) || (copyIsArray = $$.is.array(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && $$.is.array(src) ? src : []; - - } else { - clone = src && $$.is.plainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = $$.util.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; - }, - - error: function( msg ){ - if( console ){ - if( console.error ){ - console.error( msg ); - } else if( console.log ){ - console.log( msg ); - } else { - throw msg; - } - } else { - throw msg; - } - }, - - clone: function( obj ){ - var target = {}; - for (var i in obj) { - if ( obj.hasOwnProperty(i) ) { // TODO is this hasOwnProperty() call necessary for our use? - target[i] = obj[i]; - } - } - return target; - }, - - // gets a shallow copy of the argument - copy: function( obj ){ - if( obj == null ){ - return obj; - } if( $$.is.array(obj) ){ - return obj.slice(); - } else if( $$.is.plainObject(obj) ){ - return $$.util.clone( obj ); - } else { - return obj; - } - }, - - // has anything been set in the map - mapEmpty: function( map ){ - var empty = true; - - if( map != null ){ - for(var i in map){ - empty = false; - break; - } - } - - return empty; - }, - - // pushes to the array at the end of a map (map may not be built) - pushMap: function( options ){ - var array = $$.util.getMap(options); - - if( array == null ){ // if empty, put initial array - $$.util.setMap( $.extend({}, options, { - value: [ options.value ] - }) ); - } else { - array.push( options.value ); - } - }, - - // sets the value in a map (map may not be built) - setMap: function( options ){ - var obj = options.map; - var key; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to set map with object key"); - } - - if( i < keys.length - 1 ){ - - // extend the map if necessary - if( obj[key] == null ){ - obj[key] = {}; - } - - obj = obj[key]; - } else { - // set the value - obj[key] = options.value; - } - } - }, - - // gets the value in a map even if it's not built in places - getMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to get map with object key"); - } - - obj = obj[key]; - - if( obj == null ){ - return obj; - } - } - - return obj; - }, - - // deletes the entry in the map - deleteMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - var keepChildren = options.keepChildren; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to delete map with object key"); - } - - var lastKey = i === options.keys.length - 1; - if( lastKey ){ - - if( keepChildren ){ // then only delete child fields not in keepChildren - for( var child in obj ){ - if( !keepChildren[child] ){ - delete obj[child]; - } - } - } else { - delete obj[key]; - } - - } else { - obj = obj[key]; - } - } - }, - - capitalize: function(str){ - if( $$.is.emptyString(str) ){ - return str; - } - - return str.charAt(0).toUpperCase() + str.substring(1); - }, - - camel2dash: function( str ){ - var ret = []; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var chLowerCase = ch.toLowerCase(); - var isUpperCase = ch !== chLowerCase; - - if( isUpperCase ){ - ret.push( "-" ); - ret.push( chLowerCase ); - } else { - ret.push( ch ); - } - } - - var noUpperCases = ret.length === str.length; - if( noUpperCases ){ return str } // cheaper than .join() - - return ret.join(""); - }, - - dash2camel: function( str ){ - var ret = []; - var nextIsUpper = false; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var isDash = ch === "-"; - - if( isDash ){ - nextIsUpper = true; - } else { - if( nextIsUpper ){ - ret.push( ch.toUpperCase() ); - } else { - ret.push( ch ); - } - - nextIsUpper = false; - } - } - - return ret.join(""); - }, - - // strip spaces from beginning of string and end of string - trim: function( str ){ - var first, last; - - // find first non-space char - for( first = 0; first < str.length && str[first] === " "; first++ ){} - - // find last non-space char - for( last = str.length - 1; last > first && str[last] === " "; last-- ){} - - return str.substring(first, last + 1); - }, - - // get [r, g, b] from #abc or #aabbcc - hex2tuple: function( hex ){ - if( !(hex.length === 4 || hex.length === 7) || hex[0] !== "#" ){ return; } - - var shortHex = hex.length === 4; - var r, g, b; - var base = 16; - - if( shortHex ){ - r = parseInt( hex[1] + hex[1], base ); - g = parseInt( hex[2] + hex[2], base ); - b = parseInt( hex[3] + hex[3], base ); - } else { - r = parseInt( hex[1] + hex[2], base ); - g = parseInt( hex[3] + hex[4], base ); - b = parseInt( hex[5] + hex[6], base ); - } - - return [r, g, b]; - }, - - // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0) - hsl2tuple: function( hsl ){ - var ret; - var number = $$.util.regex.number; - var h, s, l, a, r, g, b; - - var m = new RegExp("^" + $$.util.regex.hsla + "$").exec(hsl); - if( m ){ - - // get hue - h = parseInt( m[1] ); - if( h < 0 ){ - h = ( 360 - (-1*h % 360) ) % 360; - } else if( h > 360 ){ - h = h % 360; - } - h /= 360; // normalise on [0, 1] - - s = parseFloat( m[2] ); - if( s < 0 || s > 100 ){ return; } // saturation is [0, 100] - s = s/100; // normalise on [0, 1] - - l = parseFloat( m[3] ); - if( l < 0 || l > 100 ){ return; } // lightness is [0, 100] - l = l/100; // normalise on [0, 1] - - a = m[4]; - if( a !== undefined ){ - a = parseFloat( a ); - - if( a < 0 || a > 1 ){ return; } // alpha is [0, 1] - } - - // now, convert to rgb - // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - if( s === 0 ){ - r = g = b = Math.round(l * 255); // achromatic - } else { - function hue2rgb(p, q, t){ - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = Math.round( 255 * hue2rgb(p, q, h + 1/3) ); - g = Math.round( 255 * hue2rgb(p, q, h) ); - b = Math.round( 255 * hue2rgb(p, q, h - 1/3) ); - } - - ret = [r, g, b, a]; - } - - return ret; - }, - - // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0) - rgb2tuple: function( rgb ){ - var ret; - var number = $$.util.regex.number; - - var m = new RegExp("^" + $$.util.regex.rgba + "$").exec(rgb); - if( m ){ - ret = []; - - var isPct = []; - for( var i = 1; i <= 3; i++ ){ - var channel = m[i]; - - if( channel[ channel.length - 1 ] === "%" ){ - isPct[i] = true; - } - channel = parseFloat( channel ); - - if( isPct[i] ){ - channel = channel/100 * 255; // normalise to [0, 255] - } - - if( channel < 0 || channel > 255 ){ return; } // invalid channel value - - ret.push( Math.floor(channel) ); - } - - var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3]; - var allArePct = isPct[1] && isPct[2] && isPct[3]; - if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is - - var alpha = m[4]; - if( alpha !== undefined ){ - alpha = parseFloat( alpha ); - - if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value - - ret.push( alpha ); - } - } - - return ret; - }, - - colorname2tuple: function( color ){ - return $$.util.colors[ color.toLowerCase() ]; - }, - - color2tuple: function( color ){ - return $$.util.colorname2tuple(color) - || $$.util.hex2tuple(color) - || $$.util.rgb2tuple(color) - || $$.util.hsl2tuple(color); - }, - - tuple2hex: function( tuple ){ - var r = tuple[0]; - var g = tuple[1]; - var b = tuple[2]; - - function ch2hex( ch ){ - var hex = ch.toString(16); - - if( hex.length === 1 ){ - hex = '0' + hex; - } - - return hex; - } - - return '#' + ch2hex(r) + ch2hex(g) + ch2hex(b); - }, - - colors: { - // special colour names - transparent: [0,0,0,0], // NB alpha === 0 - - // regular colours - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - darkkhaki: [189,183,107], - darkmagenta: [139,0,139], - darkolivegreen: [85,107,47], - darkorange: [255,140,0], - darkorchid: [153,50,204], - darkred: [139,0,0], - darksalmon: [233,150,122], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - grey: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] - } - - }; - - $$.util.regex = {}; - - $$.util.regex.number = "(?:\\d*\\.\\d+|\\d+|\\d*\\.\\d+[eE]\\d+)"; - - $$.util.regex.rgba = "rgb[a]?\\(("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.rgbaNoBackRefs = "rgb[a]?\\((?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hsla = "hsl[a]?\\(("+ $$.util.regex.number +")\\s*,\\s*("+ $$.util.regex.number +"[%])\\s*,\\s*("+ $$.util.regex.number +"[%])(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.hslaNoBackRefs = "hsl[a]?\\((?:"+ $$.util.regex.number +")\\s*,\\s*(?:"+ $$.util.regex.number +"[%])\\s*,\\s*(?:"+ $$.util.regex.number +"[%])(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hex3 = "\\#[0-9a-fA-F]{3}"; - $$.util.regex.hex6 = "\\#[0-9a-fA-F]{6}"; - -})( cytoscape ); - -;(function($$){ - - $$.math = {}; - - $$.math.boxInBezierVicinity = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - // Return values: - // 0 - curve is not in box - // 1 - curve may be in box; needs precise check - // 2 - curve is in box - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { - return 2; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { - return 2; - } else if (x2 >= boxMinX && x2 <= boxMaxX && y2 >= boxMinY && y2 <= boxMaxY) { - return 1; - } - - var curveMinX = Math.min(x1, x2, x3); - var curveMinY = Math.min(y1, y2, y3); - var curveMaxX = Math.max(x1, x2, x3); - var curveMaxY = Math.max(y1, y2, y3); - - /* - console.log(curveMinX + ", " + curveMinY + ", " + curveMaxX - + ", " + curveMaxY); - if (curveMinX == undefined) { - console.log("undefined curveMinX: " + x1 + ", " + x2 + ", " + x3); - } - */ - - if (curveMinX > boxMaxX - || curveMaxX < boxMinX - || curveMinY > boxMaxY - || curveMaxY < boxMinY) { - - return 0; - } - - return 1; - } - - $$.math.checkStraightEdgeCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - // Check left + right bounds - var aX = x2 - x1; - var bX = x1; - var yValue; - - // Top and bottom - var aY = y2 - y1; - var bY = y1; - var xValue; - - if (Math.abs(aX) < 0.0001) { - return (x1 >= boxMinX && x1 <= boxMaxX - && Math.min(y1, y2) <= boxMinY - && Math.max(y1, y2) >= boxMaxY); - } - - var tLeft = (boxMinX - bX) / aX; - if (tLeft > 0 && tLeft <= 1) { - yValue = aY * tLeft + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tRight = (boxMaxX - bX) / aX; - if (tRight > 0 && tRight <= 1) { - yValue = aY * tRight + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tTop = (boxMinY - bY) / aY; - if (tTop > 0 && tTop <= 1) { - xValue = aX * tTop + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - var tBottom = (boxMaxY - bY) / aY; - if (tBottom > 0 && tBottom <= 1) { - xValue = aX * tBottom + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - return false; - } - - $$.math.checkBezierCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { - return true; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { - return true; - } - - var aX = x1 - 2 * x2 + x3; - var bX = -2 * x1 + 2 * x2; - var cX = x1; - - var xIntervals = []; - - if (Math.abs(aX) < 0.0001) { - var leftParam = (boxMinX - x1) / bX; - var rightParam = (boxMaxX - x1) / bX; - - xIntervals.push(leftParam, rightParam); - } else { - // Find when x coordinate of the curve crosses the left side of the box - var discriminantX1 = bX * bX - 4 * aX * (cX - boxMinX); - var tX1, tX2; - if (discriminantX1 > 0) { - var sqrt = Math.sqrt(discriminantX1); - tX1 = (-bX + sqrt) / (2 * aX); - tX2 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX1, tX2); - } - - var discriminantX2 = bX * bX - 4 * aX * (cX - boxMaxX); - var tX3, tX4; - if (discriminantX2 > 0) { - var sqrt = Math.sqrt(discriminantX2); - tX3 = (-bX + sqrt) / (2 * aX); - tX4 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX3, tX4); - } - } - - xIntervals.sort(function(a, b) { return a - b; }); - - - var aY = y1 - 2 * y2 + y3; - var bY = -2 * y1 + 2 * y2; - var cY = y1; - - var yIntervals = []; - - if (Math.abs(aY) < 0.0001) { - var topParam = (boxMinY - y1) / bY; - var bottomParam = (boxMaxY - y1) / bY; - - yIntervals.push(topParam, bottomParam); - } else { - var discriminantY1 = bY * bY - 4 * aY * (cY - boxMinY); - - var tY1, tY2; - if (discriminantY1 > 0) { - var sqrt = Math.sqrt(discriminantY1); - tY1 = (-bY + sqrt) / (2 * aY); - tY2 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY1, tY2); - } - - var discriminantY2 = bY * bY - 4 * aY * (cY - boxMaxY); - - var tY3, tY4; - if (discriminantY2 > 0) { - var sqrt = Math.sqrt(discriminantY2); - tY3 = (-bY + sqrt) / (2 * aY); - tY4 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY3, tY4); - } - } - - yIntervals.sort(function(a, b) { return a - b; }); - - for (var index = 0; index < xIntervals.length; index += 2) { - for (var yIndex = 1; yIndex < yIntervals.length; yIndex += 2) { - - // Check if there exists values for the Bezier curve - // parameter between 0 and 1 where both the curve's - // x and y coordinates are within the bounds specified by the box - if (xIntervals[index] < yIntervals[yIndex] - && yIntervals[yIndex] >= 0.0 - && xIntervals[index] <= 1.0 - && xIntervals[index + 1] > yIntervals[yIndex - 1] - && yIntervals[yIndex - 1] <= 1.0 - && xIntervals[index + 1] >= 0.0) { - - return true; - } - } - } - - return false; - } - - $$.math.inBezierVicinity = function( - x, y, x1, y1, x2, y2, x3, y3, toleranceSquared) { - - // Middle point occurs when t = 0.5, this is when the Bezier - // is closest to (x2, y2) - var middlePointX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var middlePointY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - var displacementX, displacementY, offsetX, offsetY; - var dotProduct, dotSquared, hypSquared; - var outside = function(x, y, startX, startY, endX, endY, - toleranceSquared, counterClockwise) { - - dotProduct = (endY - startY) * (x - startX) + (startX - endX) * (y - startY); - dotSquared = dotProduct * dotProduct; - sideSquared = (endY - startY) * (endY - startY) - + (startX - endX) * (startX - endX); - - if (counterClockwise) { - if (dotProduct > 0) { - return false; - } - } else { - if (dotProduct < 0) { - return false; - } - } - - return (dotSquared / sideSquared > toleranceSquared); - }; - - // Used to check if the test polygon winding is clockwise or counterclockwise - var testPointX = (middlePointX + x2) / 2.0; - var testPointY = (middlePointY + y2) / 2.0; - - var counterClockwise = true; - - // The test point is always inside - if (outside(testPointX, testPointY, x1, y1, x2, y2, 0, counterClockwise)) { - counterClockwise = !counterClockwise; - } - - /* - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, middlePointX, middlePointY, toleranceSquared, - counterClockwise) - && !outside(x, y, middlePointX, middlePointY, x1, y1, toleranceSquared, - counterClockwise) - ); - */ - - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, x1, y1, toleranceSquared, - counterClockwise) - ); - } - - // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where - // r is the real component, i is the imaginary component - $$.math.solveCubic = function(a, b, c, d, result) { - - // An implementation of the Cardano method - // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots - // provided by http://www3.telus.net/thothworks/Quad3Deg.html - - // Get rid of a - b /= a; - c /= a; - d /= a; - - var discrim, q, r, dum1, s, t, term1, r13; - - q = (3.0 * c - (b * b)) / 9.0; - r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); - r /= 54.0; - - discrim = q * q * q + r * r; - result[1] = 0; //The first root is always real. - term1 = (b / 3.0); - - if (discrim > 0) { // one root real, two are complex - s = r + Math.sqrt(discrim); - s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0))); - t = r - Math.sqrt(discrim); - t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0))); - result[0] = -term1 + s + t; - term1 += (s + t) / 2.0; - result[4] = result[2] = -term1; - term1 = Math.sqrt(3.0) * (-t + s) / 2; - result[3] = term1; - result[5] = -term1; - return; - } // End if (discrim > 0) - - // The remaining options are all real - result[5] = result[3] = 0; - - if (discrim == 0){ // All roots real, at least two are equal. - r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0))); - result[0] = -term1 + 2.0 * r13; - result[4] = result[2] = -(r13 + term1); - return; - } // End if (discrim == 0) - - // Only option left is that all roots are real and unequal (to get here, q < 0) - q = -q; - dum1 = q * q * q; - dum1 = Math.acos(r / Math.sqrt(dum1)); - r13 = 2.0 * Math.sqrt(q); - result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); - result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); - result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); - return; - } - - $$.math.sqDistanceToQuadraticBezier = function(x, y, - x1, y1, x2, y2, x3, y3) { - - // Find minimum distance by using the minimum of the distance - // function between the given point and the curve - - // This gives the coefficients of the resulting cubic equation - // whose roots tell us where a possible minimum is - // (Coefficients are divided by 4) - - var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3 - + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3; - - var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3 - + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3; - - var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x - + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y; - - var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x - + y1*y2 - y1*y1 + y1*y - y2*y; - - debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); - - var roots = []; - - // Use the cubic solving algorithm - this.solveCubic(a, b, c, d, roots); - - var zeroThreshold = 0.0000001; - - var params = []; - - for (var index = 0; index < 6; index += 2) { - if (Math.abs(roots[index + 1]) < zeroThreshold - && roots[index] >= 0 - && roots[index] <= 1.0) { - params.push(roots[index]); - } - } - - params.push(1.0); - params.push(0.0); - - var minDistanceSquared = -1; - var closestParam; - - var curX, curY, distSquared; - for (var i = 0; i < params.length; i++) { - curX = Math.pow(1.0 - params[i], 2.0) * x1 - + 2.0 * (1 - params[i]) * params[i] * x2 - + params[i] * params[i] * x3; - - curY = Math.pow(1 - params[i], 2.0) * y1 - + 2 * (1.0 - params[i]) * params[i] * y2 - + params[i] * params[i] * y3; - - distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); - debug("distance for param " + params[i] + ": " + Math.sqrt(distSquared)); - if (minDistanceSquared >= 0) { - if (distSquared < minDistanceSquared) { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } else { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } - - /* - debugStats.clickX = x; - debugStats.clickY = y; - - debugStats.closestX = Math.pow(1.0 - closestParam, 2.0) * x1 - + 2.0 * (1.0 - closestParam) * closestParam * x2 - + closestParam * closestParam * x3; - - debugStats.closestY = Math.pow(1.0 - closestParam, 2.0) * y1 - + 2.0 * (1.0 - closestParam) * closestParam * y2 - + closestParam * closestParam * y3; - */ - - debug("given: " - + "( " + x + ", " + y + "), " - + "( " + x1 + ", " + y1 + "), " - + "( " + x2 + ", " + y2 + "), " - + "( " + x3 + ", " + y3 + ")"); - - - debug("roots: " + roots); - debug("params: " + params); - debug("closest param: " + closestParam); - return minDistanceSquared; - } - - var debug = function(o) { - if (false) { - console.log(o); - } - } - -})( cytoscape ); - -// type testing utility functions - -;(function($$){ - - // list of ids with other metadata assoc'd with it - $$.instances = []; - $$.instanceCounter = 0; - $$.lastInstanceTime; - - $$.registerInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - // if we have an old reg that is empty (no cy), then - var oldReg = $$.getRegistrationForInstance(instance, domElement); - if( oldReg ){ - if( !oldReg.cy ){ - oldReg.cy = instance; - oldReg.domElement = domElement; - } else { - $$.util.error('Tried to register on a pre-existing registration'); - } - - return oldReg; - - // otherwise, just make a new registration - } else { - var time = +new Date; - var suffix; - - // add a suffix in case instances collide on the same time - if( !$$.lastInstanceTime || $$.lastInstanceTime === time ){ - $$.instanceCounter = 0; - } else { - ++$$.instanceCounter; - } - $$.lastInstanceTime = time; - suffix = $$.instanceCounter; - - var id = "cy-" + time + "-" + suffix; - - // create the registration object - var registration = { - id: id, - cy: cy, - domElement: domElement, - readies: [] // list of bound ready functions before calling init - }; - - // put the registration object in the pool - $$.instances.push( registration ); - $$.instances[ id ] = registration; - - return registration; - } - }; - - $$.removeRegistrationForInstance = function(instance, domElement){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - delete $$.instances[ id ]; - $$.instances.splice(id, 1); - - } else if( $$.is.domElement(domElement) ){ - for( var i = 0; i < $$.instances.length; i++ ){ - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - delete $$.instances[ reg.id ]; - $$.instances.splice(i, 1); - i--; - } - } - } - } - - $$.getRegistrationForInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - if( instance.registered() ){ // only want it if it's registered b/c if not it has no reg'd id - cy = instance; - } - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - return $$.instances[ id ]; - - } else if( $$.is.domElement(domElement) ){ - for( var i = $$.instances.length - 1; i >= 0; i-- ){ // look backwards, since most recent is the one we want - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - return reg; - } - } - } - }; - -})( cytoscape ); - -;(function($$){ - - // registered extensions to cytoscape, indexed by name - var extensions = {}; - $$.extensions = extensions; - - // registered modules for extensions, indexed by name - var modules = {}; - $$.modules = modules; - - function setExtension(type, name, registrant){ - var impl = {}; - impl[name] = registrant; - - switch( type ){ - case "core": - case "collection": - $$.fn[type]( impl ); - } - - return $$.util.setMap({ - map: extensions, - keys: [ type, name ], - value: registrant - }); - } - - function getExtension(type, name){ - return $$.util.getMap({ - map: extensions, - keys: [ type, name ] - }); - } - - function setModule(type, name, moduleType, moduleName, registrant){ - return $$.util.setMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ], - value: registrant - }); - } - - function getModule(type, name, moduleType, moduleName){ - return $$.util.getMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ] - }); - } - - $$.extension = function(){ - // e.g. $$.extension("renderer", "svg") - if( arguments.length == 2 ){ - return getExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", { ... }) - else if( arguments.length == 3 ){ - return setExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse") - else if( arguments.length == 4 ){ - return getModule.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse", { ... }) - else if( arguments.length == 5 ){ - return setModule.apply(this, arguments); - } - - else { - $.error("Invalid extension access syntax"); - } - - }; - -})( cytoscape ); - -;(function($, $$){ - - if( !$ ){ return } // no jquery => don't need this - - // allow calls on a jQuery selector by proxying calls to $.cytoscape - // e.g. $("#foo").cytoscape(options) => $.cytoscape(options) on #foo - $.fn.cytoscape = function(opts){ - var $this = $(this); - - // get object - if( opts === "get" ){ - var reg = $$.getRegistrationForInstance( $this[0] ); - return reg.cy; - } - - // bind to ready - else if( $$.is.fn(opts) ){ - //debugger; - - var ready = opts; - var domEle = $this[0]; - var reg = $$.getRegistrationForInstance( domEle ); - - if( !reg ){ - reg = $$.registerInstance( domEle ); - } - - if( reg && reg.cy && reg.cy.ready() ){ - // already ready so just trigger now - reg.cy.trigger("ready", [], ready); - - } else { - // not yet ready, so add to readies list - - reg.readies.push( ready ); - } - - } - - // proxy to create instance - else if( $$.is.plainObject(opts) ){ - return $this.each(function(){ - var options = $.extend({}, opts, { - container: $(this)[0] - }); - - cytoscape(options); - }); - } - - // proxy a function call - else { - var domEle = $this[0]; - var rets = []; - var args = []; - for(var i = 1; i < arguments.length; i++){ - args[i - 1] = arguments[i]; - } - - $this.each(function(){ - var reg = $$.getRegistrationForInstance( domEle ); - var cy = reg.cy; - var fnName = opts; - - if( cy && $$.is.fn( cy[fnName] ) ){ - var ret = cy[fnName].apply(cy, args); - rets.push(ret); - } - }); - - // if only one instance, don't need to return array - if( rets.length === 1 ){ - rets = rets[0]; - } else if( rets.length == 0 ){ - rets = $(this); - } - - return rets; - } - - }; - - // allow access to the global cytoscape object under jquery for legacy reasons - $.cytoscape = cytoscape; - - // use short alias (cy) if not already defined - if( $.fn.cy == null && $.cy == null ){ - $.fn.cy = $.fn.cytoscape; - $.cy = $.cytoscape; - } - -})(typeof jQuery !== 'undefined' ? jQuery : null , cytoscape); - -;(function($$){ - - // shamelessly taken from jQuery - // https://github.com/jquery/jquery/blob/master/src/event.js - - $$.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof $$.Event) ) { - return new $$.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - $$.util.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || +new Date; - - // Mark it as fixed - //this[ jQuery.expando ] = true; - }; - - function returnFalse() { - return false; - } - function returnTrue() { - return true; - } - - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding - // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html - $$.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // otherwise set the returnValue property of the original event to false (IE) - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - // otherwise set the cancelBubble property of the original event to true (IE) - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse - }; - - -})( cytoscape ); - -;(function($$){ - - // metaprogramming makes me happy - - // use this module to cherry pick functions into your prototype - // (useful for functions shared between the core and collections, for example) - - // e.g. - // $$.fn.collection({ - // foo: $$.define.foo({ /* params... */ }) - // }); - - $$.define = { - - // access data field - data: function( params ){ - var defaults = { - field: "data", - bindingEvent: "data", - allowBinding: false, - allowSetting: false, - allowGetting: false, - settingEvent: "data", - settingTriggersEvent: false, - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false - }; - params = $$.util.extend({}, defaults, params); - - return function( name, value ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .data("foo", ...) - if( $$.is.string(name) ){ // set or get property - - // .data("foo") - if( p.allowGetting && value === undefined ){ // get - - var ret; - if( single ){ - ret = single._private[ p.field ][ name ]; - } - return ret; - - // .data("foo", "bar") - } else if( p.allowSetting && value !== undefined ) { // set - var valid = !p.immutableKeys[name]; - if( valid ){ - - for( var i = 0, l = all.length; i < l; i++ ){ - all[i]._private[ p.field ][ name ] = value; - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - } - } - - // .data({ "foo": "bar" }) - } else if( p.allowSetting && $$.is.plainObject(name) ){ // extend - var obj = name; - var k, v; - - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - for( var i = 0, l = all.length; i < l; i++ ){ - all[i]._private[ p.field ][ k ] = v; - } - } - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - - // .data(function(){ ... }) - } else if( p.allowBinding && $$.is.fn(name) ){ // bind to event - var fn = name; - self.bind( p.bindingEvent, fn ); - - // .data() - } else if( p.allowGetting && name === undefined ){ // get whole object - var ret; - if( single ){ - ret = single._private[ p.field ]; - } - return ret; - } - - return self; // maintain chainability - }; // function - }, // data - - batchData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false - }; - var p = params = $$.util.extend({}, defaults, params); - - return function( map ){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var eles = selfIsArrayLike ? self : self._private.elements; - - if( eles.length === 0 ){ return self; } - var cy = selfIsArrayLike ? eles[0]._private.cy : self; // NB must have at least 1 ele to get cy - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - var mapData = map[id]; - - if( mapData !== undefined && mapData !== null ){ - var obj = mapData; - var k, v; - - // set the (k, v) pairs from the map - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - ele._private[ p.field ][ k ] = v; - } - } - } // if - } // for - - // update mappers if asked - var coln = new $$.Collection(cy, eles); - if( p.updateMappers ){ coln.updateMappers(); } - - coln[ p.triggerFnName ]( p.event ); - - return self; // chaining - }; - }, - - // remove data field - removeData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: false, - immutableKeys: {} // key => true if immutable - }; - params = $$.util.extend({}, defaults, params); - - return function( names ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .removeData("foo bar") - if( $$.is.string(names) ){ // then get the list of keys, and delete them - var keys = names.split(/\s+/); - var l = keys.length; - - for( var i = 0; i < l; i++ ){ // delete each non-empty key - var key = keys[i]; - if( $$.is.emptyString(key) ){ continue; } - - var valid = !p.immutableKeys[ key ]; // not valid if immutable - if( valid ){ - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - delete all[ i_a ]._private[ p.field ][ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - - // .removeData() - } else if( names === undefined ){ // then delete all keys - - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - var _privateFields = all[ i_a ]._private[ p.field ]; - - for( var key in _privateFields ){ - var validKeyToDelete = !p.immutableKeys[ key ]; - - if( validKeyToDelete ){ - delete _privateFields[ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - } - - return self; // maintain chaining - }; // function - }, // removeData - - // event function reusable stuff - event: { - regex: /(\w+)(\.\w+)?/, // regex for matching event strings (e.g. "click.namespace") - optionalTypeRegex: /(\w+)?(\.\w+)?/, - - // properties to copy to the event obj - props: "altKey bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase metaKey offsetX offsetY originalTarget pageX pageY prevValue relatedTarget screenX screenY shiftKey target view which".split(/\s+/), - - aliases: "mousedown mouseup click mouseover mouseout mousemove touchstart touchmove touchend grab drag free".split(/\s+/), - - aliasesOn: function( thisPrototype ){ - - var aliases = $$.define.event.aliases; - for( var i = 0; i < aliases.length; i++ ){ - var eventType = aliases[i]; - - thisPrototype[ eventType ] = function(data, callback){ - if( $$.is.fn(callback) ){ - this.on(eventType, data, callback); - - } else if( $$.is.fn(data) ){ - callback = data; - this.on(eventType, callback); - - } else { - this.trigger(eventType); - } - - return this; // maintain chaining - }; - } - }, - - falseCallback: function(){ return false; } - }, - - // event binding - on: function( params ){ - var defaults = { - unbindSelfOnTrigger: false, - unbindAllBindersOnTrigger: false - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, data, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( $$.is.plainObject(selector) ){ // selector is actually data - callback = data; - data = selector; - selector = undefined; - } else if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - data = undefined; - selector = undefined; - } - - if( $$.is.fn(data) || data === false ){ // data is actually callback - callback = data; - data = undefined; - } - - // if there isn't a callback, we can't really do anything - // (can't speak for mapped events arg version) - if( !($$.is.fn(callback) || callback === false) && eventsIsString ){ - return self; // maintain chaining - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - if( !$$.is.fn(callback) ){ continue; } - - evts = evts.split(/\s+/); - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - - if( match ){ - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - var listener = { - callback: callback, // callback to run - data: data, // extra data in eventObj.data - delegated: selector ? true : false, // whether the evt is delegated - selector: selector, // the selector to match for delegated events - type: type, // the event type (e.g. "click") - namespace: namespace, // the event namespace (e.g. ".foo") - unbindSelfOnTrigger: p.unbindSelfOnTrigger, - unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger, - binders: all // who bound together - }; - - for( var j = 0; j < all.length; j++ ){ - all[j]._private.listeners.push( listener ); - } - } - } // for events array - } // for events map - - return self; // maintain chaining - }; // function - }, // on - - off: function( params ){ - var defaults = { - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( arguments.length === 0 ){ // then unbind all - - for( var i = 0; i < all.length; i++ ){ - all[i]._private.listeners = []; - } - - return self; // maintain chaining - } - - if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - selector = undefined; - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - evts = evts.split(/\s+/); - for( var h = 0; h < evts.length; h++ ){ - var evt = evts[h]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.optionalTypeRegex ); // [type][.namespace] - if( match ){ - var type = match[1] ? match[1] : undefined; - var namespace = match[2] ? match[2] : undefined; - - for( var i = 0; i < all.length; i++ ){ // - var listeners = all[i]._private.listeners; - - for( var j = 0; j < listeners.length; j++ ){ - var listener = listeners[j]; - var nsMatches = !namespace || namespace === listener.namespace; - var typeMatches = !type || listener.type === type; - var cbMatches = !callback || callback === listener.callback; - var listenerMatches = nsMatches && typeMatches && cbMatches; - - // delete listener if it matches - if( listenerMatches ){ - listeners.splice(j, 1); - j--; - } - } // for listeners - } // for all - } // if match - } // for events array - - } // for events map - - return self; // maintain chaining - }; // function - }, // off - - trigger: function( params ){ - var defaults = {}; - params = $$.util.extend({}, defaults, params); - - return function(events, extraParams, fnToTrigger){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var eventsIsObject = $$.is.plainObject(events); - var eventsIsEvent = $$.is.event(events); - var p = params; - var cy = this._private.cy || this; - - if( eventsIsString ){ // then make a plain event object for each event name - var evts = events.split(/\s+/); - events = []; - - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - events.push( { - type: type, - namespace: namespace - } ); - } - } else if( eventsIsObject ){ // put in length 1 array - var eventArgObj = events; - - events = [ eventArgObj ]; - } - - if( extraParams ){ - if( !$$.is.array(extraParams) ){ // make sure extra params are in an array if specified - extraParams = [ extraParams ]; - } - } else { // otherwise, we've got nothing - extraParams = []; - } - - for( var i = 0; i < events.length; i++ ){ // trigger each event in order - var evtObj = events[i]; - - for( var j = 0; j < all.length; j++ ){ // for each - var triggerer = all[j]; - var listeners = triggerer._private.listeners; - var triggererIsElement = $$.is.element(triggerer); - var bubbleUp = triggererIsElement; - - // create the event for this element from the event object - var evt; - - if( eventsIsEvent ){ // then just get the object - evt = evtObj; - - evt.cyTarget = evt.cyTarget || triggerer; - evt.cy = evt.cy || cy; - evt.namespace = evt.namespace || evtObj.namespace; - - } else { // then we have to make one - evt = new $$.Event( evtObj, { - cyTarget: triggerer, - cy: cy, - namespace: evtObj.namespace - } ); - - // copy properties like jQuery does - var props = $$.define.event.props; - for( var k = 0; k < props.length; k++ ){ - var prop = props[k]; - evt[ prop ] = evtObj[ prop ]; - } - } - - if( fnToTrigger ){ // then override the listeners list with just the one we specified - listeners = [{ - namespace: evt.namespace, - type: evt.type, - callback: fnToTrigger - }]; - } - - for( var k = 0; k < listeners.length; k++ ){ // check each listener - var lis = listeners[k]; - var nsMatches = !lis.namespace || lis.namespace === evt.namespace; - var typeMatches = lis.type === evt.type; - var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && $$.is.element(evt.cyTarget) && evt.cyTarget.is(lis.selector) ) : (true); // we're not going to validate the hierarchy; that's too expensive - var listenerMatches = nsMatches && typeMatches && targetMatches; - - if( listenerMatches ){ // then trigger it - var args = [ evt ]; - args = args.concat( extraParams ); // add extra params to args list - - if( lis.data ){ // add on data plugged into binding - evt.data = lis.data; - } else { // or clear it in case the event obj is reused - evt.data = undefined; - } - - if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener - listeners.splice(k, 1); - k--; - } - - if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders - var binders = lis.binders; - for( var l = 0; l < binders.length; l++ ){ - var binder = binders[l]; - if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it - - var binderListeners = binder._private.listeners; - for( var m = 0; m < binderListeners.length; m++ ){ - var binderListener = binderListeners[m]; - - if( binderListener === lis ){ // delete listener from list - binderListeners.splice(m, 1); - m--; - } - } - } - } - - // run the callback - var context = lis.delegated ? evt.cyTarget : triggerer; - var ret = lis.callback.apply( context, args ); - - if( ret === false || evt.isPropagationStopped() ){ - // then don't bubble - bubbleUp = false; - - if( ret === false ){ - // returning false is a shorthand for stopping propagation and preventing the def. action - evt.stopPropagation(); - evt.preventDefault(); - } - } - } // if listener matches - } // for each listener - - // bubble up event for elements - if( bubbleUp ){ - var parent = triggerer.parent(); - var hasParent = parent.length !== 0; - - if( hasParent ){ // then bubble up to parent - parent = parent[0]; - parent.trigger(evt); - } else { // otherwise, bubble up to the core - cy.trigger(evt); - } - } - - } // for each of all - } // for each event - - return self; // maintain chaining - }; // function - } // trigger - - }; // define - - -})( cytoscape ); - -;(function($$, window){ - - var isTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; - - $$.Style = function( cy ){ - - if( !(this instanceof $$.Style) ){ - return new $$.Style(cy); - } - - if( !$$.is.core(cy) ){ - $$.util.error("A style must have a core reference"); - return; - } - - this._private = { - cy: cy, - coreStyle: {} - }; - - this.length = 0; - - this.addDefaultStylesheet(); - }; - - // nice-to-have aliases - $$.style = $$.Style; - $$.styfn = $$.Style.prototype; - - // define functions in the Style prototype - $$.fn.style = function( fnMap, options ){ - for( var fnName in fnMap ){ - var fn = fnMap[ fnName ]; - $$.Style.prototype = fn; - } - }; - - // a dummy stylesheet object that doesn't need a reference to the core - $$.stylesheet = $$.Stylesheet = function(){ - if( !(this instanceof $$.Stylesheet) ){ - return new $$.Stylesheet(); - } - - this.length = 0; - }; - - // just store the selector to be parsed later - $$.Stylesheet.prototype.selector = function( selector ){ - var i = this.length++; - - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // just store the property to be parsed later - $$.Stylesheet.prototype.css = function( name, value ){ - var i = this.length - 1; - - if( $$.is.string(name) ){ - this[i].properties.push({ - name: name, - value: value - }); - } else if( $$.is.plainObject(name) ){ - map = name; - - for( var j = 0; j < $$.style.properties.length; j++ ){ - var prop = $$.style.properties[j]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ // also try camel case name - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - var name = prop.name; - var value = mapVal; - - this[i].properties.push({ - name: name, - value: value - }); - } - } - } - - return this; // chaining - }; - - // static function - $$.style.fromJson = function( cy, json ){ - var style = new $$.Style(cy); - - for( var i = 0; i < json.length; i++ ){ - var context = json[i]; - var selector = context.selector; - var props = context.css; - - style.selector(selector); // apply selector - - for( var name in props ){ - var value = props[name]; - - style.css( name, value ); // apply property - } - } - - return style; - }; - - $$.styfn.fromJson = function( json ){ - var style = this; - - style.resetToDefault(); - - for( var i = 0; i < json.length; i++ ){ - var context = json[i]; - var selector = context.selector; - var props = context.css; - - style.selector(selector); // apply selector - - for( var name in props ){ - var value = props[name]; - - style.css( name, value ); // apply property - } - } - - return style; - }; - - // generate a real style object from the dummy stylesheet - $$.Stylesheet.prototype.generateStyle = function( cy ){ - var style = new $$.Style(cy); - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - - return style; - }; - - $$.Stylesheet.prototype.assignToStyle = function( style, addDefaultStylesheet ){ - style.clear(); - - if( addDefaultStylesheet || addDefaultStylesheet === undefined ){ - style.addDefaultStylesheet(); - } - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - }; - - (function(){ - var number = $$.util.regex.number; - var rgba = $$.util.regex.rgbaNoBackRefs; - var hsla = $$.util.regex.hslaNoBackRefs; - var hex3 = $$.util.regex.hex3; - var hex6 = $$.util.regex.hex6; - - // each visual style property has a type and needs to be validated according to it - $$.style.types = { - zeroOneNumber: { number: true, min: 0, max: 1, unitless: true }, - nonNegativeInt: { number: true, min: 0, integer: true, unitless: true }, - size: { number: true, min: 0, enums: ["auto"] }, - bgSize: { number: true, min: 0, allowPercent: true }, - color: { color: true }, - lineStyle: { enums: ["solid", "dotted", "dashed"] }, - curveStyle: { enums: ["bundled", "bezier"] }, - fontFamily: { regex: "^([\\w- ]+(?:\\s*,\\s*[\\w- ]+)*)$" }, - fontVariant: { enums: ["small-caps", "normal"] }, - fontStyle: { enums: ["italic", "normal", "oblique"] }, - fontWeight: { enums: ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "800", "900", 100, 200, 300, 400, 500, 600, 700, 800, 900] }, - textDecoration: { enums: ["none", "underline", "overline", "line-through"] }, - textTransform: { enums: ["none", "capitalize", "uppercase", "lowercase"] }, - nodeShape: { enums: ["rectangle", "roundrectangle", "ellipse", "triangle", - "square", "pentagon", "hexagon", "heptagon", "octagon"] }, - arrowShape: { enums: ["tee", "triangle", "square", "circle", "diamond", "none"] }, - visibility: { enums: ["hidden", "visible"] }, - valign: { enums: ["top", "center", "bottom"] }, - halign: { enums: ["left", "center", "right"] }, - positionx: { enums: ["left", "center", "right"], number: true, allowPercent: true }, - positiony: { enums: ["top", "center", "bottom"], number: true, allowPercent: true }, - bgRepeat: { enums: ["repeat", "repeat-x", "repeat-y", "no-repeat"] }, - cursor: { enums: ["auto", "crosshair", "default", "e-resize", "n-resize", "ne-resize", "nw-resize", "pointer", "progress", "s-resize", "sw-resize", "text", "w-resize", "wait", "grab", "grabbing"] }, - text: { string: true }, - data: { mapping: true, regex: "^data\\s*\\(\\s*([\\w\\.]+)\\s*\\)$" }, - mapData: { mapping: true, regex: "^mapData\\(([\\w\\.]+)\\s*\\,\\s*(" + number + ")\\s*\\,\\s*(" + number + ")\\s*,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\s*\\,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\)$" }, - url: { regex: "^url\\s*\\(\\s*([^\\s]+)\\s*\\s*\\)|none|(.+)$" } - }; - - // define visual style properties - var t = $$.style.types; - $$.style.properties = [ - // these are for elements - { name: "cursor", type: t.cursor }, - { name: "text-valign", type: t.valign }, - { name: "text-halign", type: t.halign }, - { name: "color", type: t.color }, - { name: "content", type: t.text }, - { name: "text-outline-color", type: t.color }, - { name: "text-outline-width", type: t.size }, - { name: "text-outline-opacity", type: t.zeroOneNumber }, - { name: "text-opacity", type: t.zeroOneNumber }, - { name: "text-decoration", type: t.textDecoration }, - { name: "text-transform", type: t.textTransform }, - { name: "font-family", type: t.fontFamily }, - { name: "font-style", type: t.fontStyle }, - { name: "font-variant", type: t.fontVariant }, - { name: "font-weight", type: t.fontWeight }, - { name: "font-size", type: t.size }, - { name: "min-zoomed-font-size", type: t.size }, - { name: "visibility", type: t.visibility }, - { name: "opacity", type: t.zeroOneNumber }, - { name: "z-index", type: t.nonNegativeInt }, - { name: "overlay-padding", type: t.size }, - { name: "overlay-color", type: t.color }, - { name: "overlay-opacity", type: t.zeroOneNumber }, - - // these are just for nodes - { name: "background-color", type: t.color }, - { name: "background-opacity", type: t.zeroOneNumber }, - { name: "background-image", type: t.url }, - { name: "background-position-x", type: t.positionx }, - { name: "background-position-y", type: t.positiony }, - { name: "background-repeat", type: t.bgRepeat }, - { name: "background-size-x", type: t.bgSize }, - { name: "background-size-y", type: t.bgSize }, - { name: "border-color", type: t.color }, - { name: "border-opacity", type: t.zeroOneNumber }, - { name: "border-width", type: t.size }, - { name: "border-style", type: t.lineStyle }, - { name: "height", type: t.size }, - { name: "width", type: t.size }, - { name: "padding-left", type: t.size }, - { name: "padding-right", type: t.size }, - { name: "padding-top", type: t.size }, - { name: "padding-bottom", type: t.size }, - { name: "shape", type: t.nodeShape }, - - // these are just for edges - { name: "source-arrow-shape", type: t.arrowShape }, - { name: "target-arrow-shape", type: t.arrowShape }, - { name: "source-arrow-color", type: t.color }, - { name: "target-arrow-color", type: t.color }, - { name: "line-style", type: t.lineStyle }, - { name: "line-color", type: t.color }, - { name: "control-point-step-size", type: t.size }, - { name: "curve-style", type: t.curveStyle }, - - // these are just for the core - { name: "selection-box-color", type: t.color }, - { name: "selection-box-opacity", type: t.zeroOneNumber }, - { name: "selection-box-border-color", type: t.color }, - { name: "selection-box-border-width", type: t.size }, - { name: "panning-cursor", type: t.cursor }, - { name: "active-bg-color", type: t.color }, - { name: "active-bg-opacity", type: t.zeroOneNumber }, - { name: "active-bg-size", type: t.size } - ]; - - // allow access of properties by name ( e.g. $$.style.properties.height ) - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var prop = props[i]; - - props[ prop.name ] = prop; // allow lookup by name - } - })(); - - // adds the default stylesheet to the current style - $$.styfn.addDefaultStylesheet = function(){ - // to be nice, we build font related style properties from the core container - // so that cytoscape matches the style of its container by default - var fontFamily = this.containerPropertyAsString("font-family") || "sans-serif"; - var fontStyle = this.containerPropertyAsString("font-style") || "normal"; - var fontVariant = this.containerPropertyAsString("font-variant") || "normal"; - var fontWeight = this.containerPropertyAsString("font-weight") || "normal"; - var color = this.containerPropertyAsString("color") || "#000"; - var textTransform = this.containerPropertyAsString("text-transform") || "none"; - var textDecoration = this.containerPropertyAsString("text-decoration") || "none"; - var fontSize = this.containerPropertyAsString("font-size") || 12; - - // fill the style with the default stylesheet - this - .selector("node, edge") // common properties - .css({ - "cursor": "default", - "text-valign": "top", - "text-halign": "center", - "color": color, - "content": undefined, // => no label - "text-outline-color": "#000", - "text-outline-width": 0, - "text-outline-opacity": 1, - "text-opacity": 1, - "text-decoration": "none", - "text-transform": textTransform, - "font-family": fontFamily, - "font-style": fontStyle, - "font-variant": fontVariant, - "font-weight": fontWeight, - "font-size": fontSize, - "min-zoomed-font-size": 0, - "visibility": "visible", - "opacity": 1, - "z-index": 0, - "content": "", - "overlay-opacity": 0, - "overlay-color": "#000", - "overlay-padding": 10, - - // node props - "background-color": "#888", - "background-opacity": 1, - "background-image": "none", - "border-color": "#000", - "border-opacity": 1, - "border-width": 0, - "border-style": "solid", - "height": 30, - "width": 30, - "padding-top": 0, - "padding-bottom": 0, - "padding-left": 0, - "padding-right": 0, - "shape": "ellipse", - - // edge props - "source-arrow-shape": "none", - "target-arrow-shape": "none", - "source-arrow-color": "#bbb", - "target-arrow-color": "#bbb", - "line-style": "solid", - "line-color": "#bbb", - "control-point-step-size": 40, - "curve-style": "bezier" - }) - .selector("$node > node") // compound (parent) node properties - .css({ - "width": "auto", - "height": "auto", - "shape": "rectangle", - "background-opacity": 0.5, - "padding-top": 10, - "padding-right": 10, - "padding-left": 10, - "padding-bottom": 10 - }) - .selector("edge") // just edge properties - .css({ - "width": 1, - }) - .selector(":active") - .css({ - "overlay-color": "black", - "overlay-padding": 10, - "overlay-opacity": 0.25 - }) - .selector("core") // just core properties - .css({ - "selection-box-color": "#ddd", - "selection-box-opacity": 0.65, - "selection-box-border-color": "#aaa", - "selection-box-border-width": 1, - "panning-cursor": "grabbing", - "active-bg-color": "black", - "active-bg-opacity": 0.15, - "active-bg-size": isTouch ? 40 : 15 - }) - ; - }; - - // remove all contexts - $$.styfn.clear = function(){ - this._private.newStyle = true; - - for( var i = 0; i < this.length; i++ ){ - delete this[i]; - } - this.length = 0; - - return this; // chaining - }; - - $$.styfn.resetToDefault = function(){ - this.clear(); - this.addDefaultStylesheet(); - - return this; - }; - - // builds a style object for the "core" selector - $$.styfn.core = function(){ - return this._private.coreStyle; - }; - - // parse a property; return null on invalid; return parsed property otherwise - // fields : - // - name : the name of the property - // - value : the parsed, native-typed value of the property - // - strValue : a string value that represents the property value in valid css - // - bypass : true iff the property is a bypass property - $$.styfn.parse = function( name, value, propIsBypass ){ - - name = $$.util.camel2dash( name ); // make sure the property name is in dash form (e.g. "property-name" not "propertyName") - var property = $$.style.properties[ name ]; - var passedValue = value; - - if( !property ){ return null; } // return null on property of unknown name - if( value === undefined || value === null ){ return null; } // can't assign null - - var valueIsString = $$.is.string(value); - if( valueIsString ){ // trim the value to make parsing easier - value = $$.util.trim( value ); - } - - var type = property.type; - if( !type ){ return null; } // no type, no luck - - // check if bypass is null or empty string (i.e. indication to delete bypass property) - if( propIsBypass && (value === "" || value === null) ){ - return { - name: name, - value: value, - bypass: true, - deleteBypass: true - }; - } - - // check if value is mapped - var data, mapData; - if( !valueIsString ){ - // then don't bother to do the expensive regex checks - - } else if( data = new RegExp( $$.style.types.data.regex ).exec( value ) ){ - return { - name: name, - value: data, - strValue: value, - mapped: $$.style.types.data, - field: data[1], - bypass: propIsBypass - }; - - } else if( mapData = new RegExp( $$.style.types.mapData.regex ).exec( value ) ){ - // we can map only if the type is a colour or a number - if( !(type.color || type.number) ){ return false; } - - var valueMin = this.parse( name, mapData[4]); // parse to validate - if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped - - var valueMax = this.parse( name, mapData[5]); // parse to validate - if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped - - // check if valueMin and valueMax are the same - if( valueMin.value === valueMax.value ){ - return false; // can't make much of a mapper without a range - - } else if( type.color ){ - var c1 = valueMin.value; - var c2 = valueMax.value; - - var same = c1[0] === c2[0] // red - && c1[1] === c2[1] // green - && c1[2] === c2[2] // blue - && ( // optional alpha - c1[3] === c2[3] // same alpha outright - || ( - (c1[3] == null || c1[3] === 1) // full opacity for colour 1? - && - (c2[3] == null || c2[3] === 1) // full opacity for colour 2? - ) - ) - ; - - if( same ){ return false; } // can't make a mapper without a range - } - - return { - name: name, - value: mapData, - strValue: value, - mapped: $$.style.types.mapData, - field: mapData[1], - fieldMin: parseFloat( mapData[2] ), // min & max are numeric - fieldMax: parseFloat( mapData[3] ), - valueMin: valueMin.value, - valueMax: valueMax.value, - bypass: propIsBypass - }; - } - - // TODO check if value is inherited (i.e. "inherit") - - // check the type and return the appropriate object - if( type.number ){ - var units; - if( !type.unitless ){ - if( valueIsString ){ - var match = value.match( "^(" + $$.util.regex.number + ")(px|em" + (type.allowPercent ? "|\\%" : "") + ")?" + "$" ); - - if( !type.enums ){ - if( !match ){ return null; } // no match => not a number - - value = match[1]; - units = match[2] || "px"; - } - } else { - units = "px"; // implicitly px if unspecified - } - } - - value = parseFloat( value ); - - // check if this number type also accepts special keywords in place of numbers - // (i.e. `left`, `auto`, etc) - if( isNaN(value) && type.enums !== undefined ){ - value = passedValue; - - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - return null; // failed on enum after failing on number - } - - // check if value must be an integer - if( type.integer && !$$.is.integer(value) ){ - return null; - } - - // check value is within range - if( (type.min !== undefined && value < type.min) - || (type.max !== undefined && value > type.max) - ){ - return null; - } - - var ret = { - name: name, - value: value, - strValue: "" + value + (units ? units : ""), - units: units, - bypass: propIsBypass, - pxValue: type.unitless || units === "%" ? - undefined - : - ( units === "px" || !units ? (value) : (this.getEmSizeInPixels() * value) ) - }; - - return ret; - - } else if( type.color ){ - var tuple = $$.util.color2tuple( value ); - - return { - name: name, - value: tuple, - strValue: value, - bypass: propIsBypass - }; - - } else if( type.enums ){ - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - } else if( type.regex ){ - var regex = new RegExp( type.regex ); // make a regex from the type - var m = regex.exec( value ); - - if( m ){ // regex matches - return { - name: name, - value: m, - strValue: value, - bypass: propIsBypass - }; - } else { // regex doesn't match - return null; // didn't match the regex so the value is bogus - } - - } else if( type.string ){ - // just return - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - - } else { - return null; // not a type we can handle - } - - }; - - // gets what an em size corresponds to in pixels relative to a dom element - $$.styfn.getEmSizeInPixels = function(){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement ){ - var pxAsStr = window.getComputedStyle(domElement).getPropertyValue("font-size"); - var px = parseFloat( pxAsStr ); - return px; - } else { - return 1; // in case we're running outside of the browser - } - }; - - // gets css property from the core container - $$.styfn.containerCss = function( propName ){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement ){ - return window.getComputedStyle(domElement).getPropertyValue( propName ); - } - }; - - $$.styfn.containerProperty = function( propName ){ - var propStr = this.containerCss( propName ); - var prop = this.parse( propName, propStr ); - return prop; - }; - - $$.styfn.containerPropertyAsString = function( propName ){ - var prop = this.containerProperty( propName ); - - if( prop ){ - return prop.strValue; - } - }; - - // create a new context from the specified selector string and switch to that context - $$.styfn.selector = function( selectorStr ){ - // "core" is a special case and does not need a selector - var selector = selectorStr === "core" ? null : new $$.Selector( selectorStr ); - - var i = this.length++; // new context means new index - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // add one or many css rules to the current context - $$.styfn.css = function(){ - var args = arguments; - - switch( args.length ){ - case 1: - var map = args[0]; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - this.cssRule( prop.name, mapVal ); - } - } - - break; - - case 2: - this.cssRule( args[0], args[1] ); - break; - - default: - break; // do nothing if args are invalid - } - - return this; // chaining - }; - - // add a single css rule to the current context - $$.styfn.cssRule = function( name, value ){ - // name-value pair - var property = this.parse( name, value ); - - // add property to current context if valid - if( property ){ - var i = this.length - 1; - this[i].properties.push( property ); - - // add to core style if necessary - var currentSelectorIsCore = !this[i].selector; - if( currentSelectorIsCore ){ - this._private.coreStyle[ property.name ] = property; - } - } - - return this; // chaining - }; - - // apply a property to the style (for internal use) - // returns whether application was successful - // - // now, this function flattens the property, and here's how: - // - // for parsedProp:{ bypass: true, deleteBypass: true } - // no property is generated, instead the bypass property in the - // element's style is replaced by what's pointed to by the `bypassed` - // field in the bypass property (i.e. restoring the property the - // bypass was overriding) - // - // for parsedProp:{ mapped: truthy } - // the generated flattenedProp:{ mapping: prop } - // - // for parsedProp:{ bypass: true } - // the generated flattenedProp:{ bypassed: parsedProp } - $$.styfn.applyParsedProperty = function( ele, parsedProp, context ){ - parsedProp = $$.util.clone( parsedProp ); // copy b/c the same parsedProp may be applied to many elements, BUT - // the instances put in each element should be unique to avoid overwriting other the lists of other elements - - var prop = parsedProp; - var style = ele._private.style; - var fieldVal, flatProp; - var type = $$.style.properties[ prop.name ].type; - var propIsBypass = prop.bypass; - var origProp = style[ prop.name ]; - var origPropIsBypass = origProp && origProp.bypass; - - // can't apply auto to width or height unless it's a parent node - if( (parsedProp.name === "height" || parsedProp.name === "width") && parsedProp.value === "auto" && ele.isNode() && !ele.isParent() ){ - return false; - } - - // check if we need to delete the current bypass - if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete - var currentProp = style[ prop.name ]; - - // can only delete if the current prop is a bypass and it points to the property it was overriding - if( !currentProp ){ - return true; // property is already not defined - } else if( currentProp.bypass && currentProp.bypassed ){ // then replace the bypass property with the original - - // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary) - style[ prop.name ] = currentProp.bypassed; - return true; - - } else { - return false; // we're unsuccessful deleting the bypass - } - } - - // put the property in the style objects - switch( prop.mapped ){ // flatten the property if mapped - case $$.style.types.mapData: - fieldVal = ele._private.data[ prop.field ]; - if( !$$.is.number(fieldVal) ){ return false; } // it had better be a number - - var percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin); - - if( type.color ){ - var r1 = prop.valueMin[0]; - var r2 = prop.valueMax[0]; - var g1 = prop.valueMin[1]; - var g2 = prop.valueMax[1]; - var b1 = prop.valueMin[2]; - var b2 = prop.valueMax[2]; - var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3]; - var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3]; - - var clr = [ - Math.round( r1 + (r2 - r1)*percent ), - Math.round( g1 + (g2 - g1)*percent ), - Math.round( b1 + (b2 - b1)*percent ), - Math.round( a1 + (a2 - a1)*percent ) - ]; - - flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing - bypass: prop.bypass, // we're a bypass if the mapping property is a bypass - name: prop.name, - value: clr, - strValue: [ "rgba(", clr[0], ", ", clr[1], ", ", clr[2], ", ", clr[3] , ")" ].join("") // fake it til you make it - }; - - } else if( type.number ){ - var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent; - flatProp = this.parse( prop.name, calcValue, prop.bypass ); - - } else { - return false; // can only map to colours and numbers - } - - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - - break; - - case $$.style.types.data: // direct mapping - fieldVal = eval('ele._private.data.' + prop.field ); - - flatProp = this.parse( prop.name, fieldVal, prop.bypass ); - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - break; - - case undefined: - break; // just set the property - - default: - return false; // danger, will robinson - } - - // if the property is a bypass property, then link the resultant property to the original one - if( propIsBypass ){ - if( origPropIsBypass ){ // then this bypass overrides the existing one - prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass - } else { // then link the orig prop to the new bypass - prop.bypassed = origProp; - } - - style[ prop.name ] = prop; // and set - - } else { // prop is not bypass - var prevProp; - - if( origPropIsBypass ){ // then keep the orig prop (since it's a bypass) and link to the new prop - prevProp = origProp.bypassed; - - origProp.bypassed = prop; - } else { // then just replace the old prop with the new one - prevProp = style[ prop.name ]; - - style[ prop.name ] = prop; - } - - if( prevProp && prevProp.mapping && prop.mapping && prevProp.context === context ){ - prevProp = prevProp.prev; - } - - if( prevProp && prevProp !== prop ){ - prop.prev = prevProp; - } - } - - prop.context = context; - - return true; - }; - - $$.styfn.rollBackContext = function( ele, context ){ - for( var j = 0; j < context.properties.length; j++ ){ // for each prop - var prop = context.properties[j]; - var eleProp = ele._private.style[ prop.name ]; - - // because bypasses do not store prevs, look at the bypassed property - if( eleProp.bypassed ){ - eleProp = eleProp.bypassed; - } - - var first = true; - var lastEleProp; - var l = 0; - while( eleProp.prev ){ - var prev = eleProp.prev; - - if( eleProp.context === context ){ - - if( first ){ - ele._private.style[ prop.name ] = prev; - } else if( lastEleProp ){ - lastEleProp.prev = prev; - } - - } - - lastEleProp = eleProp; - eleProp = prev; - first = false; - l++; - - // in case we have a problematic prev list - // if( l >= 100 ){ - // debugger; - // } - } - } - }; - - - // (potentially expensive calculation) - // apply the style to the element based on - // - its bypass - // - what selectors match it - $$.styfn.apply = function( eles ){ - var self = this; - - for( var ie = 0; ie < eles.length; ie++ ){ - var ele = eles[ie]; - - if( self._private.newStyle ){ - ele._private.styleCxts = []; - ele._private.style = {}; - } - - // apply the styles - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var contextSelectorMatches = context.selector && context.selector.filter( ele ).length > 0; // NB: context.selector may be null for "core" - var props = context.properties; - - if( contextSelectorMatches ){ // then apply its properties - - // apply the properties in the context - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - - //if(prop.mapped) debugger; - - if( !ele._private.styleCxts[i] || prop.mapped ){ - this.applyParsedProperty( ele, prop, context ); - } - } - - // keep a note that this context matches - ele._private.styleCxts[i] = context; - } else { - - // roll back style cxts that don't match now - if( ele._private.styleCxts[i] ){ - this.rollBackContext( ele, context ); - } - - delete ele._private.styleCxts[i]; - } - } // for context - - } // for elements - - self._private.newStyle = false; - }; - - // updates the visual style for all elements (useful for manual style modification after init) - $$.styfn.update = function(){ - var cy = this._private.cy; - var eles = cy.elements(); - - eles.updateStyle(); - }; - - // gets the rendered style for an element - $$.styfn.getRenderedStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - var cy = this._private.cy; - var zoom = cy.zoom(); - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - var val = styleProp.unitless ? styleProp.strValue : (styleProp.pxValue * zoom) + "px"; - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - - return rstyle; - } - }; - - // gets the raw style for an element - $$.styfn.getRawStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - rstyle[ prop.name ] = styleProp.strValue; - rstyle[ $$.util.dash2camel(prop.name) ] = styleProp.strValue; - } - } - - return rstyle; - } - }; - - // gets the value style for an element (useful for things like animations) - $$.styfn.getValueStyle = function( ele ){ - var rstyle, style; - - if( $$.is.element(ele) ){ - rstyle = {}; - style = ele._private.style; - } else { - rstyle = {}; - style = ele; // just passed the style itself - } - - if( style ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ] || style[ $$.util.dash2camel(prop.name) ]; - - if( styleProp !== undefined && !$$.is.plainObject( styleProp ) ){ // then make a prop of it - styleProp = this.parse(prop.name, styleProp); - } - - if( styleProp ){ - var val = styleProp.value === undefined ? styleProp : styleProp.value; - - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - } - - return rstyle; - }; - - // just update the functional properties (i.e. mappings) in the elements' - // styles (less expensive than recalculation) - $$.styfn.updateFunctionalProperties = function( eles ){ - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - var style = ele._private.style; - - for( var j = 0; j < $$.style.properties.length; j++ ){ // for each prop - var prop = $$.style.properties[j]; - var propInStyle = style[ prop.name ]; - - if( propInStyle && propInStyle.mapping ){ - var mapping = propInStyle.mapping; - this.applyParsedProperty( ele, mapping ); // reapply the mapping property - } - } - } - }; - - // bypasses are applied to an existing style on an element, and just tacked on temporarily - // returns true iff application was successful for at least 1 specified property - $$.styfn.applyBypass = function( eles, name, value ){ - var props = []; - - // put all the properties (can specify one or many) in an array after parsing them - if( name === "*" || name === "**" ){ // apply to all property names - - if( value !== undefined ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - - } else if( $$.is.string(name) ){ // then parse the single property - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } else if( $$.is.plainObject(name) ){ // then parse each property - var specifiedProps = name; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = specifiedProps[ name ]; - - if( value === undefined ){ // try camel case name too - value = specifiedProps[ $$.util.dash2camel(name) ]; - } - - if( value !== undefined ){ - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - } else { // can't do anything without well defined properties - return false; - } - - // we've failed if there are no valid properties - if( props.length === 0 ){ return false; } - - // now, apply the bypass properties on the elements - var ret = false; // return true if at least one succesful bypass applied - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - - ret = this.applyParsedProperty( ele, prop ) || ret; - } - } - - return ret; - }; - - $$.styfn.removeAllBypasses = function( eles ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = ""; // empty => remove bypass - - var parsedProp = this.parse(name, value, true); - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - this.applyParsedProperty(ele, parsedProp); - } - } - }; - - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ - - var defaults = { - showOverlay: true, - hideEdgesOnViewport: false - }; - - var origDefaults = $$.util.copy( defaults ); - - $$.defaults = function( opts ){ - defaults = $$.util.extend({}, origDefaults, opts); - }; - - $$.fn.core = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - $$.Core.prototype[ name ] = fn; - } - }; - - $$.Core = function( opts ){ - if( !(this instanceof $$.Core) ){ - return new $$.Core(opts); - } - var cy = this; - - opts = $$.util.extend({}, defaults, opts); - - var container = opts.container; - var reg = $$.getRegistrationForInstance(cy, container); - if( reg && reg.cy ){ - reg.domElement.innerHTML = ''; - reg.cy.notify({ type: 'destroy' }); // destroy the renderer - - $$.removeRegistrationForInstance(reg.cy, reg.domElement); - } - - reg = $$.registerInstance( cy, container ); - var readies = reg.readies; - - var options = opts; - options.layout = $$.util.extend( { name: typeof window === 'undefined' ? "null" : "grid" }, options.layout ); - options.renderer = $$.util.extend( { name: typeof window === 'undefined' ? "null" : "canvas" }, options.renderer ); - - // TODO determine whether we need a check like this even though we allow running headless now - // - // if( !$$.is.domElement(options.container) ){ - // $$.util.error("Cytoscape.js must be called on an element"); - // return; - // } - - this._private = { - ready: false, // whether ready has been triggered - instanceId: reg.id, // the registered instance id - options: options, // cached options - elements: [], // array of elements - id2index: {}, // element id => index in elements array - listeners: [], // list of listeners - aniEles: [], // array of elements being animated - scratch: {}, // scratch object for core - layout: null, - renderer: null, - notificationsEnabled: true, // whether notifications are sent to the renderer - minZoom: 1e-50, - maxZoom: 1e50, - zoomEnabled: options.zoomEnabled === undefined ? true : options.zoomEnabled, - panEnabled: options.panEnabled === undefined ? true : options.panEnabled, - boxSelectionEnabled: options.boxSelectionEnabled === undefined ? true : options.boxSelectionEnabled, - zoom: $$.is.number(options.zoom) ? options.zoom : 1, - pan: { - x: $$.is.plainObject(options.pan) && $$.is.number(options.pan.x) ? options.pan.x : 0, - y: $$.is.plainObject(options.pan) && $$.is.number(options.pan.y) ? options.pan.y : 0, - }, - hasCompoundNodes: false - }; - - // init zoom bounds - if( $$.is.number(options.minZoom) && $$.is.number(options.maxZoom) && options.minZoom < options.maxZoom ){ - this._private.minZoom = options.minZoom; - this._private.maxZoom = options.maxZoom; - } else if( $$.is.number(options.minZoom) && options.maxZoom === undefined ){ - this._private.minZoom = options.minZoom; - } else if( $$.is.number(options.maxZoom) && options.minZoom === undefined ){ - this._private.maxZoom = options.maxZoom; - } - - // init style - this._private.style = $$.is.stylesheet(options.style) ? options.style.generateStyle(this) : ( $$.is.array(options.style) ? $$.style.fromJson(this, options.style) : new $$.Style( cy ) ); - - cy.initRenderer( $$.util.extend({ - showOverlay: options.showOverlay, - hideEdgesOnViewport: options.hideEdgesOnViewport - }, options.renderer) ); - - // initial load - cy.load(options.elements, function(){ // onready - cy.startAnimationLoop(); - cy._private.ready = true; - - // if a ready callback is specified as an option, the bind it - if( $$.is.fn( options.ready ) ){ - cy.bind("ready", options.ready); - } - - // bind all the ready handlers registered before creating this instance - for( var i = 0; i < readies.length; i++ ){ - var fn = readies[i]; - cy.bind("ready", fn); - } - reg.readies = []; // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc - - cy.trigger("ready"); - }, options.done); - }; - - $$.corefn = $$.Core.prototype; // short alias - - - $$.fn.core({ - ready: function(){ - return this._private.ready; - }, - - registered: function(){ - if( this._private && this._private.instanceId != null ){ - return true; - } else { - return false; - } - }, - - registeredId: function(){ - return this._private.instanceId; - }, - - getElementById: function( id ){ - var index = this._private.id2index[ id ]; - if( index !== undefined ){ - return this._private.elements[ index ]; - } - - // worst case, return an empty collection - return new $$.Collection( this ); - }, - - hasCompoundNodes: function(){ - return this._private.hasCompoundNodes; - }, - - addToPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var alreadyInPool = index !== undefined; - - if( !alreadyInPool ){ - index = elements.length; - elements.push( ele ) - id2index[ id ] = index; - ele._private.index = index; - } - } - - return this; // chaining - }, - - removeFromPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var inPool = index !== undefined; - - if( inPool ){ - delete this._private.id2index[ id ]; - elements.splice(index, 1); - - // adjust the index of all elements past this index - for( var j = index; j < elements.length; j++ ){ - var jid = elements[j]._private.data.id; - id2index[ jid ]--; - } - } - } - }, - - container: function(){ - return this._private.options.container; - }, - - options: function(){ - return $$.util.copy( this._private.options ); - }, - - json: function(params){ - var json = {}; - var cy = this; - - json.elements = {}; - cy.elements().each(function(i, ele){ - var group = ele.group(); - - if( !json.elements[group] ){ - json.elements[group] = []; - } - - json.elements[group].push( ele.json() ); - }); - - json.style = cy.style(); - json.scratch = cy.scratch(); - json.zoomEnabled = cy._private.zoomEnabled; - json.panEnabled = cy._private.panEnabled; - json.layout = cy._private.options.layout; - json.renderer = cy._private.options.renderer; - - return json; - } - - }); - -})( cytoscape ); - -(function($$, window){ - - $$.fn.core({ - add: function(opts){ - - var elements; - var cy = this; - - // add the elements - if( $$.is.elementOrCollection(opts) ){ - var eles = opts; - var jsons = []; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - jsons.push( ele.json() ); - } - - elements = new $$.Collection( cy, jsons ); - } - - // specify an array of options - else if( $$.is.array(opts) ){ - var jsons = opts; - - elements = new $$.Collection(cy, jsons); - } - - // specify via opts.nodes and opts.edges - else if( $$.is.plainObject(opts) && ($$.is.array(opts.nodes) || $$.is.array(opts.edges)) ){ - var elesByGroup = opts; - var jsons = []; - - var grs = ["nodes", "edges"]; - for( var i = 0, il = grs.length; i < il; i++ ){ - var group = grs[i]; - var elesArray = elesByGroup[group]; - - if( $$.is.array(elesArray) ){ - - for( var j = 0, jl = elesArray.length; j < jl; j++ ){ - var json = elesArray[j]; - - var mjson = $$.util.extend({}, json, { group: group }); - jsons.push( mjson ); - } - } - } - - elements = new $$.Collection(cy, jsons); - } - - // specify options for one element - else { - var json = opts; - elements = (new $$.Element( cy, json )).collection(); - } - - return elements.filter(function(){ - return !this.removed(); - }); - }, - - remove: function(collection){ - if( $$.is.elementOrCollection(collection) ){ - collection = collection; - } else if( $$.is.string(collection) ){ - var selector = collection; - collection = this.$( selector ); - } - - return collection.remove(); - }, - - load: function(elements, onload, ondone){ - var cy = this; - - // remove old elements - var oldEles = cy.elements(); - if( oldEles.length > 0 ){ - oldEles.remove(); - } - - cy.notifications(false); - - var processedElements = []; - - if( elements != null ){ - if( $$.is.plainObject(elements) || $$.is.array(elements) ){ - cy.add( elements ); - } - } - - function callback(){ - cy.one("layoutready", function(e){ - cy.notifications(true); - cy.trigger(e); // we missed this event by turning notifications off, so pass it on - - cy.notify({ - type: "load", - collection: cy.elements(), - style: cy._private.style - }); - - cy.one("load", onload); - cy.trigger("load"); - }).one("layoutstop", function(){ - cy.one("done", ondone); - cy.trigger("done"); - }); - - cy.layout( cy._private.options.layout ); - - } - - // TODO remove timeout when chrome reports dimensions onload properly - // TODO investigate dimensions reporting issue (also affects safari/ios) - if( true || window && window.chrome ){ - setTimeout(function(){ - callback(); - }, 30); - } else { - callback(); - } - - return this; - } - }); - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ - - $$.fn.core({ - - addToAnimationPool: function( eles ){ - var cy = this; - var aniEles = cy._private.aniEles; - var aniElesHas = []; - - for( var i = 0; i < aniEles.length; i++ ){ - var id = aniEles[i]._private.data.id; - aniElesHas[ id ] = true; - } - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - - if( !aniElesHas[id] ){ - aniEles.push( ele ); - } - } - }, - - startAnimationLoop: function(){ - var cy = this; - var stepDelay = 1000/60; - var useTimeout = false; - var useRequestAnimationFrame = true; - - // initialise the list - cy._private.aniEles = []; - - // TODO change this when standardised - var requestAnimationFrame = typeof window === 'undefined' ? function(){} : ( window.requestAnimationFrame || window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ); - - if( requestAnimationFrame == null || !useRequestAnimationFrame ){ - requestAnimationFrame = function(fn){ - window.setTimeout(function(){ - fn(+new Date); - }, stepDelay); - }; - } - - var containerDom = cy.container(); - - function globalAnimationStep(){ - function exec(){ - requestAnimationFrame(function(now){ - handleElements(now); - globalAnimationStep(); - }, containerDom); - } - - if( useTimeout ){ - setTimeout(function(){ - exec(); - }, stepDelay); - } else { - exec(); - } - } - - globalAnimationStep(); // first call - - function handleElements(now){ - now = +new Date; - - var eles = cy._private.aniEles; - for( var e = 0; e < eles.length; e++ ){ - var ele = eles[e]; - - // we might have errors if we edit animation.queue and animation.current - // for ele (i.e. by stopping) - // try{ - - var current = ele._private.animation.current; - var queue = ele._private.animation.queue; - - // if nothing currently animating, get something from the queue - if( current.length === 0 ){ - var q = queue; - var next = q.length > 0 ? q.shift() : null; - - if( next != null ){ - next.callTime = +new Date; // was queued, so update call time - current.push( next ); - } - } - - // step and remove if done - var completes = []; - for(var i = 0; i < current.length; i++){ - var ani = current[i]; - step( ele, ani, now ); - - if( current[i].done ){ - completes.push( ani ); - - // remove current[i] - current.splice(i, 1); - i--; - } - } - - // call complete callbacks - for( var i = 0; i < completes.length; i++ ){ - var ani = completes[i]; - var complete = ani.params.complete; - - if( $$.is.fn(complete) ){ - complete.apply( ele, [ now ] ); - } - } - - // } catch(e){ - // // do nothing - // } - - } // each element - - - // notify renderer - if( eles.length > 0 ){ - cy.notify({ - type: "draw", - collection: eles - }); - } - - // remove elements from list of currently animating if its queues are empty - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var queue = ele._private.animation.queue; - var current = ele._private.animation.current; - var keepEle = current.length > 0 || queue.length > 0; - - if( !keepEle ){ // then remove from the array - eles.splice(i, 1); - i--; - } - } - - } // handleElements - - function step( self, animation, now ){ - var style = cy._private.style; - var properties = animation.properties; - var params = animation.params; - var startTime = animation.callTime; - var percent; - - if( animation.duration === 0 ){ - percent = 1; - } else { - percent = Math.min(1, (now - startTime)/animation.duration); - } - - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( properties.delay == null ){ // then update the position - var startPos = animation.startPosition; - var endPos = properties.position; - var pos = self._private.position; - if( endPos ){ - if( valid( startPos.x, endPos.x ) ){ - pos.x = ease( startPos.x, endPos.x, percent ); - } - - if( valid( startPos.y, endPos.y ) ){ - pos.y = ease( startPos.y, endPos.y, percent ); - } - } - - if( properties.css ){ - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var name = props[i].name; - var end = properties.css[ name ]; - - if( end !== undefined ){ - var start = animation.startStyle[ name ]; - var easedVal = ease( start, end, percent ); - - style.applyBypass( self, name, easedVal ); - } - } // for props - } // if - } - - if( $$.is.fn(params.step) ){ - params.step.apply( self, [ now ] ); - } - - if( percent >= 1 ){ - animation.done = true; - } - - return percent; - } - - function valid(start, end){ - if( start == null || end == null ){ - return false; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return true; - } else if( (start) && (end) ){ - return true; - } - - return false; - } - - function ease(start, end, percent){ - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return start + (end - start) * percent; - - } else if( $$.is.number(start[0]) && $$.is.number(end[0]) ){ // then assume a colour - var c1 = start; - var c2 = end; - - function ch(ch1, ch2){ - var diff = ch2 - ch1; - var min = ch1; - return Math.round( percent * diff + min ); - } - - var r = ch( c1[0], c2[0] ); - var g = ch( c1[1], c2[1] ); - var b = ch( c1[2], c2[2] ); - - return 'rgb(' + r + ', ' + g + ', ' + b + ')'; - } - - return undefined; - } - - } - - }); - -})( cytoscape ); - - - - - -;(function($$){ - - $$.fn.core({ - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - }); - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - }); - - // aliases for those folks who like old stuff: - $$.corefn.bind = $$.corefn.on; - $$.corefn.unbind = $$.corefn.off; - - // add event aliases like .click() - $$.define.event.aliasesOn( $$.corefn ); - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - - png: function(){ - var cy = this; - var renderer = this._private.renderer; - - return renderer.png(); - } - - }); - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - - layout: function( params ){ - var cy = this; - - if( this._private.layoutRunning ){ // don't run another layout if one's already going - return this; - } - - // if no params, use the previous ones - if( params == null ){ - params = this._private.options.layout; - } - - this.initLayout( params ); - - cy.trigger("layoutstart"); - - this._private.layoutRunning = true; - this.one('layoutstop', function(){ - this._private.layoutRunning = false; - }); - - this._private.layout.run(); - - return this; - - }, - - initLayout: function( options ){ - if( options == null ){ - $$.util.error("Layout options must be specified to run a layout"); - return; - } - - if( options.name == null ){ - $$.util.error("A `name` must be specified to run a layout"); - return; - } - - var name = options.name; - var layoutProto = $$.extension("layout", name); - - if( layoutProto == null ){ - $$.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?", name); - return; - } - - this._private.layout = new layoutProto( $$.util.extend({}, options, { - renderer: this._private.renderer, - cy: this - }) ); - this._private.options.layout = options; // save options - } - - }); - -})( cytoscape ); - -(function($$){ - - $$.fn.core({ - notify: function( params ){ - if( !this._private.notificationsEnabled ){ return; } // exit on disabled - - var renderer = this.renderer(); - var cy = this; - - // normalise params.collection - if( $$.is.element(params.collection) ){ // make collection from element - var element = params.collection; - params.collection = new $$.Collection(cy, [ element ]); - - } else if( $$.is.array(params.collection) ){ // make collection from elements array - var elements = params.collection; - params.collection = new $$.Collection(cy, elements); - } - - renderer.notify(params); - }, - - notifications: function( bool ){ - var p = this._private; - - if( bool === undefined ){ - return p.notificationsEnabled; - } else { - p.notificationsEnabled = bool ? true : false; - } - }, - - noNotifications: function( callback ){ - this.notifications(false); - callback(); - this.notifications(true); - } - }); - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - - renderTo: function( context, zoom, pan ){ - var r = this._private.renderer; - - r.renderTo( context, zoom, pan ); - }, - - renderer: function(){ - return this._private.renderer; - }, - - initRenderer: function( options ){ - var cy = this; - - var rendererProto = $$.extension("renderer", options.name); - if( rendererProto == null ){ - $$.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?", options.name); - return; - } - - this._private.renderer = new rendererProto( - $$.util.extend({}, options, { - cy: cy, - style: cy._private.style - }) - ); - - - } - - }); - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - - // get a collection - // - empty collection on no args - // - collection of elements in the graph on selector arg - // - guarantee a returned collection when elements or collection specified - collection: function( eles ){ - - if( $$.is.string(eles) ){ - return this.$( eles ); - } else if( $$.is.elementOrCollection(eles) ){ - return eles.collection(); - } - - return new $$.Collection( this ); - }, - - nodes: function( selector ){ - var nodes = this.$("node"); - - if( selector ){ - return nodes.filter( selector ); - } - - return nodes; - }, - - edges: function( selector ){ - var edges = this.$("edge"); - - if( selector ){ - return edges.filter( selector ); - } - - return edges; - }, - - // search the graph like jQuery - $: function( selector ){ - var eles = new $$.Collection( this, this._private.elements ); - - if( selector ){ - return eles.filter( selector ); - } - - return eles; - } - - }); - - // aliases - $$.corefn.elements = $$.corefn.filter = $$.corefn.$; - -})( cytoscape ); - -;(function($$){ - - $$.fn.core({ - - style: function(val){ - return this._private.style; - } - }); - -})( cytoscape ); - - -;(function($$){ - - $$.fn.core({ - - panningEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.panEnabled = bool ? true : false; - } else { - return this._private.panEnabled; - } - - return this; // chaining - }, - - zoomingEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.zoomEnabled = bool ? true : false; - } else { - return this._private.zoomEnabled; - } - - return this; // chaining - }, - - boxSelectionEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.boxSelectionEnabled = bool ? true : false; - } else { - return this._private.boxSelectionEnabled; - } - - return this; // chaining - }, - - pan: function(){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - switch( args.length ){ - case 0: // .pan() - return pan; - - case 1: - - if( !this._private.panEnabled ){ - return this; - - } else if( $$.is.string( args[0] ) ){ // .pan("x") - dim = args[0]; - return pan[ dim ]; - - } else if( $$.is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x = x; - } - - if( $$.is.number(y) ){ - pan.y = y; - } - - this.trigger("pan"); - } - break; - - case 2: // .pan("x", 100) - if( !this._private.panEnabled ){ - return this; - } - - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] = val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - panBy: function(params){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - if( !this._private.panEnabled ){ - return this; - } - - switch( args.length ){ - case 1: - - if( $$.is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x += x; - } - - if( $$.is.number(y) ){ - pan.y += y; - } - - this.trigger("pan"); - } - break; - - case 2: // .panBy("x", 100) - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] += val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - fit: function( elements, padding ){ - if( $$.is.number(elements) && padding === undefined ){ // elements is optional - padding = elements; - elements = undefined; - } - - if( !this._private.panEnabled || !this._private.zoomEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var sel = elements; - elements = this.$( sel ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = this.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom; - padding = $$.is.number(padding) ? padding : 0; - - if( !isNaN(w) && !isNaN(h) ){ - zoom = this._private.zoom = Math.min( (w - 2*padding)/bb.w, (h - 2*padding)/bb.h ); - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - this._private.pan = { // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }; - } - - this.trigger("pan zoom"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - minZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.minZoom; - } else if( $$.is.number(zoom) ){ - this._private.minZoom = zoom; - } - - return this; - }, - - maxZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.maxZoom; - } else if( $$.is.number(zoom) ){ - this._private.maxZoom = zoom; - } - - return this; - }, - - zoom: function( params ){ - var pos; - var zoom; - - if( params === undefined ){ // then get the zoom - return this._private.zoom; - - } else if( $$.is.number(params) ){ // then set the zoom - zoom = params; - pos = { - x: 0, - y: 0 - }; - - } else if( $$.is.plainObject(params) ){ // then zoom about a point - zoom = params.level; - - if( params.renderedPosition ){ - var rpos = params.renderedPosition; - var p = this._private.pan; - var z = this._private.zoom; - - pos = { - x: (rpos.x - p.x)/z, - y: (rpos.y - p.y)/z - }; - } else if( params.position ){ - pos = params.position; - } - - if( pos && !this._private.panEnabled ){ - return this; // panning disabled - } - } - - if( !this._private.zoomEnabled ){ - return this; // zooming disabled - } - - if( !$$.is.number(zoom) || !$$.is.number(pos.x) || !$$.is.number(pos.y) ){ - return this; // can't zoom with invalid params - } - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - var pan1 = this._private.pan; - var zoom1 = this._private.zoom; - var zoom2 = zoom; - - var pan2 = { - x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x, - y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y - }; - - this._private.zoom = zoom; - this._private.pan = pan2; - - var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y; - this.trigger("zoom" + (posChanged ? " pan" : "") ); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( selector ){ - var eles = this.$( selector ); - - return eles.boundingBox(); - }, - - center: function(elements){ - if( !this._private.panEnabled || !this._private.zoomEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var selector = elements; - elements = cy.elements( selector ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = cy.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom = this._private.zoom; - - this.pan({ // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }); - - this.trigger("pan"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - reset: function(){ - if( !this._private.panEnabled || !this._private.zoomEnabled ){ - return this; - } - - this.pan({ x: 0, y: 0 }); - - if( this._private.maxZoom > 1 && this._private.minZoom < 1 ){ - this.zoom(1); - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - } - }); - -})( cytoscape ); - -;(function($$){ - - // Use this interface to define functions for collections/elements. - // This interface is good, because it forces you to think in terms - // of the collections case (more than 1 element), so we don't need - // notification blocking nonsense everywhere. - // - // Other collection-*.js files depend on this being defined first. - // It's a trade off: It simplifies the code for Collection and - // Element integration so much that it's worth it to create the - // JS dependency. - // - // Having this integration guarantees that we can call any - // collection function on an element and vice versa. - $$.fn.collection = $$.fn.eles = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - - $$.Collection.prototype[ name ] = fn; - } - }; - - // factory for generating edge ids when no id is specified for a new element - var idFactory = { - prefix: { - nodes: "n", - edges: "e" - }, - id: { - nodes: 0, - edges: 0 - }, - generate: function(cy, element, tryThisId){ - var json = $$.is.element( element ) ? element._private : element; - var group = json.group; - var id = tryThisId != null ? tryThisId : this.prefix[group] + this.id[group]; - - if( cy.getElementById(id).empty() ){ - this.id[group]++; // we've used the current id, so move it up - } else { // otherwise keep trying successive unused ids - while( !cy.getElementById(id).empty() ){ - id = this.prefix[group] + ( ++this.id[group] ); - } - } - - return id; - } - }; - - // Element - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a node or an edge - $$.Element = function(cy, params, restore){ - if( !(this instanceof $$.Element) ){ - return new $$.Element(cy, params, restore); - } - - var self = this; - restore = (restore === undefined || restore ? true : false); - - if( cy === undefined || params === undefined || !$$.is.core(cy) ){ - $$.util.error("An element must have a core reference and parameters set"); - return; - } - - // validate group - if( params.group !== "nodes" && params.group !== "edges" ){ - $$.util.error("An element must be of type `nodes` or `edges`; you specified `" + params.group + "`"); - return; - } - - // make the element array-like, just like a collection - this.length = 1; - this[0] = this; - - // NOTE: when something is added here, add also to ele.json() - this._private = { - cy: cy, - single: true, // indicates this is an element - data: params.data || {}, // data object - position: params.position || {}, // fields x, y, etc (could be 3d or radial coords; renderer decides) - autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special "auto" value - autoHeight: undefined, - listeners: [], // array of bound listeners - group: params.group, // string; "nodes" or "edges" - style: {}, // properties as set by the style - rstyle: {}, // properties for style sent from the renderer to the core - styleCxts: [], // applied style contexts from the styler - removed: true, // whether it's inside the vis; true if removed (set true here since we call restore) - selected: params.selected ? true : false, // whether it's selected - selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable - locked: params.locked ? true : false, // whether the element is locked (cannot be moved) - grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately - grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed - active: false, // whether the element is active from user interaction - classes: {}, // map ( className => true ) - animation: { // object for currently-running animations - current: [], - queue: [] - }, - rscratch: {}, // object in which the renderer can store information - scratch: {}, // scratch objects - edges: [], // array of connected edges - children: [] // array of children - }; - - // renderedPosition overrides if specified - if( params.renderedPosition ){ - var rpos = params.renderedPosition; - var pan = cy.pan(); - var zoom = cy.zoom(); - - this._private.position = { - x: (rpos.x - pan.x)/zoom, - y: (rpos.y - pan.y)/zoom - }; - } - - if( $$.is.string(params.classes) ){ - var classes = params.classes.split(/\s+/); - for( var i = 0, l = classes.length; i < l; i++ ){ - var cls = classes[i]; - if( !cls || cls === "" ){ continue; } - - self._private.classes[cls] = true; - } - } - - if( restore === undefined || restore ){ - this.restore(); - } - - }; - - - // Collection - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a set of nodes, edges, or both together - $$.Collection = function(cy, elements){ - if( !(this instanceof $$.Collection) ){ - return new $$.Collection(cy, elements); - } - - if( cy === undefined || !$$.is.core(cy) ){ - $$.util.error("A collection must have a reference to the core"); - return; - } - - var ids = {}; - var uniqueElements = []; - var createdElements = false; - - if( !elements ){ - elements = []; - } else if( elements.length > 0 && $$.is.plainObject( elements[0] ) && !$$.is.element( elements[0] ) ){ - createdElements = true; - - // make elements from json and restore all at once later - var eles = []; - var elesIds = {}; - - for( var i = 0, l = elements.length; i < l; i++ ){ - var json = elements[i]; - - if( json.data == null ){ - json.data = {}; - } - - var data = json.data; - - // make sure newly created elements have valid ids - if( data.id == null ){ - data.id = idFactory.generate( cy, json ); - } else if( cy.getElementById( data.id ).length != 0 || elesIds[ data.id ] ){ - continue; // can't create element - } - - var ele = new $$.Element( cy, json, false ); - eles.push( ele ); - elesIds[ data.id ] = true; - } - - elements = eles; - } - - for( var i = 0, l = elements.length; i < l; i++ ){ - var element = elements[i]; - if( !element ){ continue; } - - var id = element._private.data.id; - - if( !ids[ id ] ){ - ids[ id ] = element; - uniqueElements.push( element ); - } - } - - for(var i = 0, l = uniqueElements.length; i < l; i++){ - this[i] = uniqueElements[i]; - } - this.length = uniqueElements.length; - - this._private = { - cy: cy, - ids: ids - }; - - // restore the elements if we created them from json - if( createdElements ){ - this.restore(); - } - }; - - - // Functions - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // keep the prototypes in sync (an element has the same functions as a collection) - // and use $$.elefn and $$.elesfn as shorthands to the prototypes - $$.elefn = $$.elesfn = $$.Element.prototype = $$.Collection.prototype; - - $$.elesfn.cy = function(){ - return this._private.cy; - }; - - $$.elesfn.element = function(){ - return this[0]; - }; - - $$.elesfn.collection = function(){ - if( $$.is.collection(this) ){ - return this; - } else { // an element - return new $$.Collection( this._private.cy, [this] ); - } - }; - - $$.elesfn.json = function(){ - var ele = this.element(); - if( ele == null ){ return undefined } - - var p = ele._private; - - var json = $$.util.copy({ - data: p.data, - position: p.position, - group: p.group, - bypass: p.bypass, - removed: p.removed, - selected: p.selected, - selectable: p.selectable, - locked: p.locked, - grabbed: p.grabbed, - grabbable: p.grabbable, - classes: "" - }); - - var classes = []; - for( var cls in p.classes ){ - classes.push(cls); - } - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - json.classes += cls + ( i < classes.length - 1 ? " " : "" ); - } - - return json; - }; - - $$.elesfn.restore = function( notifyRenderer ){ - var self = this; - var restored = []; - var cy = self.cy(); - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // create arrays of nodes and edges, since we need to - // restore the nodes first - var elements = []; - var nodes = [], edges = []; - var numNodes = 0; - var numEdges = 0; - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - // keep nodes first in the array and edges after - if( ele.isNode() ){ // put to front of array if node - nodes.push( ele ); - numNodes++; - } else { // put to end of array if edge - edges.push( ele ); - numEdges++; - } - } - - elements = nodes.concat( edges ); - - // now, restore each element - for( var i = 0, l = elements.length; i < l; i++ ){ - var ele = elements[i]; - - if( !ele.removed() ){ - // don't need to do anything - continue; - } - - var _private = ele._private; - var data = _private.data; - - // set id and validate - if( data.id === undefined ){ - data.id = idFactory.generate( cy, ele ); - } else if( $$.is.emptyString(data.id) || !$$.is.string(data.id) ){ - // can't create element if it has empty string as id or non-string id - continue; - } else if( cy.getElementById( data.id ).length != 0 ){ - // can't create element if one already has that id - continue; - } - - var id = data.id; // id is finalised, now let's keep a ref - - if( ele.isEdge() ){ // extra checks for edges - - var edge = ele; - var fields = ["source", "target"]; - var fieldsLength = fields.length; - for(var j = 0; j < fieldsLength; j++){ - - var field = fields[j]; - var val = data[field]; - - if( val == null || val === "" ){ - // can't create if source or target is not defined properly - continue; - } else if( cy.getElementById(val).empty() ){ - // can't create edge if one of its nodes doesn't exist - continue; - } - } - - var src = cy.getElementById( data.source ); - var tgt = cy.getElementById( data.target ); - - src._private.edges.push( edge ); - tgt._private.edges.push( edge ); - - } // if is edge - - // create mock ids map for element so it can be used like collections - _private.ids = {}; - _private.ids[ data.id ] = ele; - - _private.removed = false; - cy.addToPool( ele ); - - restored.push( ele ); - } // for each element - - // do compound node sanity checks - for( var i = 0; i < numNodes; i++ ){ // each node - var node = elements[i]; - var data = node._private.data; - var id = data.id; - - var parentId = node._private.data.parent; - var specifiedParent = parentId != null; - - if( specifiedParent ){ - var parent = cy.getElementById( parentId ); - - if( parent.empty() ){ - // non-existant parent; just remove it - delete data.parent; - } else { - var selfAsParent = false; - var ancestor = parent; - while( !ancestor.empty() ){ - if( node.same(ancestor) ){ - // mark self as parent and remove from data - selfAsParent = true; - delete data.parent; // remove parent reference - - // exit or we loop forever - break; - } - - ancestor = ancestor.parent(); - } - - if( !selfAsParent ){ - // connect with children - parent[0]._private.children.push( node ); - - // let the core know we have a compound graph - cy._private.hasCompoundNodes = true; - } - } // else - } // if specified parent - } // for each node - - restored = new $$.Collection( cy, restored ); - if( restored.length > 0 ){ - - var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() ); - toUpdateStyle.updateStyle( notifyRenderer ); - - if( notifyRenderer ){ - restored.rtrigger("add"); - } else { - restored.trigger("add"); - } - } - - return self; // chainability - }; - - $$.elesfn.removed = function(){ - var ele = this[0]; - return ele && ele._private.removed; - }; - - $$.elesfn.inside = function(){ - var ele = this[0]; - return ele && !ele._private.removed; - }; - - $$.elesfn.remove = function( notifyRenderer ){ - var self = this; - var removed = []; - var elesToRemove = []; - var elesToRemoveIds = {}; - var cy = self._private.cy; - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // add connected edges - function addConnectedEdges(node){ - var edges = node._private.edges; - for( var i = 0; i < edges.length; i++ ){ - add( edges[i] ); - } - } - - - // add descendant nodes - function addChildren(node){ - var children = node._private.children; - - for( var i = 0; i < children.length; i++ ){ - add( children[i] ); - } - } - - function add( ele ){ - var alreadyAdded = elesToRemoveIds[ ele.id() ]; - if( alreadyAdded ){ - return; - } else { - elesToRemoveIds[ ele.id() ] = true; - } - - if( ele.isNode() ){ - elesToRemove.push( ele ); // nodes are removed last - - addConnectedEdges( ele ); - addChildren( ele ); - } else { - elesToRemove.unshift( ele ); // edges are removed first - } - } - - // make the list of elements to remove - // (may be removing more than specified due to connected edges etc) - - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - add( ele ); - } - - function removeEdgeRef(node, edge){ - var connectedEdges = node._private.edges; - for( var j = 0; j < connectedEdges.length; j++ ){ - var connectedEdge = connectedEdges[j]; - - if( edge === connectedEdge ){ - connectedEdges.splice( j, 1 ); - break; - } - } - } - - function removeChildRef(parent, ele){ - ele = ele[0]; - parent = parent[0]; - var children = parent._private.children; - - for( var j = 0; j < children.length; j++ ){ - if( children[j][0] === ele[0] ){ - children.splice(j, 1); - break; - } - } - } - - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - - // mark as removed - ele._private.removed = true; - - // remove from core pool - cy.removeFromPool( ele ); - - // add to list of removed elements - removed.push( ele ); - - if( ele.isEdge() ){ // remove references to this edge in its connected nodes - var src = ele.source()[0]; - var tgt = ele.target()[0]; - - removeEdgeRef( src, ele ); - removeEdgeRef( tgt, ele ); - - } else { // remove reference to parent - var parent = ele.parent(); - - if( parent.length !== 0 ){ - removeChildRef(parent, ele); - } - } - } - - // check to see if we have a compound graph or not - var elesStillInside = cy._private.elements; - cy._private.hasCompoundNodes = false; - for( var i = 0; i < elesStillInside.length; i++ ){ - var ele = elesStillInside[i]; - - if( ele.isParent() ){ - cy._private.hasCompoundNodes = true; - break; - } - } - - var removedElements = new $$.Collection( this.cy(), removed ); - if( removedElements.size() > 0 ){ - // must manually notify since trigger won't do this automatically once removed - - if( notifyRenderer ){ - this.cy().notify({ - type: "remove", - collection: removedElements - }); - } - - removedElements.trigger("remove"); - } - - // check for empty remaining parent nodes - var checkedParentId = {}; - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - var isNode = ele._private.group === "nodes"; - var parentId = ele._private.data.parent; - - if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){ - checkedParentId[ parentId ] = true; - var parent = cy.getElementById( parentId ); - - if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){ - parent.updateStyle(); - } - } - } - - return this; - }; - -})( cytoscape ); - - -;(function( $$ ){ - - $$.fn.eles({ - animated: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.animation.current.length > 0; - } - }, - - clearQueue: function(){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - ele._private.animation.queue = []; - } - - return this; - }, - - delay: function( time, complete ){ - this.animate({ - delay: time - }, { - duration: time, - complete: complete - }); - - return this; - }, - - animate: function( properties, params ){ - var callTime = +new Date; - var cy = this._private.cy; - var style = cy.style(); - var q; - - if( params === undefined ){ - params = {}; - } - - if( params.duration === undefined ){ - params.duration = 400; - } - - switch( params.duration ){ - case "slow": - params.duration = 600; - break; - case "fast": - params.duration = 200; - break; - } - - if( properties == null || (properties.position == null && properties.css == null && properties.delay == null) ){ - return this; // nothing to animate - } - - if( properties.css ){ - properties.css = style.getValueStyle( properties.css ); - } - - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - - var pos = self._private.position; - var startPosition = { - x: pos.x, - y: pos.y - }; - var startStyle = style.getValueStyle( self ); - - if( self.animated() && (params.queue === undefined || params.queue) ){ - q = self._private.animation.queue; - } else { - q = self._private.animation.current; - } - - q.push({ - properties: properties, - duration: params.duration, - params: params, - callTime: callTime, - startPosition: startPosition, - startStyle: startStyle - }); - } - - cy.addToAnimationPool( this ); - - return this; // chaining - }, // animate - - stop: function(clearQueue, jumpToEnd){ - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - var anis = self._private.animation.current; - - for( var j = 0; j < anis.length; j++ ){ - var animation = anis[j]; - if( jumpToEnd ){ - // next iteration of the animation loop, the animation - // will go straight to the end and be removed - animation.duration = 0; - } - } - - // clear the queue of future animations - if( clearQueue ){ - self._private.animation.queue = []; - } - } - - // we have to notify (the animation loop doesn't do it for us on `stop`) - this.cy().notify({ - collection: this, - type: "draw" - }); - - return this; - } - }); - -})( cytoscape ); - -;(function( $$ ){ - - $$.fn.eles({ - addClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - if( $$.is.emptyString(cls) ){ continue; } - - for( var j = 0; j < self.length; j++ ){ - var ele = self[j]; - var hasClass = ele._private.classes[cls]; - ele._private.classes[cls] = true; - - if( !hasClass ){ // if didn't already have, add to list of changed - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - hasClass: function(className){ - var ele = this[0]; - return ele != null && ele._private.classes[className]; - }, - - toggleClass: function(classesStr, toggle){ - var classes = classesStr.split(/\s+/); - var self = this; - var changed = []; // eles who had classes changed - - for( var i = 0, il = self.length; i < il; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - - if( $$.is.emptyString(cls) ){ continue; } - - var hasClass = ele._private.classes[cls]; - var shouldAdd = toggle || (toggle === undefined && !hasClass); - - if( shouldAdd ){ - ele._private.classes[cls] = true; - - if( !hasClass ){ changed.push(ele); } - } else { // then remove - ele._private.classes[cls] = false; - - if( hasClass ){ changed.push(ele); } - } - - } // for j classes - } // for i eles - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - removeClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < self.length; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - if( !cls || cls === "" ){ continue; } - - var hasClass = ele._private.classes[cls]; - delete ele._private.classes[cls]; - - if( hasClass ){ // then we changed its set of classes - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(self._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - } - }); - -})( cytoscape ); - -;(function($$){ - - $$.fn.eles({ - allAre: function(selector){ - return this.filter(selector).length === this.length; - }, - - is: function(selector){ - return this.filter(selector).length > 0; - }, - - same: function( collection ){ - collection = this.cy().collection( collection ); - - // cheap extra check - if( this.length !== collection.length ){ - return false; - } - - return this.intersect( collection ).length === this.length; - }, - - anySame: function(collection){ - collection = this.cy().collection( collection ); - - return this.intersect( collection ).length > 0; - }, - - allAreNeighbors: function(collection){ - collection = this.cy().collection( collection ); - - return this.neighborhood().intersect( collection ).length === collection.length; - } - }); - -})( cytoscape ); - -;(function($$){ - - var borderWidthMultiplier = 1.4; - var borderWidthAdjustment = 1; - - $$.fn.eles({ - - // fully updates (recalculates) the style for the elements - updateStyle: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - style.apply( this ); - - if( notifyRenderer ){ - this.rtrigger("style"); // let renderer know we changed style - } else { - this.trigger("style"); // just fire the event - } - return this; // chaining - }, - - // just update the mappers in the elements' styles; cheaper than eles.updateStyle() - updateMappers: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - style.apply( ele ); - } - - if( notifyRenderer ){ - this.rtrigger("style"); // let renderer know we changed style - } else { - this.trigger("style"); // just fire the event - } - return this; // chaining - }, - - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - - rscratch: $$.define.data({ - field: "rscratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeRscratch: $$.define.removeData({ - field: "rscratch", - triggerEvent: false - }), - - id: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.id; - } - }, - - position: $$.define.data({ - field: "position", - bindingEvent: "position", - allowBinding: true, - allowSetting: true, - settingEvent: "position", - settingTriggersEvent: true, - triggerFnName: "rtrigger", - allowGetting: true, - validKeys: ["x", "y"] - }), - - positions: function( pos ){ - if( $$.is.plainObject(pos) ){ - this.position(pos); - - } else if( $$.is.fn(pos) ){ - var fn = pos; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - var pos = fn.apply(ele, [i, ele]); - - if( pos && !ele.locked() ){ - var elePos = ele._private.position; - elePos.x = pos.x; - elePos.y = pos.y; - } - } - - this.rtrigger("position"); - } - - return this; // chaining - }, - - // get the rendered (i.e. on screen) positon of the element - // TODO allow setting - renderedPosition: function( dim ){ - var ele = this[0]; - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - - if( ele && ele.isNode() ){ // must have an element and must be a node to return position - var pos = ele._private.position; - var rpos = { - x: pos.x * zoom + pan.x, - y: pos.y * zoom + pan.y - }; - - if( dim === undefined ){ // then return the whole rendered position - return rpos; - } else { // then return the specified dimension - return rpos[ dim ]; - } - } - }, - - // get the specified css property as a rendered value (i.e. on-screen value) - // or get the whole rendered style if no property specified (NB doesn't allow setting) - renderedCss: function( property ){ - var ele = this[0]; - - if( ele ){ - var renstyle = ele.cy().style().getRenderedStyle( ele ); - - if( property === undefined ){ - return renstyle; - } else { - return renstyle[ property ]; - } - } - }, - - // read the calculated css style of the element or override the style (via a bypass) - css: function( name, value ){ - var style = this.cy().style(); - - if( $$.is.plainObject(name) ){ // then extend the bypass - var props = name; - style.applyBypass( this, props ); - this.rtrigger("style"); // let the renderer know we've updated style - - } else if( $$.is.string(name) ){ - - if( value === undefined ){ // then get the property from the style - var ele = this[0]; - - if( ele ){ - return ele._private.style[ name ].strValue; - } else { // empty collection => can't get any value - return; - } - - } else { // then set the bypass with the property value - style.applyBypass( this, name, value ); - this.rtrigger("style"); // let the renderer know we've updated style - } - - } else if( name === undefined ){ - var ele = this[0]; - - if( ele ){ - return style.getRawStyle( ele ); - } else { // empty collection => can't get any value - return; - } - } - - return this; // chaining - }, - - removeCss: function(){ - var style = this.cy().style(); - var eles = this; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - style.removeAllBypasses( ele ); - } - - this.rtrigger('style'); - }, - - show: function(){ - this.css("visibility", "visible"); - return this; // chaining - }, - - hide: function(){ - this.css("visibility", "hidden"); - return this; // chaining - }, - - visible: function(){ - var ele = this[0]; - - if( ele ){ - if( ele.css("visibility") !== "visible" ){ - return false; - } - - if( ele.isNode() ){ - var parents = ele.parents(); - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var parentVisibility = parent.css("visibility"); - - if( parentVisibility !== "visible" ){ - return false; - } - } - - return true; - } else if( ele.isEdge() ){ - var src = ele.source(); - var tgt = ele.target(); - - return src.visible() && tgt.visible(); - } - - } - }, - - hidden: function(){ - var ele = this[0]; - - if( ele ){ - return !this.visible(); - } - }, - - // convenience function to get a numerical value for the width of the node/edge - width: function(){ - var ele = this[0]; - - if( ele ){ - var w = this._private.style.width; - return w.strValue === "auto" ? ele._private.autoWidth : w.pxValue; - } - }, - - outerWidth: function(){ - var ele = this[0]; - - if( ele ){ - var style = this._private.style; - var width = style.width.strValue === "auto" ? ele._private.autoWidth : style.width.pxValue;; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return width + border; - } - }, - - renderedWidth: function(){ - var ele = this[0]; - - if( ele ){ - var width = this.width(); - return width * this.cy().zoom(); - } - }, - - renderedOuterWidth: function(){ - var ele = this[0]; - - if( ele ){ - var owidth = this.outerWidth(); - return owidth * this.cy().zoom(); - } - }, - - // convenience function to get a numerical value for the height of the node - height: function(){ - var ele = this[0]; - - if( ele && ele.isNode() ){ - var h = this._private.style.height; - return h.strValue === "auto" ? ele._private.autoHeight : h.pxValue; - } - }, - - outerHeight: function(){ - var ele = this[0]; - - if( ele ){ - var style = this._private.style; - var height = style.height.strValue === "auto" ? ele._private.autoHeight : style.height.pxValue; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return height + border; - } - }, - - renderedHeight: function(){ - var ele = this[0]; - - if( ele ){ - var height = this.height(); - return height * this.cy().zoom(); - } - }, - - renderedOuterHeight: function(){ - var ele = this[0]; - - if( ele ){ - var oheight = this.outerHeight(); - return oheight * this.cy().zoom(); - } - }, - - // get the position of the element relative to the container (i.e. not relative to parent node) - offset: function(){ - var ele = this[0]; - - if( ele && ele.isNode() ){ - var offset = { - x: ele._private.position.x, - y: ele._private.position.y - }; - - var parents = ele.parents(); - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var parentPos = parent._private.position; - - offset.x += parentPos.x; - offset.y += parentPos.y; - } - - return offset; - } - }, - - renderedOffset: function(){ - var ele = this[0]; - - if( ele && ele.isNode() ){ - var offset = this.offset(); - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - - return { - x: offset.x * zoom + pan.x, - y: offset.y * zoom + pan.y - }; - } - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( selector ){ - var eles = this; - - if( !selector || ( $$.is.elementOrCollection(selector) && selector.length === 0 ) ){ - eles = this; - } else if( $$.is.string(selector) ){ - eles = this.filter( selector ); - } else if( $$.is.elementOrCollection(selector) ){ - eles = selector; - } - - var x1 = Infinity; - var x2 = -Infinity; - var y1 = Infinity; - var y2 = -Infinity; - - // find bounds of elements - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var ex1, ex2, ey1, ey2, x, y; - - if( ele.isNode() ){ - var pos = ele._private.position; - x = pos.x; - y = pos.y; - var w = ele.outerWidth(); - var halfW = w/2; - var h = ele.outerHeight(); - var halfH = h/2; - - // handle node dimensions - ///////////////////////// - - ex1 = x - halfW; - ex2 = x + halfW; - ey1 = y - halfH; - ey2 = y + halfH; - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - } else { // is edge - var n1pos = ele.source()[0]._private.position; - var n2pos = ele.target()[0]._private.position; - - // handle edge dimensions (rough box estimate) - ////////////////////////////////////////////// - - var rstyle = ele._private.rstyle; - x = rstyle.labelX; - y = rstyle.labelY; - - ex1 = n1pos.x; - ex2 = n2pos.x; - ey1 = n1pos.y; - ey2 = n2pos.y; - - if( ex1 > ex2 ){ - var temp = ex1; - ex1 = ex2; - ex2 = temp; - } - - if( ey1 > ey2 ){ - var temp = ey1; - ey1 = ey2; - ey2 = temp; - } - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - // handle points along edge (sanity check) - ////////////////////////////////////////// - - var bpts = rstyle.bezierPts || []; - var w = ele._private.style['width'].value; - for( var j = 0; j < bpts.length; j++ ){ - var bpt = bpts[j]; - - x1 = bpt.x - w < x1 ? bpt.x - w : x1; - x2 = bpt.x + w > x2 ? bpt.x + w : x2; - y1 = bpt.y - w < y1 ? bpt.y - w : y1; - y2 = bpt.y + w > y2 ? bpt.y + w : y2; - } - - } - - // handle label dimensions - ////////////////////////// - - var style = ele._private.style; - var label = style['content'].value; - var fontSize = style['font-size']; - var halign = style['text-halign']; - var valign = style['text-valign']; - var labelWidth = ele._private.rstyle.labelWidth; - - if( label && fontSize && labelWidth != undefined && halign && valign ){ - var lh = fontSize.value; - var lw = labelWidth; - var lx1, lx2, ly1, ly2; - - switch( halign.value ){ - case "left": - lx1 = ex1 - lw; - lx2 = ex1; - break; - - case "center": - lx1 = x - lw/2; - lx2 = x + lw/2; - break; - - case "right": - lx1 = ex2; - lx2 = ex2 + lw; - break; - } - - if( ele.isEdge() ){ // force center case - lx1 = x - lw/2; - lx2 = x + lw/2; - } - - switch( valign.value ){ - case "top": - ly1 = ey1 - lh; - ly2 = ey1; - break; - - case "center": - ly1 = y - lh/2; - ly2 = y + lh/2; - break; - - case "bottom": - ly1 = ey2; - ly2 = ey2 + lh; - break; - } - - if( ele.isEdge() ){ // force center case - ly1 = y - lh/2; - ly2 = y + lh/2; - } - - x1 = lx1 < x1 ? lx1 : x1; - x2 = lx2 > x2 ? lx2 : x2; - y1 = ly1 < y1 ? ly1 : y1; - y2 = ly2 > y2 ? ly2 : y2; - } - } // for - - // testing on debug page - // $('#bb').remove(); - // $('#cytoscape').css('position', 'relative').append('
                      '); - // $('#bb').css({ - // 'position': 'absolute', - // 'left': x1, - // 'top': y1, - // 'width': x2 - x1, - // 'height': y2 - y1, - // 'background': 'rgba(255, 0, 0, 0.5)' - // }) - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2, - w: x2 - x1, - h: y2 - y1 - }; - } - }); - - -})( cytoscape ); - -;(function( $$ ){ - - // Regular degree functions (works on single element) - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeFunction(callback){ - return function(){ - var self = this; - - if( self.length === 0 ){ return; } - - if( self.isNode() && !self.removed() ){ - var degree = 0; - var node = self[0]; - var connectedEdges = node._private.edges; - - for( var i = 0; i < connectedEdges.length; i++ ){ - var edge = connectedEdges[i]; - degree += callback( node, edge ); - } - - return degree; - } else { - return; - } - }; - } - - $$.fn.eles({ - degree: defineDegreeFunction(function(node, edge){ - if( edge.source().same( edge.target() ) ){ - return 2; - } else { - return 1; - } - }), - - indegree: defineDegreeFunction(function(node, edge){ - if( edge.target().same(node) ){ - return 1; - } else { - return 0; - } - }), - - outdegree: defineDegreeFunction(function(node, edge){ - if( edge.source().same(node) ){ - return 1; - } else { - return 0; - } - }) - }); - - - // Collection degree stats - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeBoundsFunction(degreeFn, callback){ - return function(){ - var ret = undefined; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - var degree = ele[degreeFn](); - if( degree !== undefined && (ret === undefined || callback(degree, ret)) ){ - ret = degree; - } - } - - return ret; - }; - } - - $$.fn.eles({ - minDegree: defineDegreeBoundsFunction("degree", function(degree, min){ - return degree < min; - }), - - maxDegree: defineDegreeBoundsFunction("degree", function(degree, max){ - return degree > max; - }), - - minIndegree: defineDegreeBoundsFunction("indegree", function(degree, min){ - return degree < min; - }), - - maxIndegree: defineDegreeBoundsFunction("indegree", function(degree, max){ - return degree > max; - }), - - minOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, min){ - return degree < min; - }), - - maxOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, max){ - return degree > max; - }) - }); - - $$.fn.eles({ - totalDegree: function(){ - var total = 0; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - total += nodes[i].degree(); - } - - return total; - } - }); - -})( cytoscape ); - - - -;(function($$){ - - // Functions for binding & triggering events - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - - rtrigger: function(event, extraParams){ // for internal use only - // notify renderer unless removed - this.cy().notify({ - type: event, - collection: this.filter(function(){ - return !this.removed(); - }) - }); - - this.trigger(event, extraParams); - return this; - } - }); - - // aliases for those folks who like old stuff: - $$.elesfn.bind = $$.elesfn.on; - $$.elesfn.unbind = $$.elesfn.off; - - // add event aliases like .click() - $$.define.event.aliasesOn( $$.elesfn ); - -})( cytoscape ); - -;(function($$){ - - $$.fn.eles({ - isNode: function(){ - return this.group() === "nodes"; - }, - - isEdge: function(){ - return this.group() === "edges"; - }, - - isLoop: function(){ - return this.isEdge() && this.source().id() === this.target().id(); - }, - - group: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.group; - } - } - }); - - -})( cytoscape ); - -;(function($$){ - - // Functions for iterating over collections - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - each: function(fn){ - if( $$.is.fn(fn) ){ - for(var i = 0; i < this.length; i++){ - var ele = this[i]; - var ret = fn.apply( ele, [ i, ele ] ); - - if( ret === false ){ break; } // exit each early on return false - } - } - return this; - }, - - toArray: function(){ - var array = []; - - for(var i = 0; i < this.length; i++){ - array.push( this[i] ); - } - - return array; - }, - - slice: function(start, end){ - var array = []; - var thisSize = this.length; - - if( end == null ){ - end = thisSize; - } - - if( start < 0 ){ - start = thisSize + start; - } - - for(var i = start; i >= 0 && i < end && i < thisSize; i++){ - array.push( this[i] ); - } - - return new $$.Collection(this.cy(), array); - }, - - size: function(){ - return this.length; - }, - - eq: function(i){ - return this[i]; - }, - - empty: function(){ - return this.length === 0; - }, - - nonempty: function(){ - return !this.empty(); - } - }); - -})( cytoscape ); - -;(function($$){ - - // Collection functions that toggle a boolean value - //////////////////////////////////////////////////////////////////////////////////////////////////// - - - function defineSwitchFunction(params){ - return function(){ - var args = arguments; - - // e.g. cy.nodes().select( data, handler ) - if( args.length === 2 ){ - var data = args[0]; - var handler = args[1]; - this.bind( params.event, data, handler ); - } - - // e.g. cy.nodes().select( handler ) - else if( args.length === 1 ){ - var handler = args[0]; - this.bind( params.event, handler ); - } - - // e.g. cy.nodes().select() - else if( args.length === 0 ){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( !params.ableField || ele._private[params.ableField] ){ - ele._private[params.field] = params.value; - } - } - this.updateStyle(); // change of state => possible change of style - this.trigger(params.event); - } - - return this; - }; - } - - function defineSwitchSet( params ){ - $$.elesfn[ params.field ] = function(){ - var ele = this[0]; - if( ele ){ - return ele._private[ params.field ]; - } - }; - - $$.elesfn[ params.on ] = defineSwitchFunction({ - event: params.on, - field: params.field, - ableField: params.ableField, - value: true - }); - - $$.elesfn[ params.off ] = defineSwitchFunction({ - event: params.off, - field: params.field, - ableField: params.ableField, - value: false - }); - } - - defineSwitchSet({ - field: "locked", - on: "lock", - off: "unlock" - }); - - defineSwitchSet({ - field: "grabbable", - on: "grabify", - off: "ungrabify" - }); - - defineSwitchSet({ - field: "selected", - ableField: "selectable", - on: "select", - off: "unselect" - }); - - defineSwitchSet({ - field: "selectable", - on: "selectify", - off: "unselectify" - }); - - $$.elesfn.grabbed = function(){ - var ele = this[0]; - if( ele ){ - return ele._private.grabbed; - } - }; - - defineSwitchSet({ - field: "active", - on: "activate", - off: "unactivate" - }); - - $$.elesfn.inactive = function(){ - var ele = this[0]; - if( ele ){ - return !ele._private.active; - } - }; - -})( cytoscape ); - -;(function($$){ - - $$.fn.eles({ - nodes: function(selector){ - return this.filter(function(i, element){ - return element.isNode(); - }).filter(selector); - }, - - edges: function(selector){ - return this.filter(function(i, element){ - return element.isEdge(); - }).filter(selector); - }, - - filter: function(filter){ - var cy = this._private.cy; - - if( $$.is.fn(filter) ){ - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( filter.apply(ele, [i, ele]) ){ - elements.push(ele); - } - } - - return new $$.Collection(cy, elements); - - } else if( $$.is.string(filter) || $$.is.elementOrCollection(filter) ){ - return new $$.Selector(filter).filter(this); - - } else if( filter === undefined ){ - return this; - } - - return new $$.Collection( cy ); // if not handled by above, give 'em an empty collection - }, - - not: function(toRemove){ - var cy = this._private.cy; - - if( !toRemove ){ - return this; - } else { - - if( $$.is.string( toRemove ) ){ - toRemove = this.filter( toRemove ); - } - - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var element = this[i]; - - var remove = toRemove._private.ids[ element.id() ]; - if( !remove ){ - elements.push( element ); - } - } - - return new $$.Collection( cy, elements ); - } - - }, - - intersect: function( other ){ - var self = this; - var cy = this._private.cy; - - // if a selector is specified, then filter by it - if( $$.is.string(other) ){ - var selector = other; - return this.filter( selector ); - } - - var elements = []; - var col1 = this; - var col2 = other; - var col1Smaller = this.length < other.length; - var ids1 = col1Smaller ? col1._private.ids : col2._private.ids; - var ids2 = col1Smaller ? col2._private.ids : col1._private.ids; - - for( var id in ids1 ){ - var ele = ids2[ id ]; - - if( ele ){ - elements.push( ele ); - } - } - - return new $$.Collection( cy, elements ); - }, - - add: function(toAdd){ - var self = this; - var cy = this._private.cy; - - if( !toAdd ){ - return this; - } - - if( $$.is.string(toAdd) ){ - var selector = toAdd; - toAdd = cy.elements(selector); - } - - var elements = []; - var ids = {}; - - function add(element){ - if( !element ){ - return; - } - - if( !ids[ element.id() ] ){ - elements.push( element ); - ids[ element.id() ] = true; - } - } - - // add own - for( var i = 0; i < self.length; i++ ){ - var element = self[i]; - add(element); - } - - // add toAdd - for( var i = 0; i < toAdd.length; i++ ){ - var element = toAdd[i]; - add(element); - } - - return new $$.Collection(cy, elements); - } - }); - - $$.fn.eles({ - // do a breadth first search from the nodes in the collection - // from pseudocode on wikipedia - breadthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var Q = []; - var marked = {}; - var id2depth = {}; - var connectedFrom = {}; - var connectedEles = []; - - // enqueue v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - Q.unshift( v[i] ); - - // and mark v - marked[ v[i].id() ] = true; - - id2depth[ v[i].id() ] = 0; - - connectedEles.push( v[i] ); - } - } - - i = 0; - while( Q.length !== 0 ){ // while Q not empty - var t = Q.shift(); - var depth = 0; - - var fromNodeId = connectedFrom[ t.id() ]; - while( fromNodeId ){ - depth++; - fromNodeId = connectedFrom[ fromNodeId ]; - } - - id2depth[ t.id() ] = depth; - var ret = fn.call(t, i, depth); - i++; - - // on return true, return the result - if( ret === true ){ - return new $$.Collection( cy, [ t ] ); - } - - // on return false, stop iteration - else if( ret === false ){ - break; - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - - for( var j = 0; j < adjacentEdges.length; j++ ){ - var e = adjacentEdges[j]; - var u = e.connectedNodes('[id != "' + t.id() + '"]'); - - if( u.length !== 0 ){ - u = u[0]; - - if( !marked[ u.id() ] ){ - marked[ u.id() ] = true; // mark u - Q.unshift( u ); // enqueue u onto Q - - connectedFrom[ u.id() ] = t.id(); - - connectedEles.push( u ); - connectedEles.push( e ); - } - } - } - } - - return new $$.Collection( cy, connectedEles ); // return none - }, - - // do a depth first search on the nodes in the collection - // from pseudocode on wikipedia (iterative impl) - depthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var S = []; - var discovered = []; - var forwardEdge = {}; - var backEdge = {}; - var crossEdge = {}; - var treeEdge = {}; - var explored = {}; - - function labelled(e){ - var id = e.id(); - return forwardEdge[id] || backEdge[id] || crossEdge[id] || treeEdge[id]; - } - - // push v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - S.push( v[i] ); - - // and mark discovered - discovered[ v[i].id() ] = true; - } - } - - while( S.length !== 0 ){ - var t = S[ S.length - 1 ]; - var ret = fn.call(t); - var breaked = false; - - if( ret === true ){ - return new $$.Collection( cy, [t] ); - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - for( var i = 0; i < adjacentEdges.length; i++ ){ - var e = adjacentEdges[i]; - - if( labelled(e) ){ - continue; - } - - var w = e.connectedNodes('[id != "' + t.id() + '"]'); - if( w.length !== 0 ){ - w = w[0]; - var wid = w.id(); - - if( !discovered[wid] && !explored[wid] ){ - treeEdge[wid] = true; - discovered[wid] = true; - S.push(w); - breaked = true; - break; - } else if( discovered[wid] ){ - backEdge[wid] = true; - } else { - crossEdge[wid] = true; - } - } - } - - if( !breaked ){ - explored[ t.id() ] = true; - S.pop(); - } - } - }, - - // get the root nodes in the DAG - roots: function( selector ){ - var eles = this; - var roots = []; - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - if( !ele.isNode() ){ - continue; - } - - var hasEdgesPointingIn = ele.connectedEdges('[target = "' + ele.id() + '"][source != "' + ele.id() + '"]').length > 0; - - if( !hasEdgesPointingIn ){ - roots.push( ele ); - } - } - - return new $$.Collection( this._private.cy, roots ).filter( selector ); - }, - - // kruskal's algorithm (finds min spanning tree, assuming undirected graph) - // implemented from pseudocode from wikipedia - kruskal: function( weightFn ){ - weightFn = weightFn || function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - function findSet(ele){ - for( var i = 0; i < forest.length; i++ ){ - var eles = forest[i]; - - if( eles.anySame(ele) ){ - return { - eles: eles, - index: i - }; - } - } - } - - var A = new $$.Collection(this._private.cy, []); - var forest = []; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - forest.push( nodes[i].collection() ); - } - - var edges = this.edges(); - var S = edges.toArray().sort(function(a, b){ - var weightA = weightFn.call(a); - var weightB = weightFn.call(b); - - return weightA - weightB; - }); - - for(var i = 0; i < S.length; i++){ - var edge = S[i]; - var u = edge.source()[0]; - var v = edge.target()[0]; - var setU = findSet(u); - var setV = findSet(v); - - if( setU.eles !== setV.eles ){ - A = A.add( edge ); - - forest[ setU.index ] = setU.eles.add( setV.eles ); - forest.splice( setV.index, 1 ); - } - } - - return nodes.add( A ); - - }, - - dijkstra: function( target, weightFn, directed ){ - var cy = this._private.cy; - directed = !$$.is.fn(weightFn) ? weightFn : directed; - directed = directed === undefined || directed; - weightFn = $$.is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - if( this.length === 0 || !target || !$$.is.elementOrCollection(target) || target.length === 0 ){ - return new $$.Collection(cy, []); - } - - var source = this[0]; - target = target[0]; - var dist = {}; - var prev = {}; - - var nodes = cy.nodes(); - for( var i = 0; i < nodes.length; i++ ){ - dist[ nodes[i].id() ] = Infinity; - } - - dist[ source.id() ] = 0; - var Q = nodes; - - var smallestDist = function(Q){ - var smallest = Infinity; - var index; - for(var i in dist){ - if( dist[i] < smallest && Q.$('#' + i).length !== 0 ){ - smallest = dist[i]; - index = i; - } - } - - return index; - }; - - var distBetween = function(u, v){ - var edges = u.edgesWith(v); - var smallestDistance = Infinity; - var smallestEdge; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var weight = weightFn.call(edge); - - if( weight < smallestDistance ){ - smallestDistance = weight; - smallestEdge = edge; - } - } - - return { - edge: smallestEdge, - dist: smallestDistance - }; - }; - - while( Q.length !== 0 ){ - var uid = smallestDist(Q); - var u = Q.filter('#' + uid); - - if( u.length === 0 ){ - continue; - } - - //debugger; - - Q = Q.not( u ); - - if( u.same(target) ){ - break; - } - - if( dist[uid] === Math.Infinite ){ - break; - } - - var neighbors = u.neighborhood().nodes(); - for( var i = 0; i < neighbors.length; i++ ){ - var v = neighbors[i]; - var vid = v.id() - - var duv = distBetween(u, v); - var alt = dist[uid] + duv.dist; - if( alt < dist[vid] ){ - dist[vid] = alt; - prev[vid] = { - node: v, - edge: duv.edge - }; - // TODO decrease-key v in Q - } - } - } - } - }); - - // nice, short mathemathical alias - $$.elesfn.bfs = $$.elesfn.breadthFirstSearch; - $$.elesfn.dfs = $$.elesfn.depthFirstSearch; - - - - // Neighbourhood functions - ////////////////////////// - - $$.fn.eles({ - neighborhood: function(selector){ - var elements = []; - var cy = this._private.cy; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ // for all nodes - var node = nodes[i]; - var connectedEdges = node.connectedEdges(); - - // for each connected edge, add the edge and the other node - for( var j = 0; j < connectedEdges.length; j++ ){ - var edge = connectedEdges[j]; - var otherNode = edge.connectedNodes().not(node); - - // need check in case of loop - if( otherNode.length > 0 ){ - elements.push( otherNode[0] ); // add node 1 hop away - } - - // add connected edge - elements.push( edge[0] ); - } - - } - - return ( new $$.Collection( cy, elements ) ).filter( selector ); - }, - - closedNeighborhood: function(selector){ - return this.neighborhood().add(this).filter(selector); - }, - - openNeighborhood: function(selector){ - return this.neighborhood(selector); - } - }); - - - // Edge functions - ///////////////// - - $$.fn.eles({ - source: defineSourceFunction({ - attr: "source" - }), - - target: defineSourceFunction({ - attr: "target" - }) - }); - - function defineSourceFunction( params ){ - return function( selector ){ - var sources = []; - var edges = this.edges(); - var cy = this._private.cy; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var id = edge._private.data[params.attr]; - var src = cy.getElementById( id ); - - if( src.length > 0 ){ - sources.push( src ); - } - } - - return new $$.Collection( cy, sources ).filter( selector ); - } - } - - $$.fn.eles({ - edgesWith: defineEdgesWithFunction(), - - edgesTo: defineEdgesWithFunction({ - thisIs: "source" - }) - }); - - function defineEdgesWithFunction( params ){ - - return function(otherNodes){ - var elements = []; - var cy = this._private.cy; - var p = params || {}; - - // get elements if a selector is specified - if( $$.is.string(otherNodes) ){ - otherNodes = cy.$( otherNodes ); - } - - var edges = otherNodes.connectedEdges(); - var thisIds = this._private.ids; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var foundId; - var edgeData = edge._private.data; - - if( p.thisIs ){ - var idToFind = edgeData[ p.thisIs ]; - foundId = thisIds[ idToFind ]; - } else { - foundId = thisIds[ edgeData.source ] || thisIds[ edgeData.target ]; - } - - if( foundId ){ - elements.push( edge ); - } - } - - return new $$.Collection( cy, elements ); - }; - } - - $$.fn.eles({ - connectedEdges: function( selector ){ - var elements = []; - var cy = this._private.cy; - - var nodes = this.nodes(); - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - var edges = node._private.edges; - - for( var j = 0; j < edges.length; j++ ){ - var edge = edges[j]; - elements.push( edge ); - } - } - - return new $$.Collection( cy, elements ).filter( selector ); - }, - - connectedNodes: function( selector ){ - var elements = []; - var cy = this._private.cy; - - var edges = this.edges(); - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - - elements.push( edge.source()[0] ); - elements.push( edge.target()[0] ); - } - - return new $$.Collection( cy, elements ).filter( selector ); - }, - - parallelEdges: defineParallelEdgesFunction(), - - codirectedEdges: defineParallelEdgesFunction({ - codirected: true - }), - - parallelIndex: function(){ - var edge = this[0]; - - if( edge.isEdge() ){ - var src = edge.source()[0]; - var srcEdges = src._private.edges; - var index = 0; - - for( var i = 0; i < srcEdges.length; i++ ){ - var srcEdge = srcEdges[i]; - var thisIsTheIndex = srcEdge === edge; - - if( thisIsTheIndex ){ - return index; - } - - var codirected = edge._private.data.source === srcEdge._private.data.source - && edge._private.data.target === srcEdge._private.data.target; - var opdirected = edge._private.data.source === srcEdge._private.data.target - && edge._private.data.target === srcEdge._private.data.source; - var parallel = codirected || opdirected; - - if( parallel ){ // then increase the count - index++; - } - } - } - }, - - parallelSize: function(){ - var edge = this[0]; - - if( edge.isEdge() ){ - var src = edge.source()[0]; - var srcEdges = src._private.edges; - var numEdges = 0; - - for( var i = 0; i < srcEdges.length; i++ ){ - var srcEdge = srcEdges[i]; - var codirected = edge._private.data.source === srcEdge._private.data.source - && edge._private.data.target === srcEdge._private.data.target; - var opdirected = edge._private.data.source === srcEdge._private.data.target - && edge._private.data.target === srcEdge._private.data.source; - var parallel = codirected || opdirected; - - if( parallel ){ // then increase the count - numEdges++; - } - } - - return numEdges; - } - } - }); - - function defineParallelEdgesFunction(params){ - var defaults = { - codirected: false - }; - params = $$.util.extend({}, defaults, params); - - return function( selector ){ - var cy = this._private.cy; - var elements = []; - var edges = this.edges(); - var p = params; - - // look at all the edges in the collection - for( var i = 0; i < edges.length; i++ ){ - var edge1 = edges[i]; - var src1 = edge1.source()[0]; - var srcid1 = src1.id(); - var tgt1 = edge1.target()[0]; - var tgtid1 = tgt1.id(); - var srcEdges1 = src1._private.edges; - - // look at edges connected to the src node of this edge - for( var j = 0; j < srcEdges1.length; j++ ){ - var edge2 = srcEdges1[j]; - var edge2data = edge2._private.data; - var tgtid2 = edge2data.target; - var srcid2 = edge2data.source; - - var codirected = tgtid2 === tgtid1 && srcid2 === srcid1; - var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2; - - if( (p.codirected && codirected) - || (!p.codirected && (codirected || oppdirected)) ){ - elements.push( edge2 ); - } - } - } - - return new $$.Collection( cy, elements ).filter( selector ); - }; - - } - - - // Compound functions - ///////////////////// - - $$.fn.eles({ - parent: function( selector ){ - var parents = []; - var cy = this._private.cy; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - var parent = cy.getElementById( ele._private.data.parent ); - - if( parent.size() > 0 ){ - parents.push( parent ); - } - } - - return new $$.Collection( cy, parents ).filter( selector ); - }, - - parents: function( selector ){ - var parents = []; - - var eles = this.parent(); - while( eles.nonempty() ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - parents.push( ele ); - } - - eles = eles.parent(); - } - - return new $$.Collection( this.cy(), parents ).filter( selector ); - }, - - children: function( selector ){ - var children = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - children = children.concat( ele._private.children ); - } - - return new $$.Collection( this.cy(), children ).filter( selector ); - }, - - siblings: function( selector ){ - return this.parent().children().not( this ).filter( selector ); - }, - - isParent: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.children.length !== 0; - } - }, - - isChild: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.parent !== undefined && ele.parent().length !== 0; - } - }, - - descendants: function( selector ){ - var elements = []; - - function add( eles ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - elements.push( ele ); - - if( ele.children().nonempty() ){ - add( ele.children() ); - } - } - } - - add( this.children() ); - - return new $$.Collection( this.cy(), elements ).filter( selector ); - } - }); - - -})( cytoscape ); - -;(function($$){ - - - $$.fn.selector = function(map, options){ - for( var name in map ){ - var fn = map[name]; - $$.Selector.prototype[ name ] = fn; - } - }; - - $$.Selector = function(onlyThisGroup, selector){ - - if( !(this instanceof $$.Selector) ){ - return new $$.Selector(onlyThisGroup, selector); - } - - if( selector === undefined && onlyThisGroup !== undefined ){ - selector = onlyThisGroup; - onlyThisGroup = undefined; - } - - var self = this; - - self._private = { - selectorText: null, - invalid: true - } - - // storage for parsed queries - // when you add something here, also add to Selector.toString() - function newQuery(){ - return { - classes: [], - colonSelectors: [], - data: [], - group: null, - ids: [], - meta: [], - - // fake selectors - collection: null, // a collection to match against - filter: null, // filter function - - // these are defined in the upward direction rather than down (e.g. child) - // because we need to go up in Selector.filter() - parent: null, // parent query obj - ancestor: null, // ancestor query obj - subject: null, // defines subject in compound query (subject query obj; points to self if subject) - - // use these only when subject has been defined - child: null, - descendant: null - }; - } - - if( !selector || ( $$.is.string(selector) && selector.match(/^\s*$/) ) ){ - - if( onlyThisGroup == null ){ - // ignore - self.length = 0; - } else { - self[0] = newQuery(); - self[0].group = onlyThisGroup; - self.length = 1; - } - - } else if( $$.is.element( selector ) ){ - var collection = new $$.Collection(self.cy(), [ selector ]); - - self[0] = newQuery(); - self[0].collection = collection; - self.length = 1; - - } else if( $$.is.collection( selector ) ){ - self[0] = newQuery(); - self[0].collection = selector; - self.length = 1; - - } else if( $$.is.fn( selector ) ) { - self[0] = newQuery(); - self[0].filter = selector; - self.length = 1; - - } else if( $$.is.string( selector ) ){ - - // these are the actual tokens in the query language - var metaChar = "[\\!\\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]"; // chars we need to escape in var names, etc - var variable = "(?:[\\w-]|(?:\\\\"+ metaChar +"))+"; // a variable name - var comparatorOp = "=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*="; // binary comparison op (used in data selectors) - var boolOp = "\\?|\\!|\\^"; // boolean (unary) operators (used in data selectors) - var string = '"(?:\\\\"|[^"])+"' + "|" + "'(?:\\\\'|[^'])+'"; // string literals (used in data selectors) -- doublequotes | singlequotes - var number = $$.util.regex.number; // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123 - var value = string + "|" + number; // a value literal, either a string or number - var meta = "degree|indegree|outdegree"; // allowed metadata fields (i.e. allowed functions to use from $$.Collection) - var separator = "\\s*,\\s*"; // queries are separated by commas; e.g. edge[foo = "bar"], node.someClass - var className = variable; // a class name (follows variable conventions) - var descendant = "\\s+"; - var child = "\\s+>\\s+"; - var subject = "\\$"; - var id = variable; // an element id (follows variable conventions) - - // when a token like a variable has escaped meta characters, we need to clean the backslashes out - // so that values get compared properly in Selector.filter() - function cleanMetaChars(str){ - return str.replace(new RegExp("\\\\(" + metaChar + ")", "g"), "\1"); - } - - // add @ variants to comparatorOp - var ops = comparatorOp.split("|"); - for( var i = 0; i < ops.length; i++ ){ - var op = ops[i]; - comparatorOp += "|@" + op; - } - - // the current subject in the query - var currentSubject = null; - - // NOTE: add new expression syntax here to have it recognised by the parser; - // a query contains all adjacent (i.e. no separator in between) expressions; - // the current query is stored in self[i] --- you can use the reference to `this` in the populate function; - // you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward - var exprs = { - group: { - query: true, - regex: "(node|edge|\\*)", - populate: function( group ){ - this.group = group == "*" ? group : group + "s"; - } - }, - - state: { - query: true, - regex: "(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:parent|:child|:active|:inactive|:touch)", - populate: function( state ){ - this.colonSelectors.push( state ); - } - }, - - id: { - query: true, - regex: "\\#("+ id +")", - populate: function( id ){ - this.ids.push( cleanMetaChars(id) ); - } - }, - - className: { - query: true, - regex: "\\.("+ className +")", - populate: function( className ){ - this.classes.push( cleanMetaChars(className) ); - } - }, - - dataExists: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*\\]", - populate: function( variable ){ - this.data.push({ - field: cleanMetaChars(variable) - }); - } - }, - - dataCompare: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*("+ comparatorOp +")\\s*("+ value +")\\s*\\]", - populate: function( variable, comparatorOp, value ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: comparatorOp, - value: value - }); - } - }, - - dataBool: { - query: true, - regex: "\\[\\s*("+ boolOp +")\\s*("+ variable +")\\s*\\]", - populate: function( boolOp, variable ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: boolOp - }); - } - }, - - metaCompare: { - query: true, - regex: "\\{\\s*("+ meta +")\\s*("+ comparatorOp +")\\s*("+ number +")\\s*\\}", - populate: function( meta, comparatorOp, number ){ - this.meta.push({ - field: cleanMetaChars(meta), - operator: comparatorOp, - value: number - }); - } - }, - - nextQuery: { - separator: true, - regex: separator, - populate: function(){ - // go on to next query - self[++i] = newQuery(); - currentSubject = null; - } - }, - - child: { - separator: true, - regex: child, - populate: function(){ - // this query is the parent of the following query - var childQuery = newQuery(); - childQuery.parent = this; - childQuery.subject = currentSubject; - - // we're now populating the child query with expressions that follow - self[i] = childQuery; - } - }, - - descendant: { - separator: true, - regex: descendant, - populate: function(){ - // this query is the ancestor of the following query - var descendantQuery = newQuery(); - descendantQuery.ancestor = this; - descendantQuery.subject = currentSubject; - - // we're now populating the descendant query with expressions that follow - self[i] = descendantQuery; - } - }, - - subject: { - modifier: true, - regex: subject, - populate: function(){ - if( currentSubject != null && this.subject != this ){ - $$.util.error("Redefinition of subject in selector `" + selector + "`"); - return false; - } - - currentSubject = this; - this.subject = this; - }, - - } - }; - - var j = 0; - for( var name in exprs ){ - exprs[j] = exprs[name]; - exprs[j].name = name; - - j++; - } - exprs.length = j; - - self._private.selectorText = selector; - var remaining = selector; - var i = 0; - - // of all the expressions, find the first match in the remaining text - function consumeExpr( expectation ){ - var expr; - var match; - var name; - - for( var j = 0; j < exprs.length; j++ ){ - var e = exprs[j]; - var n = e.name; - - // ignore this expression if it doesn't meet the expectation function - if( $$.is.fn( expectation ) && !expectation(n, e) ){ continue } - - var m = remaining.match(new RegExp( "^" + e.regex )); - - if( m != null ){ - match = m; - expr = e; - name = n; - - var consumed = m[0]; - remaining = remaining.substring( consumed.length ); - - break; // we've consumed one expr, so we can return now - } - } - - return { - expr: expr, - match: match, - name: name - }; - } - - // consume all leading whitespace - function consumeWhitespace(){ - var match = remaining.match(/^\s+/); - - if( match ){ - var consumed = match[0]; - remaining = remaining.substring( consumed.length ); - } - } - - self[0] = newQuery(); // get started - - consumeWhitespace(); // get rid of leading whitespace - for(;;){ - var check = consumeExpr(); - - if( check.expr == null ){ - $$.util.error("The selector `"+ selector +"`is invalid"); - return; - } else { - var args = []; - for(var j = 1; j < check.match.length; j++){ - args.push( check.match[j] ); - } - - // let the token populate the selector object (i.e. in self[i]) - var ret = check.expr.populate.apply( self[i], args ); - - if( ret === false ){ return } // exit if population failed - } - - // we're done when there's nothing left to parse - if( remaining.match(/^\s*$/) ){ - break; - } - } - - self.length = i + 1; - - // adjust references for subject - for(j = 0; j < self.length; j++){ - var query = self[j]; - - if( query.subject != null ){ - // go up the tree until we reach the subject - for(;;){ - if( query.subject == query ){ break } // done if subject is self - - if( query.parent != null ){ // swap parent/child reference - var parent = query.parent; - var child = query; - - child.parent = null; - parent.child = child; - - query = parent; // go up the tree - } else if( query.ancestor != null ){ // swap ancestor/descendant - var ancestor = query.ancestor; - var descendant = query; - - descendant.ancestor = null; - ancestor.descendant = descendant; - - query = ancestor; // go up the tree - } else { - $$.util.error("When adjusting references for the selector `"+ query +"`, neither parent nor ancestor was found"); - break; - } - } // for - - self[j] = query.subject; // subject should be the root query - } // if - } // for - - // make sure for each query that the subject group matches the implicit group if any - if( onlyThisGroup != null ){ - for(var j = 0; j < self.length; j++){ - if( self[j].group != null && self[j].group != onlyThisGroup ){ - $$.util.error("Group `"+ self[j].group +"` conflicts with implicit group `"+ onlyThisGroup +"` in selector `"+ selector +"`"); - return; - } - - self[j].group = onlyThisGroup; // set to implicit group - } - } - - } else { - $$.util.error("A selector must be created from a string; found " + selector); - return; - } - - self._private.invalid = false; - - }; - - $$.selfn = $$.Selector.prototype; - - $$.selfn.size = function(){ - return this.length; - }; - - $$.selfn.eq = function(i){ - return this[i]; - }; - - // get elements from the core and then filter them - $$.selfn.find = function(){ - // TODO impl if we decide to use a DB for storing elements - }; - - // filter an existing collection - $$.selfn.filter = function(collection, addLiveFunction){ - var self = this; - var cy = collection.cy(); - - // don't bother trying if it's invalid - if( self._private.invalid ){ - return new $$.Collection( cy ); - } - - var queryMatches = function(query, element){ - // check group - if( query.group != null && query.group != "*" && query.group != element._private.group ){ - return false; - } - - // check colon selectors - var allColonSelectorsMatch = true; - for(var k = 0; k < query.colonSelectors.length; k++){ - var sel = query.colonSelectors[k]; - var renderer = cy.renderer(); // TODO remove reference after refactoring - - switch(sel){ - case ":selected": - allColonSelectorsMatch = element.selected(); - break; - case ":unselected": - allColonSelectorsMatch = !element.selected(); - break; - case ":selectable": - allColonSelectorsMatch = element.selectable(); - break; - case ":unselectable": - allColonSelectorsMatch = !element.selectable(); - break; - case ":locked": - allColonSelectorsMatch = element.locked(); - break; - case ":unlocked": - allColonSelectorsMatch = !element.locked(); - break; - case ":visible": - allColonSelectorsMatch = element.visible(); - break; - case ":hidden": - allColonSelectorsMatch = !element.visible(); - break; - case ":grabbed": - allColonSelectorsMatch = element.grabbed(); - break; - case ":free": - allColonSelectorsMatch = !element.grabbed(); - break; - case ":removed": - allColonSelectorsMatch = element.removed(); - break; - case ":inside": - allColonSelectorsMatch = !element.removed(); - break; - case ":grabbable": - allColonSelectorsMatch = element.grabbable(); - break; - case ":ungrabbable": - allColonSelectorsMatch = !element.grabbable(); - break; - case ":animated": - allColonSelectorsMatch = element.animated(); - break; - case ":unanimated": - allColonSelectorsMatch = !element.animated(); - break; - case ":parent": - allColonSelectorsMatch = element.children().nonempty(); - break; - case ":child": - allColonSelectorsMatch = element.parent().nonempty(); - break; - case ":active": - allColonSelectorsMatch = element.active(); - break; - case ":inactive": - allColonSelectorsMatch = !element.active(); - break; - case ":touch": - allColonSelectorsMatch = window && document && (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); - break; - } - - if( !allColonSelectorsMatch ) break; - } - if( !allColonSelectorsMatch ) return false; - - // check id - var allIdsMatch = true; - for(var k = 0; k < query.ids.length; k++){ - var id = query.ids[k]; - var actualId = element._private.data.id; - - allIdsMatch = allIdsMatch && (id == actualId); - - if( !allIdsMatch ) break; - } - if( !allIdsMatch ) return false; - - // check classes - var allClassesMatch = true; - for(var k = 0; k < query.classes.length; k++){ - var cls = query.classes[k]; - - allClassesMatch = allClassesMatch && element.hasClass(cls); - - if( !allClassesMatch ) break; - } - if( !allClassesMatch ) return false; - - // generic checking for data/metadata - function operandsMatch(params){ - var allDataMatches = true; - for(var k = 0; k < query[params.name].length; k++){ - var data = query[params.name][k]; - var operator = data.operator; - var value = data.value; - var field = data.field; - var matches; - - if( operator != null && value != null ){ - - var fieldStr = "" + params.fieldValue(field); - var valStr = "" + eval(value); - - var caseInsensitive = false; - if( operator.charAt(0) == "@" ){ - fieldStr = fieldStr.toLowerCase(); - valStr = valStr.toLowerCase(); - - operator = operator.substring(1); - caseInsensitive = true; - } - - if( operator == "=" ){ - operator = "=="; - } - - switch(operator){ - case "*=": - matches = fieldStr.search(valStr) >= 0; - break; - case "$=": - matches = new RegExp(valStr + "$").exec(fieldStr) != null; - break; - case "^=": - matches = new RegExp("^" + valStr).exec(fieldStr) != null; - break; - default: - // if we're doing a case insensitive comparison, then we're using a STRING comparison - // even if we're comparing numbers - if( caseInsensitive ){ - // eval with lower case strings - var expr = "fieldStr " + operator + " valStr"; - matches = eval(expr); - } else { - // just eval as normal - var expr = params.fieldRef(field) + " " + operator + " " + value; - matches = eval(expr); - } - - } - } else if( operator != null ){ - switch(operator){ - case "?": - matches = params.fieldTruthy(field); - break; - case "!": - matches = !params.fieldTruthy(field); - break; - case "^": - matches = params.fieldUndefined(field); - break; - } - } else { - matches = !params.fieldUndefined(field); - } - - if( !matches ){ - allDataMatches = false; - break; - } - } // for - - return allDataMatches; - } // operandsMatch - - // check data matches - var allDataMatches = operandsMatch({ - name: "data", - fieldValue: function(field){ - return element._private.data[field]; - }, - fieldRef: function(field){ - return "element._private.data." + field; - }, - fieldUndefined: function(field){ - return element._private.data[field] === undefined; - }, - fieldTruthy: function(field){ - if( element._private.data[field] ){ - return true; - } - return false; - } - }); - - if( !allDataMatches ){ - return false; - } - - // check metadata matches - var allMetaMatches = operandsMatch({ - name: "meta", - fieldValue: function(field){ - return element[field](); - }, - fieldRef: function(field){ - return "element." + field + "()"; - }, - fieldUndefined: function(field){ - return element[field]() == undefined; - }, - fieldTruthy: function(field){ - if( element[field]() ){ - return true; - } - return false; - } - }); - - if( !allMetaMatches ){ - return false; - } - - // check collection - if( query.collection != null ){ - var matchesAny = query.collection._private.ids[ element.id() ] != null; - - if( !matchesAny ){ - return false; - } - } - - // check filter function - if( query.filter != null && element.collection().filter( query.filter ).size() == 0 ){ - return false; - } - - - // check parent/child relations - function confirmRelations( query, elements ){ - if( query != null ){ - var matches = false; - elements = elements(); // make elements functional so we save cycles if query == null - - // query must match for at least one element (may be recursive) - for(var i = 0; i < elements.size(); i++){ - if( queryMatches( query, elements.eq(i) ) ){ - matches = true; - break; - } - } - - return matches; - } else { - return true; - } - } - - if (! confirmRelations(query.parent, function(){ - return element.parent() - }) ){ return false } - - if (! confirmRelations(query.ancestor, function(){ - return element.parents() - }) ){ return false } - - if (! confirmRelations(query.child, function(){ - return element.children() - }) ){ return false } - - if (! confirmRelations(query.descendant, function(){ - return element.descendants() - }) ){ return false } - - // we've reached the end, so we've matched everything for this query - return true; - }; // queryMatches - - var selectorFunction = function(i, element){ - for(var j = 0; j < self.length; j++){ - var query = self[j]; - - if( queryMatches(query, element) ){ - return true; - } - } - - return false; - }; - - if( self._private.selectorText == null ){ - selectorFunction = function(){ return true; }; - } - - var filteredCollection = collection.filter( selectorFunction ); - - return filteredCollection; - }; // filter - - // ith query to string - $$.selfn.toString = $$.selfn.selector = function(){ - - var str = ""; - - function clean(obj){ - if( $$.is.string(obj) ){ - return obj; - } - return ""; - } - - function queryToString(query){ - var str = ""; - - var group = clean(query.group); - str += group.substring(0, group.length - 1); - - for(var j = 0; j < query.data.length; j++){ - var data = query.data[j]; - str += "[" + data.field + clean(data.operator) + clean(data.value) + "]" - } - - for(var j = 0; j < query.meta.length; j++){ - var meta = query.meta[j]; - str += "{" + meta.field + clean(meta.operator) + clean(meta.value) + "}" - } - - for(var j = 0; j < query.colonSelectors.length; j++){ - var sel = query.colonSelectors[i]; - str += sel; - } - - for(var j = 0; j < query.ids.length; j++){ - var sel = "#" + query.ids[i]; - str += sel; - } - - for(var j = 0; j < query.classes.length; j++){ - var sel = "." + query.classes[i]; - str += sel; - } - - if( query.parent != null ){ - str = queryToString( query.parent ) + " > " + str; - } - - if( query.ancestor != null ){ - str = queryToString( query.ancestor ) + " " + str; - } - - if( query.child != null ){ - str += " > " + queryToString( query.child ); - } - - if( query.descendant != null ){ - str += " " + queryToString( query.descendant ); - } - - return str; - } - - for(var i = 0; i < this.length; i++){ - var query = this[i]; - - str += queryToString( query ); - - if( this.length > 1 && i < this.length - 1 ){ - str += ", "; - } - } - - return str; - }; - -})( cytoscape ); - -;(function($$){ - - function NullRenderer(options){ - } - - NullRenderer.prototype.notify = function(params){ - }; - - $$("renderer", "null", NullRenderer); - -})( cytoscape ); - -(function($$) { - - var isTouch = ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch; - var time = function() { return Date.now(); } ; - var arrowShapes = {}; var nodeShapes = {}; - var rendFunc = CanvasRenderer.prototype; - var panOrBoxSelectDelay = 400; - - // Canvas layer constants - var CANVAS_LAYERS = 5, SELECT_BOX = 0, DRAG = 2, OVERLAY = 3, NODE = 4, BUFFER_COUNT = 2; - - function CanvasRenderer(options) { - - this.options = options; - - this.data = { - - select: [undefined, undefined, undefined, undefined, 0], // Coordinates for selection box, plus enabled flag - renderer: this, cy: options.cy, container: options.cy.container(), - - canvases: new Array(CANVAS_LAYERS), - canvasRedrawReason: new Array(CANVAS_LAYERS), - canvasNeedsRedraw: new Array(CANVAS_LAYERS), - - bufferCanvases: new Array(BUFFER_COUNT) - - }; - - //--Pointer-related data - this.hoverData = {down: null, last: null, - downTime: null, triggerMode: null, - dragging: false, - initialPan: [null, null], capture: false}; - - this.timeoutData = {panTimeout: null}; - - this.dragData = {possibleDragElements: []}; - - this.touchData = {start: null, capture: false, - // These 3 fields related to tap, taphold events - startPosition: [null, null, null, null, null, null], - singleTouchStartTime: null, - singleTouchMoved: true, - - - now: [null, null, null, null, null, null], - earlier: [null, null, null, null, null, null] }; - //-- - - //--Wheel-related data - this.zoomData = {freeToZoom: false, lastPointerX: null}; - //-- - - this.redraws = 0; - - this.bindings = []; - - this.init(); - - for (var i = 0; i < CANVAS_LAYERS; i++) { - this.data.canvases[i] = document.createElement("canvas"); - this.data.canvases[i].style.position = "absolute"; - this.data.canvases[i].setAttribute("data-id", "layer" + i); - this.data.canvases[i].style.zIndex = String(CANVAS_LAYERS - i); - this.data.container.appendChild(this.data.canvases[i]); - - this.data.canvasRedrawReason[i] = new Array(); - this.data.canvasNeedsRedraw[i] = false; - } - - this.data.canvases[NODE].setAttribute("data-id", "layer" + NODE + '-node'); - this.data.canvases[SELECT_BOX].setAttribute("data-id", "layer" + SELECT_BOX + '-selectbox'); - this.data.canvases[DRAG].setAttribute("data-id", "layer" + DRAG + '-drag'); - this.data.canvases[OVERLAY].setAttribute("data-id", "layer" + OVERLAY + '-overlay'); - - for (var i = 0; i < BUFFER_COUNT; i++) { - this.data.bufferCanvases[i] = document.createElement("canvas"); - this.data.bufferCanvases[i].style.position = "absolute"; - this.data.bufferCanvases[i].setAttribute("data-id", "buffer" + i); - this.data.bufferCanvases[i].style.zIndex = String(-i - 1); - this.data.bufferCanvases[i].style.visibility = "visible"; - this.data.container.appendChild(this.data.bufferCanvases[i]); - } - - var overlay = document.createElement('div'); - this.data.container.appendChild( overlay ); - this.data.overlay = overlay; - overlay.style.position = 'absolute'; - overlay.style.zIndex = 1000; - - if( options.showOverlay ){ - - var link = document.createElement('a'); - overlay.appendChild( link ); - this.data.link = link; - - link.innerHTML = 'cytoscape.js'; - link.style.font = '14px helvetica'; - link.style.position = 'absolute'; - link.style.right = 0; - link.style.bottom = 0; - link.style.padding = '1px 3px'; - link.style.paddingLeft = '5px'; - link.style.paddingTop = '5px'; - link.style.opacity = 0; - link.style['-webkit-tap-highlight-color'] = 'transparent'; - link.style.background = 'red'; - - link.href = 'http://cytoscape.github.io/cytoscape.js/'; - link.target = '_blank'; - - } - - this.hideEdgesOnViewport = options.hideEdgesOnViewport; - - this.load(); - } - - CanvasRenderer.prototype.notify = function(params) { - if ( params.type == "destroy" ){ - this.destroy(); - return; - - } else if (params.type == "add" - || params.type == "remove" - || params.type == "load" - ) { - - this.updateNodesCache(); - this.updateEdgesCache(); - } - - if (params.type == "viewport") { - this.data.canvasNeedsRedraw[SELECT_BOX] = true; - this.data.canvasRedrawReason[SELECT_BOX].push("viewchange"); - } - - this.data.canvasNeedsRedraw[DRAG] = true; this.data.canvasRedrawReason[DRAG].push("notify"); - this.data.canvasNeedsRedraw[NODE] = true; this.data.canvasRedrawReason[NODE].push("notify"); - - this.redraws++; - this.redraw(); - }; - - CanvasRenderer.prototype.registerBinding = function(target, event, handler, useCapture){ - this.bindings.push({ - target: target, - event: event, - handler: handler, - useCapture: useCapture - }); - - target.addEventListener(event, handler, useCapture); - }; - - CanvasRenderer.prototype.destroy = function(){ - this.destroyed = true; - - for( var i = 0; i < this.bindings.length; i++ ){ - var binding = this.bindings[i]; - var b = binding; - - b.target.removeEventListener(b.event, b.handler, b.useCapture); - } - }; - - - CanvasRenderer.prototype.png = function(){ - var data = this.data; - - // Rasterize the layers, but only if container has nonzero size - if (this.data.container.clientHeight > 0 - && this.data.container.clientWidth > 0) { - - context = data.bufferCanvases[1].getContext("2d"); - context.globalCompositeOperation = "copy"; - context.drawImage(data.canvases[4], 0, 0); - context.globalCompositeOperation = "source-over"; - context.drawImage(data.canvases[2], 0, 0); - context.drawImage(data.canvases[0], 0, 0); - - context = data.bufferCanvases[0].getContext("2d"); - context.globalCompositeOperation = "copy"; - context.drawImage(data.bufferCanvases[1], 0, 0); - } - - var canvas = this.data.bufferCanvases[0]; - - return canvas.toDataURL("image/png"); - }; - - // @O Initialization functions - { - CanvasRenderer.prototype.load = function() { - var r = this; - - // helper function to determine which child nodes and inner edges - // of a compound node to be dragged as well as the grabbed and selected nodes - var addDescendantsToDrag = function(node, addSelected, dragElements) { - if (!addSelected) - { - var parents = node.parents(); - - // do not process descendants for this node, - // because those will be handled for the topmost selected parent - for (var i=0; i < parents.size(); i++) - { - if (parents[i]._private.selected) - { - return; - } - } - } - - var innerNodes = node.descendants(); - - function hasNonAutoParent(ele){ - while( ele.parent().nonempty() && ele.parent().id() !== node.id() ){ - parent = ele.parent()[0]; - var pstyle = parent._private.style; - - if( pstyle.width.value !== 'auto' || pstyle.height.value !== 'auto' ){ - return true; - } - - ele = ele.parent(); - } - - return false; - } - - // TODO do not drag hidden children & children of hidden children? - for (var i=0; i < innerNodes.size(); i++) - { - // if addSelected is true, then add node in any case, - // if not, then add only non-selected nodes - if ( (addSelected || !innerNodes[i]._private.selected) ) - { - innerNodes[i]._private.rscratch.inDragLayer = true; - //innerNodes[i].trigger(new $$.Event(e, {type: "grab"})); - //innerNodes[i].trigger(event); - dragElements.push(innerNodes[i]); - - for (var j=0; j < innerNodes[i]._private.edges.length; j++) - { - innerNodes[i]._private.edges[j]._private.rscratch.inDragLayer = true; - } - } - } - }; - - // adds the given nodes, and its edges to the drag layer - var addNodeToDrag = function(node, dragElements) { - node._private.grabbed = true; - node._private.rscratch.inDragLayer = true; - - dragElements.push(node); - - for (var i=0;i containerPageCoords[0] && e.pageX < containerPageCoords[0] + r.data.container.clientWidth - && e.pageY > containerPageCoords[1] && e.pageY < containerPageCoords[1] + r.data.container.clientHeight) { - - } else { - return; - } - } - - var cy = r.data.cy; - var pos = r.projectIntoViewport(e.pageX, e.pageY); - var select = r.data.select; - - var near = r.findNearestElement(pos[0], pos[1], true); - var last = r.hoverData.last; - var down = r.hoverData.down; - - var disp = [pos[0] - select[2], pos[1] - select[3]]; - var nodes = r.getCachedNodes(); - var edges = r.getCachedEdges(); - - var draggedElements = r.dragData.possibleDragElements; - - - var shiftDown = e.shiftKey; - - - preventDefault = true; - - // Mousemove event - { - var event = new $$.Event(e, {type: "mousemove"}); - - if (near != null) { - near.trigger(event); - - } else if (near == null) { - cy.trigger(event); - } - - } - - - // trigger context drag if rmouse down - if( r.hoverData.which === 3 ){ - var cxtEvt = new $$.Event(e, {type: "cxtdrag"}); - - if( down ){ - down.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - r.hoverData.cxtDragged = true; - - // Check if we are drag panning the entire graph - } else if (r.hoverData.dragging) { - preventDefault = true; - - if( cy.panningEnabled() ){ - var deltaP = {x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}; - - cy.panBy( deltaP ); - } - - // Needs reproject due to pan changing viewport - pos = r.projectIntoViewport(e.pageX, e.pageY); - - // Checks primary button down & out of time & mouse not moved much - } else if (select[4] == 1 && (down == null || down.isEdge()) - && ( !cy.boxSelectionEnabled() || +new Date - r.hoverData.downTime >= panOrBoxSelectDelay ) - && (Math.abs(select[3] - select[1]) + Math.abs(select[2] - select[0]) < 4) - && cy.panningEnabled() ) { - - r.hoverData.dragging = true; - select[4] = 0; - - } else { - // deactivate bg on box selection - if (cy.boxSelectionEnabled() && Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) > 7 && select[4]){ - clearTimeout( r.bgActiveTimeout ); - } - - if( down && down.isEdge() && down.active() ){ down.unactivate(); } - - if (near != last) { - - if (last) { last.trigger(new $$.Event(e, {type: "mouseout"})); } - if (near) { near.trigger(new $$.Event(e, {type: "mouseover"})); } - - r.hoverData.last = near; - } - - if ( down && down.isNode() && r.nodeIsDraggable(down) ) { - r.dragData.didDrag = true; // indicate that we actually did drag the node - - var toTrigger = []; - for (var i=0; i 7 && select[4]) // not box selection - && !r.hoverData.dragging // not panning - ) { - - // console.log('unselect all from bg'); - - //++clock+unselect - // var a = time(); - cy.$(':selected').unselect(); - - //++clock+unselect - // console.log("unselect", time() - a); - - if (draggedElements.length > 0) { - r.data.canvasNeedsRedraw[NODE] = true; r.data.canvasRedrawReason[NODE].push("De-select"); - } - - r.dragData.possibleDragElements = draggedElements = []; - } - - // Click event - { - // console.log('trigger click et al'); - - if (Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) == 0) { - if (near != null) { - near - .trigger( new $$.Event(e, {type: "click"}) ) - .trigger( new $$.Event(e, {type: "tap"}) ) - .trigger( new $$.Event(e, {type: "vclick"}) ) - ; - } else if (near == null) { - cy - .trigger( new $$.Event(e, {type: "click"}) ) - .trigger( new $$.Event(e, {type: "tap"}) ) - .trigger( new $$.Event(e, {type: "vclick"}) ) - ; - } - } - } - - // Mouseup event - { - // console.log('trigger mouseup et al'); - - if (near != null) { - near - .trigger(new $$.Event(e, {type: "mouseup"})) - .trigger(new $$.Event(e, {type: "tapend"})) - .trigger(new $$.Event(e, {type: "vmouseup"})) - ; - } else if (near == null) { - cy - .trigger(new $$.Event(e, {type: "mouseup"})) - .trigger(new $$.Event(e, {type: "tapend"})) - .trigger(new $$.Event(e, {type: "vmouseup"})) - ; - } - } - - // Single selection - if (near == down && !r.dragData.didDrag) { - if (near != null && near._private.selectable) { - - // console.log('single selection') - - if( !shiftDown ){ - cy.$(':selected').unselect(); - } - - if( near.selected() ){ - near.unselect(); - } else { - near.select(); - } - - updateAncestorsInDragLayer(near, false); - - r.data.canvasNeedsRedraw[NODE] = true; r.data.canvasRedrawReason[NODE].push("sglslct"); - - } - // Ungrab single drag - } else if (near == down) { - if (near != null && near._private.grabbed) { - // console.log('ungrab single drag') - - var grabbedEles = cy.$(':grabbed'); - - for(var i = 0; i < grabbedEles.length; i++){ - var ele = grabbedEles[i]; - - ele._private.grabbed = false; - - var sEdges = ele._private.edges; - for (var j=0;j 7 && select[4] ) { - // console.log("box selection"); - - if( !shiftDown ){ - cy.$(':selected').unselect(); - } - - var newlySelected = []; - var box = r.getAllInBox(select[0], select[1], select[2], select[3]); - // console.log(box); - var event = new $$.Event(e, {type: "select"}); - for (var i=0;i 0) { - r.data.canvasNeedsRedraw[NODE] = true; r.data.canvasRedrawReason[NODE].push("Selection"); - } - } - - // Cancel drag pan - r.hoverData.dragging = false; - - if (!select[4]) { - // console.log('free at end', draggedElements) - var freeEvent = new $$.Event(e, {type: "free"}); - - for (var i=0;i 250) { - if (r.touchData.start) { - r.touchData.start.trigger(new $$.Event(e, {type: "taphold"})); - } else { - r.data.cy.trigger(new $$.Event(e, {type: "taphold"})); - - cy.$(':selected').unselect(); - } - -// console.log("taphold"); - } - }, 1000); - } - - r.redraw(); - - }, false); - -// console.log = function(m){ $('#console').append('
                      '+m+'
                      '); }; - - r.registerBinding(window, "touchmove", function(e) { - - var select = r.data.select; - var capture = r.touchData.capture; //if (!capture) { return; }; - capture && e.preventDefault(); - - var cy = r.data.cy; - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - var now = r.touchData.now; var earlier = r.touchData.earlier; - - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - var disp = []; for (var j=0;j= 1.5 || distance2 >= 150 ){ - r.touchData.cxt = false; - if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; } - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[SELECT_BOX] = true; - - var cxtEvt = new $$.Event(e, {type: "cxttapend"}); - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - } - - } - - if( capture && r.touchData.cxt ){ - var cxtEvt = new $$.Event(e, {type: "cxtdrag"}); - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[SELECT_BOX] = true; - - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - if( r.touchData.start ){ r.touchData.start._private.grabbed = false; } - r.touchData.cxtDragged = true; - - //console.log('cxtdrag') - - } else if( capture && e.touches[2] && cy.boxSelectionEnabled() ){ - r.data.bgActivePosistion = undefined; - clearTimeout( this.threeFingerSelectTimeout ); - this.lastThreeTouch = +new Date; - - r.data.canvasNeedsRedraw[SELECT_BOX] = true; - r.data.canvasRedrawReason[SELECT_BOX].push("Touch moved, redraw selection box"); - - if( !select || select.length === 0 || select[0] === undefined ){ - select[0] = (now[0] + now[2] + now[4])/3; - select[1] = (now[1] + now[3] + now[5])/3; - select[2] = (now[0] + now[2] + now[4])/3 + 1; - select[3] = (now[1] + now[3] + now[5])/3 + 1; - } else { - select[2] = (now[0] + now[2] + now[4])/3; - select[3] = (now[1] + now[3] + now[5])/3; - } - - select[4] = 1; - - } else if ( capture && e.touches[1] && cy.zoomingEnabled() && cy.panningEnabled() ) { // two fingers => pinch to zoom - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[SELECT_BOX] = true; - - // console.log('touchmove ptz'); - - // (x2, y2) for fingers 1 and 2 - var f1x2 = e.touches[0].pageX - offsetLeft, f1y2 = e.touches[0].pageY - offsetTop; - var f2x2 = e.touches[1].pageX - offsetLeft, f2y2 = e.touches[1].pageY - offsetTop; - - // console.log( f1x2, f1y2 ) - // console.log( f2x2, f2y2 ) - - var distance2 = distance( f1x2, f1y2, f2x2, f2y2 ); - var factor = distance2 / distance1; - - // console.log(distance2) - // console.log(factor) - - if( factor != 1 && twoFingersStartInside){ - - // console.log(factor) - // console.log(distance2 + ' / ' + distance1); - // console.log('--'); - - // delta finger1 - var df1x = f1x2 - f1x1; - var df1y = f1y2 - f1y1; - - // delta finger 2 - var df2x = f2x2 - f2x1; - var df2y = f2y2 - f2y1; - - // translation is the normalised vector of the two fingers movement - // i.e. so pinching cancels out and moving together pans - var tx = (df1x + df2x)/2; - var ty = (df1y + df2y)/2; - - // adjust factor by the speed multiplier - // var speed = 1.5; - // if( factor > 1 ){ - // factor = (factor - 1) * speed + 1; - // } else { - // factor = 1 - (1 - factor) * speed; - // } - - // now calculate the zoom - var zoom1 = cy.zoom(); - var zoom2 = zoom1 * factor; - var pan1 = cy.pan(); - - // the model center point converted to the current rendered pos - var ctrx = modelCenter1[0] * zoom1 + pan1.x; - var ctry = modelCenter1[1] * zoom1 + pan1.y; - - var pan2 = { - x: -zoom2/zoom1 * (ctrx - pan1.x - tx) + ctrx, - y: -zoom2/zoom1 * (ctry - pan1.y - ty) + ctry - }; - - // console.log(pan2); - // console.log(zoom2); - - cy._private.zoom = zoom2; - cy._private.pan = pan2; - cy - .trigger('pan zoom') - .notify('viewport') - ; - - distance1 = distance2; - f1x1 = f1x2; - f1y1 = f1y2; - f2x1 = f2x2; - f2y1 = f2y2; - - r.pinching = true; - } - - // Re-project - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - - } else if (e.touches[0]) { - var start = r.touchData.start; - var last = r.touchData.last; - - if ( start != null && start._private.group == "nodes" && r.nodeIsDraggable(start)) { - var draggedEles = r.dragData.touchDragEles; - - for( var k = 0; k < draggedEles.length; k++ ){ - var draggedEle = draggedEles[k]; - - if( r.nodeIsDraggable(draggedEle) ){ - r.dragData.didDrag = true; - - draggedEle._private.position.x += disp[0]; - draggedEle._private.position.y += disp[1]; - - } - } - - ( new $$.Collection(cy, draggedEles) ) - .trigger( new $$.Event(e, {type: "drag"}) ) - .trigger( new $$.Event(e, {type: "position"}) ) - ; - - r.data.canvasNeedsRedraw[DRAG] = true; - r.data.canvasRedrawReason[DRAG].push("touchdrag node"); - - if (r.touchData.startPosition[0] == earlier[0] - && r.touchData.startPosition[1] == earlier[1]) { - - r.data.canvasNeedsRedraw[NODE] = true; - r.data.canvasRedrawReason[NODE].push("node drag started"); - } - - } - - // Touchmove event - { - if (start != null) { start.trigger(new $$.Event(e, {type: "touchmove"})); } - - if (start == null) { - var near = r.findNearestElement(now[0], now[1], true); - if (near != null) { near.trigger(new $$.Event(e, {type: "touchmove"})); } - if (near == null) { cy.trigger(new $$.Event(e, {type: "touchmove"})); } - } - - if (near != last) { - if (last) { last.trigger(new $$.Event(e, {type: "touchout"})); } - if (near) { near.trigger(new $$.Event(e, {type: "touchover"})); } - } - - r.touchData.last = near; - } - - // Check to cancel taphold - for (var i=0;i 4) { - - r.touchData.singleTouchMoved = true; - } - } - - if ( capture && (start == null || start.isEdge()) && cy.panningEnabled() ) { - if( start ){ - start.unactivate(); - - if( !r.data.bgActivePosistion ){ - r.data.bgActivePosistion = { - x: now[0], - y: now[1] - }; - } - - r.data.canvasNeedsRedraw[SELECT_BOX] = true; - r.data.canvasRedrawReason[SELECT_BOX].push("bgactive"); - } - - cy.panBy({x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}); - r.swipePanning = true; - - // Re-project - var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); - now[0] = pos[0]; now[1] = pos[1]; - } - } - - for (var j=0;j 0) { - r.data.canvasNeedsRedraw[NODE] = true; r.data.canvasRedrawReason[NODE].push("Selection"); - } - - }, 100); - } - - if( !e.touches[1] ){ - r.pinching = false; - } - - var updateStartStyle = false; - - if( start != null ){ - start._private.active = false; - updateStartStyle = true; - start.trigger( new $$.Event(e, {type: "unactivate"}) ); - } - - if (e.touches[2]) { - r.data.bgActivePosistion = undefined; - } else if (e.touches[1]) { - - } else if (e.touches[0]) { - - // Last touch released - } else if (!e.touches[0]) { - - r.data.bgActivePosistion = undefined; - - if (start != null ) { - - if (start._private.grabbed == true) { - start._private.grabbed = false; - start.trigger(new $$.Event(e, {type: "free"})); - start._private.rscratch.inDragLayer = false; - } - - var sEdges = start._private.edges; - for (var j=0;j - this.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2ax, - rs.cp2ay, - rs.selfEdgeMidX, - rs.selfEdgeMidY))) - || - (this.inBezierVicinity(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].value/2, 2)) - && - (Math.pow(edges[i]._private.style["width"].value/2, 2) + edgeThreshold > - this.sqDistanceToQuadraticBezier(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY)))) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "straight") { - if (this.inLineVicinity(x, y, rs.startX, rs.startY, rs.endX, rs.endY, edges[i]._private.style["width"].value * 2) - && - Math.pow(edges[i]._private.style["width"].value / 2, 2) + edgeThreshold > - this.sqDistanceToFiniteLine(x, y, - rs.startX, - rs.startY, - rs.endX, - rs.endY)) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "bezier") { - if (this.inBezierVicinity(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].value / 2, 2)) - && - (Math.pow(edges[i]._private.style["width"].value / 2 , 2) + edgeThreshold > - this.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY))) - { addCurrentEdge = true; } - } - - if (!near.length || near[near.length - 1] != edges[i]) { - if ((arrowShapes[edges[i]._private.style["source-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].value), - this.getArrowHeight(edges[i]._private.style["width"].value), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0) - && - arrowShapes[edges[i]._private.style["source-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].value), - this.getArrowHeight(edges[i]._private.style["width"].value), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0)) - || - (arrowShapes[edges[i]._private.style["target-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].value), - this.getArrowHeight(edges[i]._private.style["width"].value), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0) - && - arrowShapes[edges[i]._private.style["target-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].value), - this.getArrowHeight(edges[i]._private.style["width"].value), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0))) - { addCurrentEdge = true; } - } - - if (addCurrentEdge) { - if (visibleElementsOnly) { - // For edges, make sure the edge is visible/has nonzero opacity, - // then also make sure both source and target nodes are visible/have - // nonzero opacity - var source = data.cy.getElementById(edges[i]._private.data.source) - var target = data.cy.getElementById(edges[i]._private.data.target) - - if (edges[i]._private.style["opacity"].value != 0 - && edges[i]._private.style["visibility"].value == "visible" - && source._private.style["opacity"].value != 0 - && source._private.style["visibility"].value == "visible" - && target._private.style["opacity"].value != 0 - && target._private.style["visibility"].value == "visible") { - - near.push(edges[i]); - } - } else { - near.push(edges[i]); - } - } - } - - near.sort( zOrderSort ); - - if (near.length > 0) { return near[ near.length - 1 ]; } else { return null; } - } - - // "Give me everything from this box" - CanvasRenderer.prototype.getAllInBox = function(x1, y1, x2, y2) { - var data = this.data; var nodes = this.getCachedNodes(); var edges = this.getCachedEdges(); var box = []; - - var x1c = Math.min(x1, x2); var x2c = Math.max(x1, x2); var y1c = Math.min(y1, y2); var y2c = Math.max(y1, y2); x1 = x1c; x2 = x2c; y1 = y1c; y2 = y2c; var heur; - - for (var i=0;i= 0; i--) - { - if (elements[i].isNode() && - (elements[i]._private.style["width"].value == "auto" || - elements[i]._private.style["height"].value == "auto") && - elements[i].children().length > 0) - { - var node = elements[i]; - var bounds = this.calcCompoundBounds(node); - - //console.log("%s : %o", node._private.data.id, bounds); - node._private.position.x = bounds.x; - node._private.position.y = bounds.y; - node._private.autoWidth = bounds.width; - node._private.autoHeight = bounds.height; - } - } - - }; - - /** - * Calculates rectangular bounds of a given compound node. - * If the node is hidden, or none of its children is visible, - * then instead of calculating the bounds, returns the last - * calculated value. - * - * @param node a node with children (compound node) - * @return {{x: number, y: number, width: number, height: number}} - */ - CanvasRenderer.prototype.calcCompoundBounds = function(node) - { - // TODO assuming rectangular compounds, we may add support for other shapes in the future - - // this selection doesn't work if parent is invisible - //var children = node.children(":visible").not(":removed"); - - // consider only not removed children - var children = node.descendants().not(":removed"); - - // TODO instead of last calculated width & height define a default compound node size? - // last calculated bounds - var bounds = {x: node._private.position.x, - y: node._private.position.y, - width: node._private.autoWidth, - height: node._private.autoHeight}; - - // check node visibility - if (node._private.style["visibility"].value != "visible") - { - // do not calculate bounds for invisible compounds, - // just return last calculated values - return bounds; - } - - var visibleChildren = []; - - // find out visible children - for (var i=0; i < children.size(); i++) - { - if (children[i]._private.style["visibility"].value == "visible") - { - visibleChildren.push(children[i]); - } - } - - if (visibleChildren.length == 0) - { - // no visible children, just return last calculated values - return bounds; - } - - // process only visible children - children = visibleChildren; - - // find the leftmost, rightmost, topmost, and bottommost child node positions - var leftBorder = this.borderValue(children, "left"); - var rightBorder = this.borderValue(children, "right"); - var topBorder = this.borderValue(children, "top"); - var bottomBorder = this.borderValue(children, "bottom"); - - // take padding values into account in addition to border values - var padding = this.getNodePadding(node); - var x = (leftBorder - padding.left + rightBorder + padding.right) / 2; - var y = (topBorder - padding.top + bottomBorder + padding.bottom) / 2; - var width = (rightBorder - leftBorder) + padding.left + padding.right; - var height = (bottomBorder - topBorder) + padding.top + padding.bottom; - - // it is not possible to use the function boundingBox() before - // actually rendering the graph -// var bBox = children.boundingBox(); -// -// var x = (bBox.x1 + bBox.x2) / 2; -// var y = (bBox.y1 + bBox.y2) / 2; -// var width = bBox.width; -// var height = bBox.height; - - bounds = {x: x, - y: y, - width: width, - height: height}; - - return bounds; - }; - - /** - * Calculates the leftmost, rightmost, topmost or bottommost point for the given - * set of nodes. If the type parameter is "left" (or "right"), then the min (or - * the max) x-coordinate value will be returned. If the type is "top" (or "bottom") - * then the min (or the max) y-coordinate value will be returned. - * - * This function is designed to help determining the bounds (bounding box) of - * compound nodes. - * - * @param nodes set of nodes - * @param type "left", "right", "top", "bottom" - * @return {number} border value for the specified type - */ - CanvasRenderer.prototype.borderValue = function(nodes, type) - { - var nodeVals, labelVals; - var minValue = 1/0, maxValue = -1/0; - var r = this; - - // helper function to determine node position and dimensions - var calcNodePosAndDim = function(node) { - var values = {}; - - values.x = node._private.position.x; - values.y = node._private.position.y; - //values.width = r.getNodeWidth(node); - //values.height = r.getNodeHeight(node); - values.width = node.outerWidth(); - values.height = node.outerHeight(); - - return values; - }; - - // helper function to determine label width - var getLabelWidth = function(node) - { - var text = String(node._private.style["content"].value); - var textTransform = node._private.style["text-transform"].value; - - if (textTransform == "none") { - } else if (textTransform == "uppercase") { - text = text.toUpperCase(); - } else if (textTransform == "lowercase") { - text = text.toLowerCase(); - } - - // TODO width doesn't measure correctly without actually rendering - var context = r.data.canvases[4].getContext("2d"); - return context.measureText(text).width; - }; - - // helper function to determine label position and dimensions - var calcLabelPosAndDim = function(node) { - - var values = {}; - var nodeWidth = r.getNodeWidth(node); - var nodeHeight = r.getNodeHeight(node); - - - values.height = node._private.style["font-size"].value; - - // TODO ignoring label width for now, it may be a good idea to do so, - // since longer label texts may increase the node size unnecessarily - //values.width = getLabelWidth(node); - values.width = values.height; - - var textHalign = node._private.style["text-halign"].strValue; - - if (textHalign == "left") { - values.x = node._private.position.x - nodeWidth / 2; - values.left = values.x - values.width; - values.right = values.x; - } else if (textHalign == "right") { - values.x = node._private.position.x + nodeWidth / 2; - values.left = values.x; - values.right = values.x + values.width; - } else { //if (textHalign == "center") - values.x = node._private.position.x; - values.left = values.x - values.width / 2; - values.right = values.x + values.width / 2; - } - - var textValign = node._private.style["text-valign"].strValue; - - if (textValign == "top") { - values.y = node._private.position.y - nodeHeight / 2; - values.top = values.y - values.height; - values.bottom = values.y; - } else if (textValign == "bottom") { - values.y = node._private.position.y + nodeHeight / 2; - values.top = values.y; - values.bottom = values.y + values.height; - } else { // if (textValign == "middle" || textValign == "center") - values.y = node._private.position.y; - values.top = values.y - values.height / 2; - values.bottom = values.y + values.height / 2; - } - - return values; - }; - - - - // find out border values by iterating given nodes - - for (i = 0; i < nodes.length; i++) - { - nodeVals = calcNodePosAndDim(nodes[i]); - labelVals = calcLabelPosAndDim(nodes[i]); - - if (type == "left") - { - var leftBorder = Math.min(nodeVals.x - nodeVals.width / 2, - labelVals.left); - - if (leftBorder < minValue) - { - minValue = leftBorder; - } - } - else if (type == "right") - { - var rightBorder = Math.max(nodeVals.x + nodeVals.width / 2, - labelVals.right); - - if (rightBorder > maxValue) - { - maxValue = rightBorder; - } - } - else if (type == "top") - { - var topBorder = Math.min(nodeVals.y - nodeVals.height / 2, - labelVals.top); - - if (topBorder < minValue) - { - minValue = topBorder; - } - } - else if (type == "bottom") - { - var bottomBorder = Math.max(nodeVals.y + nodeVals.height / 2, - labelVals.bottom); - - if (bottomBorder > maxValue) - { - maxValue = bottomBorder; - } - } - } - - // return the border value according to the type - - if ((type == "left") || (type == "top")) - { - return minValue; - } - else - { - return maxValue; - } - }; - - /** - * Returns the width of the given node. If the width is set to auto, - * returns the value of the autoWidth field. - * - * @param node a node - * @return {number} width of the node - */ - CanvasRenderer.prototype.getNodeWidth = function(node) - { - if (node._private.style["width"].value == "auto" || - node._private.style["height"].value == "auto") - { - return node._private.autoWidth; - } - else - { - return node._private.style["width"].value; - } - }; - - /** - * Returns the height of the given node. If the height is set to auto, - * returns the value of the autoHeight field. - * - * @param node a node - * @return {number} width of the node - */ - CanvasRenderer.prototype.getNodeHeight = function(node) - { - if (node._private.style["width"].value == "auto" || - node._private.style["height"].value == "auto") - { - return node._private.autoHeight; - } - else - { - return node._private.style["height"].value; - } - }; - - /** - * Returns the shape of the given node. If the height or width of the given node - * is set to auto, the node is considered to be a compound. - * - * @param node a node - * @return {String} shape of the node - */ - CanvasRenderer.prototype.getNodeShape = function(node) - { - // TODO only allow rectangle for a compound node? -// if (node._private.style["width"].value == "auto" || -// node._private.style["height"].value == "auto") -// { -// return "rectangle"; -// } - - var shape = node._private.style["shape"].value; - - if( node.isParent() ){ - if( shape === 'rectangle' || shape === 'roundrectangle' ){ - return shape; - } else { - return 'rectangle'; - } - } - - return shape; - }; - - CanvasRenderer.prototype.getNodePadding = function(node) - { - var left = node._private.style["padding-left"].value; - var right = node._private.style["padding-right"].value; - var top = node._private.style["padding-top"].value; - var bottom = node._private.style["padding-bottom"].value; - - if (isNaN(left)) - { - left = 0; - } - - if (isNaN(right)) - { - right = 0; - } - - if (isNaN(top)) - { - top = 0; - } - - if (isNaN(bottom)) - { - bottom = 0; - } - - return {left : left, - right : right, - top : top, - bottom : bottom}; - }; - - // @O Keyboard functions - { - } - - // @O Drawing functions - { - - // Resize canvas - CanvasRenderer.prototype.matchCanvasSize = function(container) { - var data = this.data; var width = container.clientWidth; var height = container.clientHeight; - - var canvas, canvasWidth = width, canvasHeight = height; - - if ('devicePixelRatio' in window) { - canvasWidth *= devicePixelRatio; - canvasHeight *= devicePixelRatio; - } - - for (var i = 0; i < CANVAS_LAYERS; i++) { - - canvas = data.canvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - - canvas.style.width = width + 'px'; - canvas.style.height = height + 'px'; - } - } - - for (var i = 0; i < BUFFER_COUNT; i++) { - - canvas = data.bufferCanvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - } - } - - this.data.overlay.style.width = width + 'px'; - this.data.overlay.style.height = height + 'px'; - } - - - // helper function for the sort operation - var elementDepth = function(ele) { - if (ele._private.group == "nodes") - { - return ele.parents().size(); - } - else if (ele._private.group == "edges") - { - return Math.max(ele.source()[0].parents().size(), - ele.target()[0].parents().size()); - } - else - { - return 0; - } - }; - - - CanvasRenderer.prototype.getCachedZSortedEles = function(){ - var lastNodes = this.lastZOrderCachedNodes; - var lastEdges = this.lastZOrderCachedEdges; - var nodes = this.getCachedNodes(); - var edges = this.getCachedEdges(); - var eles = []; - - if( !lastNodes || !lastEdges || lastNodes !== nodes || lastEdges !== edges ){ - //console.time('cachezorder') - - for( var i = 0; i < nodes.length; i++ ){ - eles.push( nodes[i] ); - } - - for( var i = 0; i < edges.length; i++ ){ - eles.push( edges[i] ); - } - - eles.sort( zOrderSort ); - this.cachedZSortedEles = eles; - //console.log('make cache') - - //console.timeEnd('cachezorder') - } else { - eles = this.cachedZSortedEles; - //console.log('read cache') - } - - this.lastZOrderCachedNodes = nodes; - this.lastZOrderCachedEdges = edges; - - return eles; - }; - - - var zOrderSort = function(a, b) { - var result = a._private.style["z-index"].value - - b._private.style["z-index"].value; - - var depthA = 0; - var depthB = 0; - - // no need to calculate element depth if there is no compound node - if ( a.cy().hasCompoundNodes() ) - { - depthA = elementDepth(a); - depthB = elementDepth(b); - } - - // if both elements has same depth, - // then edges should be drawn first - if (depthA - depthB === 0) - { - // "a" is a node, it should be drawn later - if (a._private.group === "nodes" - && b._private.group === "edges") - { - return 1; - } - - // "a" is an edge, it should be drawn first - else if (a._private.group === "edges" - && b._private.group === "nodes") - { - return -1; - } - - // both nodes or both edges - else - { - if( result === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top) - return a._private.index - b._private.index; - } else { - return result; - } - } - } - - // elements on different level - else - { - // deeper element should be drawn later - return depthA - depthB; - } - - // return zero if z-index values are not the same - return 0; - }; - - CanvasRenderer.prototype.renderTo = function( cxt, zoom, pan ){ - this.redraw( cxt, true, zoom, pan ); - }; - - // Redraw frame - CanvasRenderer.prototype.redraw = function( forcedContext, drawAll, forcedZoom, forcedPan ) { - var r = this; - - if( this.averageRedrawTime === undefined ){ this.averageRedrawTime = 0; } - - var minRedrawLimit = 1000/60; // people can't see much better than 60fps - var maxRedrawLimit = 1000; // don't cap max b/c it's more important to be responsive than smooth - - var redrawLimit = this.averageRedrawTime; // estimate the ideal redraw limit based on how fast we can draw - - redrawLimit = Math.max(minRedrawLimit, redrawLimit); - redrawLimit = Math.min(redrawLimit, maxRedrawLimit); - - //console.log('--\nideal: %i; effective: %i', this.averageRedrawTime, redrawLimit); - - if( this.lastDrawTime === undefined ){ this.lastDrawTime = 0; } - - var nowTime = +new Date; - var timeElapsed = nowTime - this.lastDrawTime; - var callAfterLimit = timeElapsed >= redrawLimit; - - if( !forcedContext ){ - if( !callAfterLimit ){ - clearTimeout( this.redrawTimeout ); - this.redrawTimeout = setTimeout(function(){ - r.redraw(); - }, redrawLimit); - - return; - } - - this.lastDrawTime = nowTime; - } - - - // start on thread ready - setTimeout(function(){ - - var startTime = nowTime; - - var looperMax = 100; - //console.log('-- redraw --') - - // console.time('init'); for( var looper = 0; looper <= looperMax; looper++ ){ - - var cy = r.data.cy; var data = r.data; - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - r.matchCanvasSize(data.container); - - var zoom = cy.zoom(); - var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom; - var pan = cy.pan(); - var effectivePan = { - x: pan.x, - y: pan.y - }; - - if( forcedPan ){ - effectivePan = forcedPan; - } - - if( 'devicePixelRatio' in window ){ - effectiveZoom *= devicePixelRatio; - effectivePan.x *= devicePixelRatio; - effectivePan.y *= devicePixelRatio; - } - - var elements = []; - for( var i = 0; i < nodes.length; i++ ){ - elements.push( nodes[i] ); - } - for( var i = 0; i < edges.length; i++ ){ - elements.push( edges[i] ); - } - - // } console.timeEnd('init') - - - - if (data.canvasNeedsRedraw[DRAG] || data.canvasNeedsRedraw[NODE] || drawAll) { - //NB : VERY EXPENSIVE - //console.time('edgectlpts'); for( var looper = 0; looper <= looperMax; looper++ ){ - - if( r.hideEdgesOnViewport && (r.pinching || r.hoverData.dragging || r.data.wheel || r.swipePanning) ){ - } else { - r.findEdgeControlPoints(edges); - } - - //} console.timeEnd('edgectlpts') - - - - // console.time('sort'); for( var looper = 0; looper <= looperMax; looper++ ){ - var elements = r.getCachedZSortedEles(); - // } console.timeEnd('sort') - - // console.time('updatecompounds'); for( var looper = 0; looper <= looperMax; looper++ ){ - // no need to update graph if there is no compound node - if ( cy.hasCompoundNodes() ) - { - r.updateAllCompounds(elements); - } - // } console.timeEnd('updatecompounds') - } - - var elesInDragLayer; - var elesNotInDragLayer; - var element; - - - // console.time('drawing'); for( var looper = 0; looper <= looperMax; looper++ ){ - if (data.canvasNeedsRedraw[NODE] || drawAll) { - // console.log("redrawing node layer", data.canvasRedrawReason[NODE]); - - if( !elesInDragLayer || !elesNotInDragLayer ){ - elesInDragLayer = []; - elesNotInDragLayer = []; - - for (var index = 0; index < elements.length; index++) { - element = elements[index]; - - if ( element._private.rscratch.inDragLayer ) { - elesInDragLayer.push( element ); - } else { - elesNotInDragLayer.push( element ); - } - } - } - - var context = forcedContext || data.canvases[NODE].getContext("2d"); - - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - if( !drawAll ){ - context.translate(effectivePan.x, effectivePan.y); - context.scale(effectiveZoom, effectiveZoom); - } - if( forcedPan ){ - context.translate(forcedPan.x, forcedPan.y); - } - if( forcedZoom ){ - context.scale(forcedZoom, forcedZoom); - } - - for (var index = 0; index < elesNotInDragLayer.length; index++) { - element = elesNotInDragLayer[index]; - - if (element._private.group == "nodes") { - r.drawNode(context, element); - - } else if (element._private.group == "edges") { - r.drawEdge(context, element); - } - } - - for (var index = 0; index < elesNotInDragLayer.length; index++) { - element = elesNotInDragLayer[index]; - - if (element._private.group == "nodes") { - r.drawNodeText(context, element); - } else if (element._private.group == "edges") { - r.drawEdgeText(context, element); - } - - // draw the overlay - if (element._private.group == "nodes") { - r.drawNode(context, element, true); - } else if (element._private.group == "edges") { - r.drawEdge(context, element, true); - } - } - - if( !drawAll ){ - data.canvasNeedsRedraw[NODE] = false; data.canvasRedrawReason[NODE] = []; - } - } - - if (data.canvasNeedsRedraw[DRAG] || drawAll) { - // console.log("redrawing drag layer", data.canvasRedrawReason[DRAG]); - - if( !elesInDragLayer || !elesNotInDragLayer ){ - elesInDragLayer = []; - elesNotInDragLayer = []; - - for (var index = 0; index < elements.length; index++) { - element = elements[index]; - - if ( element._private.rscratch.inDragLayer ) { - elesInDragLayer.push( element ); - } else { - elesNotInDragLayer.push( element ); - } - } - } - - var context = forcedContext || data.canvases[DRAG].getContext("2d"); - - if( !drawAll ){ - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - context.translate(effectivePan.x, effectivePan.y); - context.scale(effectiveZoom, effectiveZoom); - } - if( forcedPan ){ - context.translate(forcedPan.x, forcedPan.y); - } - if( forcedZoom ){ - context.scale(forcedZoom, forcedZoom); - } - - var element; - - for (var index = 0; index < elesInDragLayer.length; index++) { - element = elesInDragLayer[index]; - - if (element._private.group == "nodes") { - r.drawNode(context, element); - } else if (element._private.group == "edges") { - r.drawEdge(context, element); - } - } - - for (var index = 0; index < elesInDragLayer.length; index++) { - element = elesInDragLayer[index]; - - if (element._private.group == "nodes") { - r.drawNodeText(context, element); - } else if (element._private.group == "edges") { - r.drawEdgeText(context, element); - } - - // draw the overlay - if (element._private.group == "nodes") { - r.drawNode(context, element, true); - } else if (element._private.group == "edges") { - r.drawEdge(context, element, true); - } - } - - if( !drawAll ){ - data.canvasNeedsRedraw[DRAG] = false; data.canvasRedrawReason[DRAG] = []; - } - } - - if (data.canvasNeedsRedraw[SELECT_BOX]) { - // console.log("redrawing selection box", data.canvasRedrawReason[SELECT_BOX]); - - var context = forcedContext || data.canvases[SELECT_BOX].getContext("2d"); - - if( !drawAll ){ - context.setTransform(1, 0, 0, 1, 0, 0); - context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - context.translate(effectivePan.x, effectivePan.y); - context.scale(effectiveZoom, effectiveZoom); - } - if( forcedPan ){ - context.translate(forcedPan.x, forcedPan.y); - } - if( forcedZoom ){ - context.scale(forcedZoom, forcedZoom); - } - - var coreStyle = cy.style()._private.coreStyle; - - if (data.select[4] == 1) { - var zoom = data.cy.zoom(); - var borderWidth = coreStyle["selection-box-border-width"].value / zoom; - - context.lineWidth = borderWidth; - context.fillStyle = "rgba(" - + coreStyle["selection-box-color"].value[0] + "," - + coreStyle["selection-box-color"].value[1] + "," - + coreStyle["selection-box-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.fillRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - - if (borderWidth > 0) { - context.strokeStyle = "rgba(" - + coreStyle["selection-box-border-color"].value[0] + "," - + coreStyle["selection-box-border-color"].value[1] + "," - + coreStyle["selection-box-border-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.strokeRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - } - } - - if( data.bgActivePosistion ){ - var zoom = data.cy.zoom(); - var pos = data.bgActivePosistion; - - context.fillStyle = "rgba(" - + coreStyle["active-bg-color"].value[0] + "," - + coreStyle["active-bg-color"].value[1] + "," - + coreStyle["active-bg-color"].value[2] + "," - + coreStyle["active-bg-opacity"].value + ")"; - - context.beginPath(); - context.arc(pos.x, pos.y, coreStyle["active-bg-size"].pxValue / zoom, 0, 2 * Math.PI); - context.fill(); - } - - if( !drawAll ){ - data.canvasNeedsRedraw[SELECT_BOX] = false; data.canvasRedrawReason[SELECT_BOX] = []; - } - } - - if( r.options.showOverlay ){ - var context = data.canvases[OVERLAY].getContext("2d"); - - context.lineJoin = 'round'; - context.font = '14px helvetica'; - context.strokeStyle = '#fff'; - context.lineWidth = '4'; - context.fillStyle = '#666'; - context.textAlign = 'right'; - - var text = 'cytoscape.js'; - - var w = context.canvas.width; - var h = context.canvas.height; - var p = 4; - var tw = context.measureText(text).width; - var th = 14; - - context.clearRect(0, 0, w, h); - context.strokeText(text, w - p, h - p); - context.fillText(text, w - p, h - p); - - data.overlayDrawn = true; - } - - // } console.timeEnd('drawing') - - var endTime = +new Date; - - if( r.averageRedrawTime === undefined ){ - r.averageRedrawTime = endTime - startTime; - } - - // use a weighted average with a bias from the previous average so we don't spike so easily - r.averageRedrawTime = r.averageRedrawTime/2 + (endTime - startTime)/2; - //console.log('actual: %i, average: %i', endTime - startTime, this.averageRedrawTime); - - - // end on thread ready - }, 0); - }; - - var imageCache = {}; - - // Discard after 5 min. of disuse - var IMAGE_KEEP_TIME = 30 * 300; // 300frames@30fps, or. 5min - - CanvasRenderer.prototype.getCachedImage = function(url, onLoadRedraw) { - - if (imageCache[url] && imageCache[url].image) { - - // Reset image discard timer - imageCache[url].keepTime = IMAGE_KEEP_TIME; - return imageCache[url].image; - } - - var imageContainer = imageCache[url]; - - if (imageContainer == undefined) { - imageCache[url] = new Object(); - imageCache[url].image = new Image(); - imageCache[url].image.onload = onLoadRedraw; - - imageCache[url].image.src = url; - - // Initialize image discard timer - imageCache[url].keepTime = IMAGE_KEEP_TIME; - - imageContainer = imageCache[url]; - } - - return imageContainer.image; - } - - // Attempt to replace the image object with a canvas buffer to solve zooming problem - CanvasRenderer.prototype.swapCachedImage = function(url) { - if (imageCache[url]) { - - if (imageCache[url].image - && imageCache[url].image.complete) { - - var image = imageCache[url].image; - - var buffer = document.createElement("canvas"); - buffer.width = image.width; - buffer.height = image.height; - - buffer.getContext("2d").drawImage(image, - 0, 0 - ); - - imageCache[url].image = buffer; - imageCache[url].swappedWithCanvas = true; - - return buffer; - } else { - return null; - } - } else { - return null; - } - } - - CanvasRenderer.prototype.updateImageCaches = function() { - - for (var url in imageCache) { - if (imageCache[url].keepTime <= 0) { - - if (imageCache[url].image != undefined) { - imageCache[url].image.src = undefined; - imageCache[url].image = undefined; - } - - imageCache[url] = undefined; - } else { - imageCache[url] -= 1; - } - } - } - - CanvasRenderer.prototype.drawImage = function(context, x, y, widthScale, heightScale, rotationCW, image) { - - image.widthScale = 0.5; - image.heightScale = 0.5; - - image.rotate = rotationCW; - - var finalWidth; var finalHeight; - - canvas.drawImage(image, x, y); - } - - // Draw edge - CanvasRenderer.prototype.drawEdge = function(context, edge, drawOverlayInstead) { - - if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching - - var startNode, endNode; - - startNode = edge.source()[0]; - endNode = edge.target()[0]; - - if (edge._private.style["visibility"].value != "visible" - || startNode._private.style["visibility"].value != "visible" - || endNode._private.style["visibility"].value != "visible") { - return; - } - - var overlayPadding = edge._private.style["overlay-padding"].value; - var overlayOpacity = edge._private.style["overlay-opacity"].value; - var overlayColor = edge._private.style["overlay-color"].value; - - // Edge color & opacity - if( drawOverlayInstead ){ - context.strokeStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - context.lineCap = "round"; - - if( edge._private.rscratch.edgeType == "self"){ - context.lineCap = "butt"; - } - - } else { - context.strokeStyle = "rgba(" - + edge._private.style["line-color"].value[0] + "," - + edge._private.style["line-color"].value[1] + "," - + edge._private.style["line-color"].value[2] + "," - + edge._private.style.opacity.value + ")"; - } - - // Edge line width - if (edge._private.style["width"].value <= 0) { - return; - } - - var edgeWidth = edge._private.style["width"].value + (drawOverlayInstead ? 2 * overlayPadding : 0); - var lineStyle = drawOverlayInstead ? "solid" : edge._private.style["line-style"].value; - context.lineWidth = edgeWidth; - - this.findEndpoints(edge); - - if (edge._private.rscratch.edgeType == "self") { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, details.cp2ax, - details.cp2ay, details.selfEdgeMidX, details.selfEdgeMidY], - lineStyle, - edgeWidth); - - this.drawStyledEdge(edge, context, [details.selfEdgeMidX, details.selfEdgeMidY, - details.cp2cx, details.cp2cy, details.endX, details.endY], - lineStyle, - edgeWidth); - - } else if (edge._private.rscratch.edgeType == "straight") { - - var nodeDirectionX = endNode._private.position.x - startNode._private.position.x; - var nodeDirectionY = endNode._private.position.y - startNode._private.position.y; - - var edgeDirectionX = edge._private.rscratch.endX - edge._private.rscratch.startX; - var edgeDirectionY = edge._private.rscratch.endY - edge._private.rscratch.startY; - - if (nodeDirectionX * edgeDirectionX - + nodeDirectionY * edgeDirectionY < 0) { - - edge._private.rscratch.straightEdgeTooShort = true; - } else { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.endX, details.endY], - lineStyle, - edgeWidth); - - edge._private.rscratch.straightEdgeTooShort = false; - } - } else { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.cp2x, details.cp2y, details.endX, details.endY], - lineStyle, - edgeWidth); - - } - - if (edge._private.rscratch.noArrowPlacement !== true - && edge._private.rscratch.startX !== undefined) { - this.drawArrowheads(context, edge, drawOverlayInstead); - } - - } - - var _genPoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[4] - pt[0], 2) + Math.pow(pt[5] - pt[1], 2)); - approxLen += Math.sqrt(Math.pow((pt[4] + pt[0]) / 2 - pt[2], 2) + Math.pow((pt[5] + pt[1]) / 2 - pt[3], 2)); - - var pts = Math.ceil(approxLen / spacing); var inc = approxLen / spacing; - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = pt[0] * (1 - cur) * (1 - cur) + 2 * (pt[2]) * (1 - cur) * cur + pt[4] * (cur) * (cur); - pz[i * 2 + 1] = pt[1] * (1 - cur) * (1 - cur) + 2 * (pt[3]) * (1 - cur) * cur + pt[5] * (cur) * (cur); - } - - return pz; - } - - var _genStraightLinePoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[2] - pt[0], 2) + Math.pow(pt[3] - pt[1], 2)); - - var pts = Math.ceil(approxLen / spacing); - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - var lineOffset = [pt[2] - pt[0], pt[3] - pt[1]]; - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = lineOffset[0] * cur + pt[0]; - pz[i * 2 + 1] = lineOffset[1] * cur + pt[1]; - } - - return pz; - } - - var _genEvenOddpts = function(pt, evenspac, oddspac) { - - pt1 = _genpts(pt, evenspac); - pt2 = _genpts(pt, oddspac); - } - - CanvasRenderer.prototype.createBuffer = function(w, h) { - var buffer = document.createElement("canvas"); - buffer.width = w; - buffer.height = h; - - return [buffer, buffer.getContext("2d")]; - } - - /* - CanvasRenderer.prototype. - - CanvasRenderer.prototype.drawStraightEdge = function(context, x1, y1, x2, y2, type, width) { - - if (type == "solid") { - context.beginPath(); - context.moveTo( - edge._private.rscratch.startX, - edge._private.rscratch.startY); - - - context.stroke(); - } else if (type == "dotted") { - var pt = _genStraightLinePoints([x1, y1, x2, y2], 10, false); - - - } else if (type == "dashed") { - var pt = _genStraightLinePoints([x1, y1, x2, y2], 10, false); - } - - } - */ - - CanvasRenderer.prototype.drawStyledEdge = function( - edge, context, pts, type, width) { - - // 3 points given -> assume Bezier - // 2 -> assume straight - - var cy = this.data.cy; - var zoom = cy.zoom(); - - // Adjusted edge width for dotted -// width = Math.max(width * 1.6, 3.4) * zoom; - - // console.log("w", width); - - // from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves - function qbezierAt(p0, p1, p2, t){ - return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2; - } - - if( edge._private.rstyle.bezierPts === undefined ){ - edge._private.rstyle.bezierPts = []; - } - - var nBpts = edge._private.rstyle.bezierPts.length; - if( edge.isLoop() ){ - if( nBpts >= 12 ){ - edge._private.rstyle.bezierPts = []; - } else { - // append to current array - } - } else { - edge._private.rstyle.bezierPts = []; - } - - var bpts = edge._private.rstyle.bezierPts; - - if( pts.length === 6 ){ - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.05 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.05 ) - }); - - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.25 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.25 ) - }); - - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.35 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.35 ) - }); - - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.65 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.65 ) - }); - - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.75 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.75 ) - }); - - bpts.push({ - x: qbezierAt( pts[0], pts[2], pts[4], 0.95 ), - y: qbezierAt( pts[1], pts[3], pts[5], 0.95 ) - }); - } - - if (type == "solid") { - - context.beginPath(); - context.moveTo(pts[0], pts[1]); - if (pts.length == 3 * 2) { - context.quadraticCurveTo(pts[2], pts[3], pts[4], pts[5]); - } else { - context.lineTo(pts[2], pts[3]); - } -// context.closePath(); - context.stroke(); - - } else if (type == "dotted") { - - var pt; - if (pts.length == 3 * 2) { - pt = _genPoints(pts, 16, true); - } else { - pt = _genStraightLinePoints(pts, 16, true); - } - - if (!pt) { return; } - - var dotRadius = Math.max(width * 1.6, 3.4) * zoom; - var bufW = dotRadius * 2, bufH = dotRadius * 2; - bufW = Math.max(bufW, 1); - bufH = Math.max(bufH, 1); - - var buffer = this.createBuffer(bufW, bufH); - - var context2 = buffer[1]; -// console.log(buffer); -// console.log(bufW, bufH); - - // Draw on buffer - context2.setTransform(1, 0, 0, 1, 0, 0); - context2.clearRect(0, 0, bufW, bufH); - - context2.fillStyle = context.strokeStyle; - context2.beginPath(); - context2.arc(bufW/2, bufH/2, dotRadius * 0.5, 0, Math.PI * 2, false); - context2.fill(); - - // Now use buffer - context.beginPath(); - //context.save(); - - for (var i=0; i 0) { - context.stroke(); - } - - - // draw the overlay - } else { - - var overlayPadding = node._private.style["overlay-padding"].value; - var overlayOpacity = node._private.style["overlay-opacity"].value; - var overlayColor = node._private.style["overlay-color"].value; - if( overlayOpacity > 0 ){ - context.fillStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - - nodeShapes[this.getNodeShape(node)].draw( - context, - node._private.position.x, - node._private.position.y, - nodeWidth + overlayPadding * 2, - nodeHeight + overlayPadding * 2 - ); - } - } - - }; - - CanvasRenderer.prototype.drawInscribedImage = function(context, img, node) { - var r = this; -// console.log(this.data); - var zoom = this.data.cy._private.zoom; - - var nodeX = node._private.position.x; - var nodeY = node._private.position.y; - - //var nodeWidth = node._private.style["width"].value; - //var nodeHeight = node._private.style["height"].value; - var nodeWidth = this.getNodeWidth(node); - var nodeHeight = this.getNodeHeight(node); - - context.save(); - - nodeShapes[r.getNodeShape(node)].drawPath( - context, - nodeX, nodeY, - nodeWidth, nodeHeight); - - context.clip(); - -// context.setTransform(1, 0, 0, 1, 0, 0); - - var imgDim = [img.width, img.height]; - context.drawImage(img, - nodeX - imgDim[0] / 2, - nodeY - imgDim[1] / 2, - imgDim[0], - imgDim[1]); - - context.restore(); - - if (node._private.style["border-width"].value > 0) { - context.stroke(); - } - - }; - - // Draw node text - CanvasRenderer.prototype.drawNodeText = function(context, node) { - - if (node._private.style["visibility"].value != "visible") { - return; - } - - var computedSize = node._private.style["font-size"].pxValue * node.cy().zoom(); - var minSize = node._private.style["min-zoomed-font-size"].pxValue; - - if( computedSize < minSize ){ - return; - } - - var textX, textY; - - //var nodeWidth = node._private.style["width"].value; - //var nodeHeight = node._private.style["height"].value; - var nodeWidth = this.getNodeWidth(node); - var nodeHeight = this.getNodeHeight(node); - - // Find text position - var textHalign = node._private.style["text-halign"].strValue; - if (textHalign == "left") { - // Align right boundary of text with left boundary of node - context.textAlign = "right"; - textX = node._private.position.x - nodeWidth / 2; - } else if (textHalign == "right") { - // Align left boundary of text with right boundary of node - context.textAlign = "left"; - textX = node._private.position.x + nodeWidth / 2; - } else if (textHalign == "center") { - context.textAlign = "center"; - textX = node._private.position.x; - } else { - // Same as center - context.textAlign = "center"; - textX = node._private.position.x; - } - - var textValign = node._private.style["text-valign"].strValue; - if (textValign == "top") { - context.textBaseline = "bottom"; - textY = node._private.position.y - nodeHeight / 2; - } else if (textValign == "bottom") { - context.textBaseline = "top"; - textY = node._private.position.y + nodeHeight / 2; - } else if (textValign == "middle" || textValign == "center") { - context.textBaseline = "middle"; - textY = node._private.position.y; - } else { - // same as center - context.textBaseline = "middle"; - textY = node._private.position.y; - } - - this.drawText(context, node, textX, textY); - }; - - // Draw text - CanvasRenderer.prototype.drawText = function(context, element, textX, textY) { - - var parentOpacity = 1; - var parents = element.parents(); - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var opacity = parent._private.style.opacity.value; - - parentOpacity = opacity * parentOpacity; - - if( opacity === 0 ){ - return; - } - } - - // Font style - var labelStyle = element._private.style["font-style"].strValue; - var labelSize = element._private.style["font-size"].value + "px"; - var labelFamily = element._private.style["font-family"].strValue; - var labelVariant = element._private.style["font-variant"].strValue; - var labelWeight = element._private.style["font-weight"].strValue; - - context.font = labelStyle + " " + labelWeight + " " - + labelSize + " " + labelFamily; - - var text = String(element._private.style["content"].value); - var textTransform = element._private.style["text-transform"].value; - - if (textTransform == "none") { - } else if (textTransform == "uppercase") { - text = text.toUpperCase(); - } else if (textTransform == "lowercase") { - text = text.toLowerCase(); - } - - // Calculate text draw position based on text alignment - - // so text outlines aren't jagged - context.lineJoin = 'round'; - - context.fillStyle = "rgba(" - + element._private.style["color"].value[0] + "," - + element._private.style["color"].value[1] + "," - + element._private.style["color"].value[2] + "," - + (element._private.style["text-opacity"].value - * element._private.style["opacity"].value * parentOpacity) + ")"; - - context.strokeStyle = "rgba(" - + element._private.style["text-outline-color"].value[0] + "," - + element._private.style["text-outline-color"].value[1] + "," - + element._private.style["text-outline-color"].value[2] + "," - + (element._private.style["text-opacity"].value - * element._private.style["opacity"].value * parentOpacity) + ")"; - - if (text != undefined) { - var lineWidth = 2 * element._private.style["text-outline-width"].value; // *2 b/c the stroke is drawn centred on the middle - if (lineWidth > 0) { - context.lineWidth = lineWidth; - context.strokeText(text, textX, textY); - } - - // Thanks sysord@github for the isNaN checks! - if (isNaN(textX)) { textX = 0; } - if (isNaN(textY)) { textY = 0; } - - context.fillText("" + text, textX, textY); - - // record the text's width for use in bounding box calc - element._private.rstyle.labelWidth = context.measureText( text ).width; - } - }; - - CanvasRenderer.prototype.drawBackground = function(context, color1, color2, - startPosition, endPosition) { - - - } - - // @O Edge calculation functions - { - - // Find edge control points - CanvasRenderer.prototype.findEdgeControlPoints = function(edges) { - var hashTable = {}; var cy = this.data.cy; - var pairIds = []; - - var pairId; - for (var i = 0; i < edges.length; i++) { - pairId = edges[i]._private.data.source > edges[i]._private.data.target ? - edges[i]._private.data.target + '-' + edges[i]._private.data.source : - edges[i]._private.data.source + '-' + edges[i]._private.data.target ; - - if (hashTable[pairId] == undefined) { - hashTable[pairId] = []; - } - - hashTable[pairId].push( edges[i] ); - pairIds.push( pairId ); - } - var src, tgt; - - // Nested for loop is OK; total number of iterations for both loops = edgeCount - for (var p = 0; p < pairIds.length; p++) { - pairId = pairIds[p]; - - src = cy.getElementById( hashTable[pairId][0]._private.data.source ); - tgt = cy.getElementById( hashTable[pairId][0]._private.data.target ); - - var midPointX = (src._private.position.x + tgt._private.position.x) / 2; - var midPointY = (src._private.position.y + tgt._private.position.y) / 2; - - var displacementX, displacementY; - - if (hashTable[pairId].length > 1) { - displacementX = tgt._private.position.y - src._private.position.y; - displacementY = src._private.position.x - tgt._private.position.x; - - var displacementLength = Math.sqrt(displacementX * displacementX - + displacementY * displacementY); - - displacementX /= displacementLength; - displacementY /= displacementLength; - } - - var edge; - - for (var i = 0; i < hashTable[pairId].length; i++) { - edge = hashTable[pairId][i]; - - var edgeIndex1 = edge._private.rscratch.lastEdgeIndex; - var edgeIndex2 = i; - - var numEdges1 = edge._private.rscratch.lastNumEdges; - var numEdges2 = hashTable[pairId].length; - - var srcX1 = edge._private.rscratch.lastSrcCtlPtX; - var srcX2 = src._private.position.x; - var srcY1 = edge._private.rscratch.lastSrcCtlPtY; - var srcY2 = src._private.position.y; - var srcW1 = edge._private.rscratch.lastSrcCtlPtW; - var srcW2 = src.outerWidth(); - var srcH1 = edge._private.rscratch.lastSrcCtlPtH; - var srcH2 = src.outerHeight(); - - var tgtX1 = edge._private.rscratch.lastTgtCtlPtX; - var tgtX2 = tgt._private.position.x; - var tgtY1 = edge._private.rscratch.lastTgtCtlPtY; - var tgtY2 = tgt._private.position.y; - var tgtW1 = edge._private.rscratch.lastTgtCtlPtW; - var tgtW2 = tgt.outerWidth(); - var tgtH1 = edge._private.rscratch.lastTgtCtlPtH; - var tgtH2 = tgt.outerHeight(); - - if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2 - && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2 - && edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2 ){ - // console.log('edge ctrl pt cache HIT') - continue; // then the control points haven't changed and we can skip calculating them - } else { - var rs = edge._private.rscratch; - - rs.lastSrcCtlPtX = srcX2; - rs.lastSrcCtlPtY = srcY2; - rs.lastSrcCtlPtW = srcW2; - rs.lastSrcCtlPtH = srcH2; - rs.lastTgtCtlPtX = tgtX2; - rs.lastTgtCtlPtY = tgtY2; - rs.lastTgtCtlPtW = tgtW2; - rs.lastTgtCtlPtH = tgtH2; - rs.lastEdgeIndex = edgeIndex2; - rs.lastNumEdges = numEdges2; - // console.log('edge ctrl pt cache MISS') - } - - // Self-edge - if (src._private.data.id == tgt._private.data.id) { - var stepSize = edge._private.style["control-point-step-size"].pxValue; - - edge._private.rscratch.edgeType = "self"; - - // New -- fix for large nodes - edge._private.rscratch.cp2ax = src._private.position.x; - edge._private.rscratch.cp2ay = src._private.position.y - - (1 + Math.pow(this.getNodeHeight(src), 1.12) / 100) * stepSize * (i / 3 + 1); - - edge._private.rscratch.cp2cx = src._private.position.x - - (1 + Math.pow(this.getNodeWidth(src), 1.12) / 100) * stepSize * (i / 3 + 1); - edge._private.rscratch.cp2cy = src._private.position.y; - - edge._private.rscratch.selfEdgeMidX = - (edge._private.rscratch.cp2ax + edge._private.rscratch.cp2cx) / 2.0; - - edge._private.rscratch.selfEdgeMidY = - (edge._private.rscratch.cp2ay + edge._private.rscratch.cp2cy) / 2.0; - - // Straight edge - } else if (hashTable[pairId].length % 2 == 1 - && i == Math.floor(hashTable[pairId].length / 2)) { - - edge._private.rscratch.edgeType = "straight"; - - // Bezier edge - } else { - var stepSize = edge._private.style["control-point-step-size"].value; - var distanceFromMidpoint = (0.5 - hashTable[pairId].length / 2 + i) * stepSize; - - edge._private.rscratch.edgeType = "bezier"; - - edge._private.rscratch.cp2x = midPointX - + displacementX * distanceFromMidpoint; - edge._private.rscratch.cp2y = midPointY - + displacementY * distanceFromMidpoint; - - // console.log(edge, midPointX, displacementX, distanceFromMidpoint); - } - } - } - - return hashTable; - } - - CanvasRenderer.prototype.findEndpoints = function(edge) { - var intersect; - - var source = edge.source()[0]; - var target = edge.target()[0]; - -// var sourceRadius = Math.max(edge.source()[0]._private.style["width"].value, -// edge.source()[0]._private.style["height"].value); - - var sourceRadius = Math.max(this.getNodeWidth(source), - this.getNodeHeight(source)); - -// var targetRadius = Math.max(edge.target()[0]._private.style["width"].value, -// edge.target()[0]._private.style["height"].value); - - var targetRadius = Math.max(this.getNodeWidth(target), - this.getNodeHeight(target)); - - sourceRadius = 0; - targetRadius /= 2; - - var start = [edge.source().position().x, edge.source().position().y]; - var end = [edge.target().position().x, edge.target().position().y]; - - if (edge._private.rscratch.edgeType == "self") { - - var cp = [edge._private.rscratch.cp2cx, edge._private.rscratch.cp2cy]; - - intersect = nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - //target._private.style["width"].value, - //target._private.style["height"].value, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], //halfPointX, - cp[1], //halfPointY - target._private.style["border-width"].value / 2 - ); - - var arrowEnd = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["target-arrow-shape"].value].spacing(edge)); - var edgeEnd = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["target-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.endX = edgeEnd[0]; - edge._private.rscratch.endY = edgeEnd[1]; - - edge._private.rscratch.arrowEndX = arrowEnd[0]; - edge._private.rscratch.arrowEndY = arrowEnd[1]; - - var cp = [edge._private.rscratch.cp2ax, edge._private.rscratch.cp2ay]; - - intersect = nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - //source._private.style["width"].value, - //source._private.style["height"].value, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - source._private.style["border-width"].value / 2 - ); - - var arrowStart = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["source-arrow-shape"].value].spacing(edge)); - var edgeStart = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["source-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.startX = edgeStart[0]; - edge._private.rscratch.startY = edgeStart[1]; - - edge._private.rscratch.arrowStartX = arrowStart[0]; - edge._private.rscratch.arrowStartY = arrowStart[1]; - - } else if (edge._private.rscratch.edgeType == "straight") { - - intersect = nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - //target._private.style["width"].value, - //target._private.style["height"].value, - this.getNodeWidth(target), - this.getNodeHeight(target), - source.position().x, - source.position().y, - target._private.style["border-width"].value / 2); - - if (intersect.length == 0) { - edge._private.rscratch.noArrowPlacement = true; - // return; - } else { - edge._private.rscratch.noArrowPlacement = false; - } - - var arrowEnd = this.shortenIntersection(intersect, - [source.position().x, source.position().y], - arrowShapes[edge._private.style["target-arrow-shape"].value].spacing(edge)); - var edgeEnd = this.shortenIntersection(intersect, - [source.position().x, source.position().y], - arrowShapes[edge._private.style["target-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.endX = edgeEnd[0]; - edge._private.rscratch.endY = edgeEnd[1]; - - edge._private.rscratch.arrowEndX = arrowEnd[0]; - edge._private.rscratch.arrowEndY = arrowEnd[1]; - - intersect = nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - //source._private.style["width"].value, - //source._private.style["height"].value, - this.getNodeWidth(source), - this.getNodeHeight(source), - target.position().x, - target.position().y, - source._private.style["border-width"].value / 2); - - if (intersect.length == 0) { - edge._private.rscratch.noArrowPlacement = true; - // return; - } else { - edge._private.rscratch.noArrowPlacement = false; - } - - /* - console.log("1: " - + arrowShapes[edge._private.style["source-arrow-shape"].value], - edge._private.style["source-arrow-shape"].value); - */ - var arrowStart = this.shortenIntersection(intersect, - [target.position().x, target.position().y], - arrowShapes[edge._private.style["source-arrow-shape"].value].spacing(edge)); - var edgeStart = this.shortenIntersection(intersect, - [target.position().x, target.position().y], - arrowShapes[edge._private.style["source-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.startX = edgeStart[0]; - edge._private.rscratch.startY = edgeStart[1]; - - edge._private.rscratch.arrowStartX = arrowStart[0]; - edge._private.rscratch.arrowStartY = arrowStart[1]; - - } else if (edge._private.rscratch.edgeType == "bezier") { - - var cp = [edge._private.rscratch.cp2x, edge._private.rscratch.cp2y]; - - // Point at middle of Bezier - var halfPointX = start[0] * 0.25 + end[0] * 0.25 + cp[0] * 0.5; - var halfPointY = start[1] * 0.25 + end[1] * 0.25 + cp[1] * 0.5; - - intersect = nodeShapes[ - this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - //target._private.style["width"].value, - //target._private.style["height"].value, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], //halfPointX, - cp[1], //halfPointY - target._private.style["border-width"].value / 2 - ); - - /* - console.log("2: " - + arrowShapes[edge._private.style["source-arrow-shape"].value], - edge._private.style["source-arrow-shape"].value); - */ - var arrowEnd = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["target-arrow-shape"].value].spacing(edge)); - var edgeEnd = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["target-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.endX = edgeEnd[0]; - edge._private.rscratch.endY = edgeEnd[1]; - - edge._private.rscratch.arrowEndX = arrowEnd[0]; - edge._private.rscratch.arrowEndY = arrowEnd[1]; - - intersect = nodeShapes[ - this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - //source._private.style["width"].value, - //source._private.style["height"].value, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - source._private.style["border-width"].value / 2 - ); - - var arrowStart = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["source-arrow-shape"].value].spacing(edge)); - var edgeStart = this.shortenIntersection(intersect, cp, - arrowShapes[edge._private.style["source-arrow-shape"].value].gap(edge)); - - edge._private.rscratch.startX = edgeStart[0]; - edge._private.rscratch.startY = edgeStart[1]; - - edge._private.rscratch.arrowStartX = arrowStart[0]; - edge._private.rscratch.arrowStartY = arrowStart[1]; - - } else if (edge._private.rscratch.isArcEdge) { - return; - } - } - - } - - // @O Graph traversal functions - { - - // Find adjacent edges - CanvasRenderer.prototype.findEdges = function(nodeSet) { - - var edges = this.getCachedEdges(); - - var hashTable = {}; - var adjacentEdges = []; - - for (var i = 0; i < nodeSet.length; i++) { - hashTable[nodeSet[i]._private.data.id] = nodeSet[i]; - } - - for (var i = 0; i < edges.length; i++) { - if (hashTable[edges[i]._private.data.source] - || hashTable[edges[i]._private.data.target]) { - - adjacentEdges.push(edges[i]); - } - } - - return adjacentEdges; - } - - } - - // @O Intersection functions - { - CanvasRenderer.prototype.intersectLineEllipse = function( - x, y, centerX, centerY, ellipseWradius, ellipseHradius) { - - var dispX = centerX - x; - var dispY = centerY - y; - - dispX /= ellipseWradius; - dispY /= ellipseHradius; - - var len = Math.sqrt(dispX * dispX + dispY * dispY); - - var newLength = len - 1; - - if (newLength < 0) { - return []; - } - - var lenProportion = newLength / len; - - return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y]; - } - - CanvasRenderer.prototype.dotProduct = function( - vec1, vec2) { - - if (vec1.length != 2 || vec2.length != 2) { - throw 'dot product: arguments are not vectors'; - } - - return (vec1[0] * vec2[0] + vec1[1] * vec2[1]); - } - - // Returns intersections of increasing distance from line's start point - CanvasRenderer.prototype.intersectLineCircle = function( - x1, y1, x2, y2, centerX, centerY, radius) { - - // Calculate d, direction vector of line - var d = [x2 - x1, y2 - y1]; // Direction vector of line - var s = [x1, y1]; // Start of line - var c = [centerX, centerY]; // Center of circle - var f = [x1 - centerX, y1 - centerY] - - var a = d[0] * d[0] + d[1] * d[1]; - var b = 2 * (f[0] * d[0] + f[1] * d[1]); - var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ; - - /* - var a = this.dotProduct(d, d); - var b = 2 * this.dotProduct(s, d) - this.dotProduct(d, c); - var c = this.dotProduct(s, s) - 2 * this.dotProduct(s, c) + this.dotProduct(c, c) - radius * radius ; - */ - - var discriminant = b*b-4*a*c; - - if (discriminant < 0) { - return []; - } - - t1 = (-b + Math.sqrt(discriminant)) / (2 * a); - t2 = (-b - Math.sqrt(discriminant)) / (2 * a); - - var tMin = Math.min(t1, t2); - var tMax = Math.max(t1, t2); - var inRangeParams = []; - - if (tMin >= 0 && tMin <= 1) { - inRangeParams.push(tMin); - } - - if (tMax >= 0 && tMax <= 1) { - inRangeParams.push(tMax); - } - - if (inRangeParams.length == 0) { - return []; - } - - var nearIntersectionX = inRangeParams[0] * d[0] + x1; - var nearIntersectionY = inRangeParams[0] * d[1] + y1; - - if (inRangeParams.length > 1) { - - if (inRangeParams[0] == inRangeParams[1]) { - return [nearIntersectionX, nearIntersectionY]; - } else { - - var farIntersectionX = inRangeParams[1] * d[0] + x1; - var farIntersectionY = inRangeParams[1] * d[1] + y1; - - return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY]; - } - - } else { - return [nearIntersectionX, nearIntersectionY] - } - - } - - CanvasRenderer.prototype.findCircleNearPoint = function(centerX, centerY, - radius, farX, farY) { - - var displacementX = farX - centerX; - var displacementY = farY - centerY; - var distance = Math.sqrt(displacementX * displacementX - + displacementY * displacementY); - - var unitDisplacementX = displacementX / distance; - var unitDisplacementY = displacementY / distance; - - return [centerX + unitDisplacementX * radius, - centerY + unitDisplacementY * radius]; - } - - CanvasRenderer.prototype.findMaxSqDistanceToOrigin = function(points) { - var maxSqDistance = 0.000001; - var sqDistance; - - for (var i = 0; i < points.length / 2; i++) { - - sqDistance = points[i * 2] * points[i * 2] - + points[i * 2 + 1] * points[i * 2 + 1]; - - if (sqDistance > maxSqDistance) { - maxSqDistance = sqDistance; - } - } - - return maxSqDistance; - } - - CanvasRenderer.prototype.finiteLinesIntersect = function( - x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { - - var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); - var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); - var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - - if (u_b != 0) { - var ua = ua_t / u_b; - var ub = ub_t / u_b; - - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - - } else { - if (!infiniteLines) { - return []; - } else { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - } - } - } else { - if (ua_t == 0 || ub_t == 0) { - - // Parallel, coincident lines. Check if overlap - - // Check endpoint of second line - if ([x1, x2, x4].sort()[1] == x4) { - return [x4, y4]; - } - - // Check start point of second line - if ([x1, x2, x3].sort()[1] == x3) { - return [x3, y3]; - } - - // Endpoint of first line - if ([x3, x4, x2].sort()[1] == x2) { - return [x2, y2]; - } - - return []; - } else { - - // Parallel, non-coincident - return []; - } - } - } - - // (boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - // cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - - CanvasRenderer.prototype.boxIntersectEllipse = function( - x1, y1, x2, y2, padding, width, height, centerX, centerY) { - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - // 4 ortho extreme points - var west = [centerX - width / 2 - padding, centerY]; - var east = [centerX + width / 2 + padding, centerY]; - var north = [centerX, centerY - height / 2 - padding]; - var south = [centerX, centerY + height / 2 + padding]; - - // out of bounds: return false - if (x2 < west[0]) { - return false; - } - - if (x1 > east[0]) { - return false; - } - - if (y1 > south[1]) { - return false; - } - - if (y2 < north[1]) { - return false; - } - - // 1 of 4 ortho extreme points in box: return true - if (x1 <= east[0] && east[0] <= x2 - && y1 <= east[1] && east[1] <= y2) { - return true; - } - - if (x1 <= west[0] && west[0] <= x2 - && y1 <= west[1] && west[1] <= y2) { - return true; - } - - if (x1 <= north[0] && north[0] <= x2 - && y1 <= north[1] && north[1] <= y2) { - return true; - } - - if (x1 <= south[0] && south[0] <= x2 - && y1 <= south[1] && south[1] <= y2) { - return true; - } - - // box corner in ellipse: return true - x1 = (x1 - centerX) / (width / 2 + padding); - x2 = (x2 - centerX) / (width / 2 + padding); - - y1 = (y1 - centerY) / (height / 2 + padding); - y2 = (y2 - centerY) / (height / 2 + padding); - - if (x1 * x1 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y2 * y2 <= 1) { - return true; - } - - if (x1 * x1 + y2 * y2 <= 1) { - return true; - } - - return false; - } - - CanvasRenderer.prototype.boxIntersectPolygon = function( - x1, y1, x2, y2, basePoints, width, height, centerX, centerY, direction, padding) { - -// console.log(arguments); - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - var transformedPoints = new Array(basePoints.length) - - // Gives negative of angle - var angle = Math.asin(direction[1] / (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - if (direction[0] < 0) { - angle = angle + Math.PI / 2; - } else { - angle = -angle - Math.PI / 2; - } - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = - width / 2 * (basePoints[i * 2] * cos - - basePoints[i * 2 + 1] * sin); - - transformedPoints[i * 2 + 1] = - height / 2 * (basePoints[i * 2 + 1] * cos - + basePoints[i * 2] * sin); - - transformedPoints[i * 2] += centerX; - transformedPoints[i * 2 + 1] += centerY; - } - - // Assume transformedPoints.length > 0, and check if intersection is possible - var minTransformedX = transformedPoints[0]; - var maxTransformedX = transformedPoints[0]; - var minTransformedY = transformedPoints[1]; - var maxTransformedY = transformedPoints[1]; - - for (var i = 1; i < transformedPoints.length / 2; i++) { - if (transformedPoints[i * 2] > maxTransformedX) { - maxTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2] < minTransformedX) { - minTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2 + 1] > maxTransformedY) { - maxTransformedY = transformedPoints[i * 2 + 1]; - } - - if (transformedPoints[i * 2 + 1] < minTransformedY) { - minTransformedY = transformedPoints[i * 2 + 1]; - } - } - - if (x2 < minTransformedX - padding) { - return false; - } - - if (x1 > maxTransformedX + padding) { - return false; - } - - if (y2 < minTransformedY - padding) { - return false; - } - - if (y1 > maxTransformedY + padding) { - return false; - } - - // Continue checking with padding-corrected points - var points; - - if (padding > 0) { - var expandedLineSet = renderer.expandPolygon( - transformedPoints, - -padding); - - points = renderer.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - // Check if a point is in box - for (var i = 0; i < transformedPoints.length / 2; i++) { - if (x1 <= transformedPoints[i * 2] - && transformedPoints[i * 2] <= x2) { - - if (y1 <= transformedPoints[i * 2 + 1] - && transformedPoints[i * 2 + 1] <= y2) { - - return true; - } - } - } - - - // Check for intersections with the selection box - for (var i = 0; i < points.length / 2; i++) { - - var currentX = points[i * 2]; - var currentY = points[i * 2 + 1]; - var nextX; - var nextY; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1] - } else { - nextX = points[0]; - nextY = points[1]; - } - - // Intersection with top of selection box - if (renderer.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x2, y1, false).length > 0) { - return true; - } - - // Intersection with bottom of selection box - if (renderer.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y2, x2, y2, false).length > 0) { - return true; - } - - // Intersection with left side of selection box - if (renderer.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x1, y2, false).length > 0) { - return true; - } - - // Intersection with right side of selection box - if (renderer.finiteLinesIntersect(currentX, currentY, nextX, nextY, x2, y1, x2, y2, false).length > 0) { - return true; - } - } - - /* - // Check if box corner in the polygon - if (renderer.pointInsidePolygon( - x1, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if (renderer.pointInsidePolygon( - x1, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if (renderer.pointInsidePolygon( - x2, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if (renderer.pointInsidePolygon( - x2, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } - */ - return false; - } - - CanvasRenderer.prototype.polygonIntersectLine = function( - x, y, basePoints, centerX, centerY, width, height, padding) { - - var intersections = []; - var intersection; - - var transformedPoints = new Array(basePoints.length); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = basePoints[i * 2] * width + centerX; - transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY; - } - - var points; - - if (padding > 0) { - var expandedLineSet = renderer.expandPolygon( - transformedPoints, - -padding); - - points = renderer.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - // var points = transformedPoints; - - var currentX, currentY, nextX, nextY; - - for (var i = 0; i < points.length / 2; i++) { - - currentX = points[i * 2]; - currentY = points[i * 2 + 1]; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1]; - } else { - nextX = points[0]; - nextY = points[1]; - } - - intersection = this.finiteLinesIntersect( - x, y, centerX, centerY, - currentX, currentY, - nextX, nextY); - - if (intersection.length != 0) { - intersections.push(intersection[0], intersection[1]); - } - } - - return intersections; - } - - CanvasRenderer.prototype.shortenIntersection = function( - intersection, offset, amount) { - - var disp = [intersection[0] - offset[0], intersection[1] - offset[1]]; - - var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]); - - var lenRatio = (length - amount) / length; - - if (lenRatio < 0) { - return []; - } else { - return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]]; - } - } - } - - // @O Arrow shapes - { - // Contract for arrow shapes: - { - // 0, 0 is arrow tip - // (0, 1) is direction towards node - // (1, 0) is right - // - // functional api: - // collide: check x, y in shape - // roughCollide: called before collide, no false negatives - // draw: draw - // spacing: dist(arrowTip, nodeBoundary) - // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip - } - - // Declarations - { - arrowShapes["arrow"] = { - _points: [ - -0.15, -0.3, - 0, 0, - 0.15, -0.3 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["arrow"]._points; - -// console.log("collide(): " + direction); - - return rendFunc.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["arrow"]._farthestPointSqDistance) == "undefined") { - arrowShapes["arrow"]._farthestPointSqDistance = - rendFunc.findMaxSqDistanceToOrigin(arrowShapes["arrow"]._points); - } - - return rendFunc.checkInBoundingCircle( - x, y, arrowShapes["arrow"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["arrow"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].value * 2; - } - } - - arrowShapes["triangle"] = arrowShapes["arrow"]; - - arrowShapes["none"] = { - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - draw: function(context) { - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return 0; - } - } - - arrowShapes["circle"] = { - _baseRadius: 0.15, - - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - // Transform x, y to get non-rotated ellipse - - if (width != height) { - // This gives negative of the angle - var angle = Math.asin(direction[1] / - (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - var rotatedPoint = - [x * cos - y * sin, - y * cos + x * sin]; - - var aspectRatio = (height + padding) / (width + padding); - y /= aspectRatio; - centerY /= aspectRatio; - - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } else { - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return true; - }, - draw: function(context) { - context.arc(0, 0, arrowShapes["circle"]._baseRadius, 0, Math.PI * 2, false); - }, - spacing: function(edge) { - return rendFunc.getArrowWidth(edge._private.style["width"].value) - * arrowShapes["circle"]._baseRadius; - }, - gap: function(edge) { - return edge._private.style["width"].value * 2; - } - } - - arrowShapes["inhibitor"] = { - _points: [ - -0.25, 0, - -0.25, -0.1, - 0.25, -0.1, - 0.25, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["inhibitor"]._points; - - return rendFunc.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["inhibitor"]._farthestPointSqDistance) == "undefined") { - arrowShapes["inhibitor"]._farthestPointSqDistance = - rendFunc.findMaxSqDistanceToOrigin(arrowShapes["inhibitor"]._points); - } - - return rendFunc.checkInBoundingCircle( - x, y, arrowShapes["inhibitor"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["inhibitor"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 4; - }, - gap: function(edge) { - return 4; - } - } - - arrowShapes["square"] = { - _points: [ - -0.12, 0.00, - 0.12, 0.00, - 0.12, -0.24, - -0.12, -0.24 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["square"]._points; - - return rendFunc.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["square"]._farthestPointSqDistance) == "undefined") { - arrowShapes["square"]._farthestPointSqDistance = - rendFunc.findMaxSqDistanceToOrigin(arrowShapes["square"]._points); - } - - return rendFunc.checkInBoundingCircle( - x, y, arrowShapes["square"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["square"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].value * 2; - } - } - - arrowShapes["diamond"] = { - _points: [ - -0.14, -0.14, - 0, -0.28, - 0.14, -0.14, - 0, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["diamond"]._points; - - return rendFunc.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["diamond"]._farthestPointSqDistance) == "undefined") { - arrowShapes["diamond"]._farthestPointSqDistance = - rendFunc.findMaxSqDistanceToOrigin(arrowShapes["diamond"]._points); - } - - return rendFunc.checkInBoundingCircle( - x, y, arrowShapes["diamond"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { -// context.translate(0, 0.16); - context.lineTo(-0.14, -0.14); - context.lineTo(0, -0.28); - context.lineTo(0.14, -0.14); - context.lineTo(0, 0.0); - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].value * 2; - } - } - - arrowShapes["tee"] = arrowShapes["inhibitor"]; - } - - // @O Arrow shape sizing (w + l) - { - - CanvasRenderer.prototype.getArrowWidth = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - CanvasRenderer.prototype.getArrowHeight = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - } - - // @O Arrow shape drawing - - // Draw arrowheads on edge - CanvasRenderer.prototype.drawArrowheads = function(context, edge, drawOverlayInstead) { - if( drawOverlayInstead ){ return; } // don't do anything for overlays - - // Displacement gives direction for arrowhead orientation - var dispX, dispY; - - var startX = edge._private.rscratch.arrowStartX; - var startY = edge._private.rscratch.arrowStartY; - - dispX = startX - edge.source().position().x; - dispY = startY - edge.source().position().y; - - //this.context.strokeStyle = "rgba(" - context.fillStyle = "rgba(" - + edge._private.style["source-arrow-color"].value[0] + "," - + edge._private.style["source-arrow-color"].value[1] + "," - + edge._private.style["source-arrow-color"].value[2] + "," - + edge._private.style.opacity.value + ")"; - - context.lineWidth = edge._private.style["width"].value; - - this.drawArrowShape(context, edge._private.style["source-arrow-shape"].value, - startX, startY, dispX, dispY); - - var endX = edge._private.rscratch.arrowEndX; - var endY = edge._private.rscratch.arrowEndY; - - dispX = endX - edge.target().position().x; - dispY = endY - edge.target().position().y; - - //this.context.strokeStyle = "rgba(" - context.fillStyle = "rgba(" - + edge._private.style["target-arrow-color"].value[0] + "," - + edge._private.style["target-arrow-color"].value[1] + "," - + edge._private.style["target-arrow-color"].value[2] + "," - + edge._private.style.opacity.value + ")"; - - context.lineWidth = edge._private.style["width"].value; - - this.drawArrowShape(context, edge._private.style["target-arrow-shape"].value, - endX, endY, dispX, dispY); - } - - // Draw arrowshape - CanvasRenderer.prototype.drawArrowShape = function(context, shape, x, y, dispX, dispY) { - - // Negative of the angle - var angle = Math.asin(dispY / (Math.sqrt(dispX * dispX + dispY * dispY))); - - if (dispX < 0) { - //context.strokeStyle = "AA99AA"; - angle = angle + Math.PI / 2; - } else { - //context.strokeStyle = "AAAA99"; - angle = - (Math.PI / 2 + angle); - } - - //context.save(); - context.translate(x, y); - - context.moveTo(0, 0); - context.rotate(-angle); - - var size = this.getArrowWidth(context.lineWidth); - /// size = 100; - context.scale(size, size); - - context.beginPath(); - - arrowShapes[shape].draw(context); - - context.closePath(); - -// context.stroke(); - context.fill(); - - context.scale(1/size, 1/size); - context.rotate(angle); - context.translate(-x, -y); - //context.restore(); - } - - } - - // @O Node shapes - { - - // Generate polygon points - var generateUnitNgonPoints = function(sides, rotationRadians) { - - var increment = 1.0 / sides * 2 * Math.PI; - var startAngle = sides % 2 == 0 ? - Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0; -// console.log(nodeShapes["square"]); - startAngle += rotationRadians; - - var points = new Array(sides * 2); - - var currentAngle; - for (var i = 0; i < sides; i++) { - currentAngle = i * increment + startAngle; - - points[2 * i] = Math.cos(currentAngle);// * (1 + i/2); - points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2); - } - - // The above generates points for a polygon inscribed in a radius 1 circle. - // Stretch so that the maximum of the height and width becomes 2 so the resulting - // scaled shape appears to be inscribed inside a rectangle with the given - // width and height. The maximum of the width and height is used to preserve - // the shape's aspect ratio. - - // Stretch width - var maxAbsX = 0 - var maxAbsY = 0; - for (var i = 0; i < points.length / 2; i++) { - if (Math.abs(points[2 * i] > maxAbsX)) { - maxAbsX = Math.abs(points[2 * i]); - } - - if (Math.abs(points[2 * i + 1] > maxAbsY)) { - maxAbsY = Math.abs(points[2 * i + 1]); - } - } - - var minScaleLimit = 0.0005; - - // Use the larger dimension to do the scale, in order to preserve the shape's - // aspect ratio - var maxDimension = Math.max(maxAbsX, maxAbsY); - - for (var i = 0; i < points.length / 2; i++) { - if (maxDimension > minScaleLimit) { - points[2 * i] *= (1 / maxDimension); - points[2 * i + 1] *= (1 / maxDimension); - } - } - - return points; - } - - // Node shape declarations - - // Contract for node shapes: - { - // Node shape contract: - // - // draw: draw - // intersectLine: report intersection from x, y, to node center - // checkPointRough: heuristic check x, y in node, no false negatives - // checkPoint: check x, y in node - } - - // Declarations - { - - var renderer = rendFunc; - - nodeShapes["ellipse"] = { - draw: function(context, centerX, centerY, width, height) { - nodeShapes["ellipse"].drawPath(context, centerX, centerY, width, height); - context.fill(); - -// console.log("drawing ellipse"); -// console.log(arguments); - }, - - drawPath: function(context, centerX, centerY, width, height) { - - //context.save(); - - context.beginPath(); - context.translate(centerX, centerY); - context.scale(width / 2, height / 2); - // At origin, radius 1, 0 to 2pi - context.arc(0, 0, 1, 0, Math.PI * 2 * 0.999, false); // *0.999 b/c chrome rendering bug on full circle - context.closePath(); - - context.scale(2/width, 2/height); - context.translate(-centerX, -centerY); - //context.restore(); - -// console.log("drawing ellipse"); -// console.log(arguments); - - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - var intersect = rendFunc.intersectLineEllipse( - x, y, - nodeX, - nodeY, - width / 2 + padding, - height / 2 + padding); - - return intersect; - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - return CanvasRenderer.prototype.boxIntersectEllipse( - x1, y1, x2, y2, padding, width, height, centerX, centerY); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return true; - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - -// console.log(arguments); - - x -= centerX; - y -= centerY; - - x /= (width / 2 + padding); - y /= (height / 2 + padding); - - return (Math.pow(x, 2) + Math.pow(y, 2) <= 1); - } - } - - nodeShapes["triangle"] = { - points: generateUnitNgonPoints(3, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, - nodeShapes["triangle"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, - nodeShapes["triangle"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["triangle"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - - /* - polygonIntersectLine(x, y, basePoints, centerX, centerY, - width, height, padding); - */ - - - /* - return renderer.polygonIntersectLine( - node, width, height, - x, y, nodeShapes["triangle"].points); - */ - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - var points = nodeShapes["triangle"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["triangle"].points, // Triangle? - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon( - x, y, nodeShapes["triangle"].points, - centerX, centerY, width, height, - [0, -1], padding); - } - } - - nodeShapes["square"] = { - points: generateUnitNgonPoints(4, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, - nodeShapes["square"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, - nodeShapes["square"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["square"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, - width, height, centerX, - centerY, padding) { - - var points = nodeShapes["square"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, - centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, - centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["square"].points, - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon(x, y, nodeShapes["square"].points, - centerX, centerY, width, height, [0, -1], padding); - } - } - - nodeShapes["rectangle"] = nodeShapes["square"]; - - nodeShapes["octogon"] = {}; - - nodeShapes["roundrectangle"] = { - points: generateUnitNgonPoints(4, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawRoundRectangle(context, - centerX, centerY, - width, height, - 10); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawRoundRectanglePath(context, - centerX, centerY, - width, height, - 10); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.roundRectangleIntersectLine( - x, y, - nodeX, - nodeY, - width, height, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, - width, height, centerX, - centerY, padding) { - - return renderer.roundRectangleIntersectBox( - x1, y1, x2, y2, - width, height, centerX, centerY, padding); - }, - - checkPointRough: function( - x, y, padding, width, height, - centerX, centerY) { - - // This check is OK because it assumes the round rectangle - // has sharp edges for the rough check - return renderer.checkInBoundingBox( - x, y, nodeShapes["roundrectangle"].points, - padding, width, height, centerX, centerY); - }, - - // Looks like the width passed into this function is actually the total width / 2 - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - var cornerRadius = renderer.getRoundRectangleRadius(width, height); - - // Check hBox - if (renderer.pointInsidePolygon(x, y, nodeShapes["roundrectangle"].points, - centerX, centerY, width, height - 2 * cornerRadius, [0, -1], padding)) { - return true; - } - - // Check vBox - if (renderer.pointInsidePolygon(x, y, nodeShapes["roundrectangle"].points, - centerX, centerY, width - 2 * cornerRadius, height, [0, -1], padding)) { - return true; - } - - var checkInEllipse = function(x, y, centerX, centerY, width, height, padding) { - x -= centerX; - y -= centerY; - - x /= (width / 2 + padding); - y /= (height / 2 + padding); - - return (Math.pow(x, 2) + Math.pow(y, 2) <= 1); - } - - - // Check top left quarter circle - if (checkInEllipse(x, y, - centerX - width / 2 + cornerRadius, - centerY - height / 2 + cornerRadius, - cornerRadius * 2, cornerRadius * 2, padding)) { - - return true; - } - - /* - if (renderer.boxIntersectEllipse(x, y, x, y, padding, - cornerRadius * 2, cornerRadius * 2, - centerX - width + cornerRadius, - centerY - height + cornerRadius)) { - return true; - } - */ - - // Check top right quarter circle - if (checkInEllipse(x, y, - centerX + width / 2 - cornerRadius, - centerY - height / 2 + cornerRadius, - cornerRadius * 2, cornerRadius * 2, padding)) { - - return true; - } - - // Check bottom right quarter circle - if (checkInEllipse(x, y, - centerX + width / 2 - cornerRadius, - centerY + height / 2 - cornerRadius, - cornerRadius * 2, cornerRadius * 2, padding)) { - - return true; - } - - // Check bottom left quarter circle - if (checkInEllipse(x, y, - centerX - width / 2 + cornerRadius, - centerY + height / 2 - cornerRadius, - cornerRadius * 2, cornerRadius * 2, padding)) { - - return true; - } - - return false; - } - }; - - nodeShapes["roundrectangle2"] = { - roundness: 4.99, - - draw: function(node, width, height) { - if (width <= roundness * 2) { - return; - } - - renderer.drawPolygon(node._private.position.x, - node._private.position.y, width, height, nodeSapes["roundrectangle2"].points); - }, - - intersectLine: function(node, width, height, x, y) { - return renderer.findPolygonIntersection( - node, width, height, x, y, nodeShapes["square"].points); - }, - - // TODO: Treat rectangle as sharp-cornered for now. This is a not-large approximation. - intersectBox: function(x1, y1, x2, y2, width, height, centerX, centerY, padding) { - var points = nodeShapes["square"].points; - - /* - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, - */ - } - } - - /* - function PolygonNodeShape(points) { - this.points = points; - - this.draw = function(context, node, width, height) { - renderer.drawPolygon(context, - node._private.position.x, - node._private.position.y, - width, height, nodeShapes["pentagon"].points); - }; - - this.drawPath = - } - */ - - nodeShapes["pentagon"] = { - points: generateUnitNgonPoints(5, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, nodeShapes["pentagon"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, nodeShapes["pentagon"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["pentagon"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - var points = nodeShapes["pentagon"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["pentagon"].points, - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon(x, y, nodeShapes["pentagon"].points, - centerX, centerY, width, height, [0, -1], padding); - } - } - - nodeShapes["hexagon"] = { - points: generateUnitNgonPoints(6, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, - nodeShapes["hexagon"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, - nodeShapes["hexagon"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["hexagon"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - var points = nodeShapes["hexagon"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["hexagon"].points, - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon(x, y, nodeShapes["hexagon"].points, - centerX, centerY, width, height, [0, -1], padding); - } - } - - nodeShapes["heptagon"] = { - points: generateUnitNgonPoints(7, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, - nodeShapes["heptagon"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, - nodeShapes["heptagon"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["heptagon"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - var points = nodeShapes["heptagon"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["heptagon"].points, - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon(x, y, nodeShapes["heptagon"].points, - centerX, centerY, width, height, [0, -1], padding); - } - } - - nodeShapes["octagon"] = { - points: generateUnitNgonPoints(8, 0), - - draw: function(context, centerX, centerY, width, height) { - renderer.drawPolygon(context, - centerX, centerY, - width, height, - nodeShapes["octagon"].points); - }, - - drawPath: function(context, centerX, centerY, width, height) { - renderer.drawPolygonPath(context, - centerX, centerY, - width, height, - nodeShapes["octagon"].points); - }, - - intersectLine: function(nodeX, nodeY, width, height, x, y, padding) { - return renderer.polygonIntersectLine( - x, y, - nodeShapes["octagon"].points, - nodeX, - nodeY, - width / 2, height / 2, - padding); - }, - - intersectBox: function( - x1, y1, x2, y2, width, height, centerX, centerY, padding) { - - var points = nodeShapes["octagon"].points; - - return renderer.boxIntersectPolygon( - x1, y1, x2, y2, - points, width, height, centerX, centerY, [0, -1], padding); - }, - - checkPointRough: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.checkInBoundingBox( - x, y, nodeShapes["octagon"].points, - padding, width, height, centerX, centerY); - }, - - checkPoint: function( - x, y, padding, width, height, centerX, centerY) { - - return renderer.pointInsidePolygon(x, y, nodeShapes["octagon"].points, - centerX, centerY, width, height, [0, -1], padding); - } - }; - - var star5Points = new Array(20); - { - var outerPoints = generateUnitNgonPoints(5, 0); - var innerPoints = generateUnitNgonPoints(5, Math.PI / 5); - -// console.log(outerPoints); -// console.log(innerPoints); - - // Outer radius is 1; inner radius of star is smaller - var innerRadius = 0.5 * (3 - Math.sqrt(5)); - innerRadius *= 1.57; - - for (var i=0;i 0) { - var expandedLineSet = renderer.expandPolygon( - transformedPoints, - -padding); - - points = renderer.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - var x1, y1, x2, y2; - var y3; - - // Intersect with vertical line through (x, y) - var up = 0; - var down = 0; - for (var i = 0; i < points.length / 2; i++) { - - x1 = points[i * 2]; - y1 = points[i * 2 + 1]; - - if (i + 1 < points.length / 2) { - x2 = points[(i + 1) * 2]; - y2 = points[(i + 1) * 2 + 1]; - } else { - x2 = points[(i + 1 - points.length / 2) * 2]; - y2 = points[(i + 1 - points.length / 2) * 2 + 1]; - } - -//* console.log("line from (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")"); - -//& console.log(x1, x, x2); - - if (x1 == x && x2 == x) { - - } else if ((x1 >= x && x >= x2) - || (x1 <= x && x <= x2)) { - - y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1; - - if (y3 > y) { - up++; - } - - if (y3 < y) { - down++; - } - -//* console.log(y3, y); - - } else { -//* console.log("22"); - continue; - } - - } - -//* console.log("up: " + up + ", down: " + down); - - if (up % 2 == 0) { - return false; - } else { - return true; - } - } - } - - // @O Polygon drawing - CanvasRenderer.prototype.drawPolygonPath = function( - context, x, y, width, height, points) { - - //context.save(); - - - context.translate(x, y); - context.scale(width / 2, height / 2); - - context.beginPath(); - - context.moveTo(points[0], points[1]); - - for (var i = 1; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - - context.closePath(); - - context.scale(2/width, 2/height); - context.translate(-x, -y); - // context.restore(); - } - - CanvasRenderer.prototype.drawPolygon = function( - context, x, y, width, height, points) { - - // Draw path - this.drawPolygonPath(context, x, y, width, height, points); - - // Fill path - context.fill(); - } - - CanvasRenderer.prototype.getRoundRectangleRadius = function(width, height) { - - // Set the default radius, unless half of width or height is smaller than default - return Math.min(width / 2, height / 2, 10); - } - - // Round rectangle drawing - CanvasRenderer.prototype.drawRoundRectanglePath = function( - context, x, y, width, height, radius) { - - var halfWidth = width / 2; - var halfHeight = height / 2; - var cornerRadius = this.getRoundRectangleRadius(width, height); - context.translate(x, y); - - context.beginPath(); - - // Start at top middle - context.moveTo(0, -halfHeight); - // Arc from middle top to right side - context.arcTo(halfWidth, -halfHeight, halfWidth, 0, cornerRadius); - // Arc from right side to bottom - context.arcTo(halfWidth, halfHeight, 0, halfHeight, cornerRadius); - // Arc from bottom to left side - context.arcTo(-halfWidth, halfHeight, -halfWidth, 0, cornerRadius); - // Arc from left side to topBorder - context.arcTo(-halfWidth, -halfHeight, 0, -halfHeight, cornerRadius); - // Join line - context.lineTo(0, -halfHeight); - - /* - void arc(unrestricted double x, - unrestricted double y, - unrestricted double radius, - unrestricted double startAngle, - unrestricted double endAngle, - optional boolean anticlockwise = false); - */ - /* - context.arc(-width / 2 + cornerRadius, - -height / 2 + cornerRadius, - cornerRadius, - 0, - Math.PI * 2 * 0.999); - */ - - context.closePath(); - - context.translate(-x, -y); - } - - CanvasRenderer.prototype.drawRoundRectangle = function( - context, x, y, width, height, radius) { - - this.drawRoundRectanglePath(context, x, y, width, height, radius); - - context.fill(); - } - - CanvasRenderer.prototype.roundRectangleIntersectLine = function( - x, y, nodeX, nodeY, width, height, padding) { - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var halfWidth = width / 2; - var halfHeight = height / 2; - - // Check intersections with straight line segments - var straightLineIntersections; - - // Top segment, left to right - { - var topStartX = nodeX - halfWidth + cornerRadius - padding; - var topStartY = nodeY - halfHeight - padding; - var topEndX = nodeX + halfWidth - cornerRadius + padding; - var topEndY = topStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Right segment, top to bottom - { - var rightStartX = nodeX + halfWidth + padding; - var rightStartY = nodeY - halfHeight + cornerRadius - padding; - var rightEndX = rightStartX; - var rightEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Bottom segment, left to right - { - var bottomStartX = nodeX - halfWidth + cornerRadius - padding; - var bottomStartY = nodeY + halfHeight + padding; - var bottomEndX = nodeX + halfWidth - cornerRadius + padding; - var bottomEndY = bottomStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Left segment, top to bottom - { - var leftStartX = nodeX - halfWidth - padding; - var leftStartY = nodeY - halfHeight + cornerRadius - padding; - var leftEndX = leftStartX; - var leftEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Check intersections with arc segments - var arcIntersections; - - // Top Left - { - var topLeftCenterX = nodeX - halfWidth + cornerRadius; - var topLeftCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topLeftCenterX, topLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= topLeftCenterX - && arcIntersections[1] <= topLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Top Right - { - var topRightCenterX = nodeX + halfWidth - cornerRadius; - var topRightCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topRightCenterX, topRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= topRightCenterX - && arcIntersections[1] <= topRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Right - { - var bottomRightCenterX = nodeX + halfWidth - cornerRadius; - var bottomRightCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomRightCenterX, bottomRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= bottomRightCenterX - && arcIntersections[1] >= bottomRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Left - { - var bottomLeftCenterX = nodeX - halfWidth + cornerRadius; - var bottomLeftCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= bottomLeftCenterX - && arcIntersections[1] >= bottomLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - } - - CanvasRenderer.prototype.roundRectangleIntersectBox = function( - boxX1, boxY1, boxX2, boxY2, width, height, centerX, centerY, padding) { - - // We have the following shpae - - // _____ - // _| |_ - // | | - // |_ _| - // |_____| - // - // With a quarter circle at each corner. - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var hBoxTopLeftX = centerX - width / 2 - padding; - var hBoxTopLeftY = centerY - height / 2 + cornerRadius - padding; - var hBoxBottomRightX = centerX + width / 2 + padding; - var hBoxBottomRightY = centerY + height / 2 - cornerRadius + padding; - - var vBoxTopLeftX = centerX - width / 2 + cornerRadius - padding; - var vBoxTopLeftY = centerY - height / 2 - padding; - var vBoxBottomRightX = centerX + width / 2 - cornerRadius + padding; - var vBoxBottomRightY = centerY + height / 2 + padding; - - // Check if the box is out of bounds - var boxMinX = Math.min(boxX1, boxX2); - var boxMaxX = Math.max(boxX1, boxX2); - var boxMinY = Math.min(boxY1, boxY2); - var boxMaxY = Math.max(boxY1, boxY2); - - if (boxMaxX < hBoxTopLeftX) { - return false; - } else if (boxMinX > hBoxBottomRightX) { - return false; - } - - if (boxMaxY < vBoxTopLeftY) { - return false; - } else if (boxMinY > vBoxBottomRightY) { - return false; - } - - // Check if an hBox point is in given box - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the hBox - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - // Check if an vBox point is in given box - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the vBox - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - // Lastly, check if one of the ellipses coincide with the box - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxBottomRightY - padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxBottomRightY - padding)) { - return true; - } - - return false; - } - - // @O Approximate collision functions - CanvasRenderer.prototype.checkInBoundingCircle = function( - x, y, farthestPointSqDistance, padding, width, height, centerX, centerY) { - - x = (x - centerX) / (width + padding); - y = (y - centerY) / (height + padding); - - return (x * x + y * y) <= farthestPointSqDistance; - } - - CanvasRenderer.prototype.checkInBoundingBox = function( - x, y, points, padding, width, height, centerX, centerY) { - - // Assumes width, height >= 0, points.length > 0 - - var minX = points[0], minY = points[1]; - var maxX = points[0], maxY = points[1]; - - for (var i = 1; i < points.length / 2; i++) { - - if (points[i * 2] < minX) { - minX = points[i * 2]; - } else if (points[i * 2] > maxX) { - maxX = points[i * 2]; - } - - if (points[i * 2 + 1] < minY) { - minY = points[i * 2 + 1]; - } else if (points[i * 2 + 1] > maxY) { - maxY = points[i * 2 + 1]; - } - } - - x -= centerX; - y -= centerY; - - x /= width; - y /= height; - - if (x < minX) { - return false; - } else if (x > maxX) { - return false; - } - - if (y < minY) { - return false; - } else if (y > maxY) { - return false; - } - - return true; - } - - // @O Straight/bezier edge approximate collision, precise collision, and distance calculation functions - { - CanvasRenderer.prototype.boxInBezierVicinity = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - // Return values: - // 0 - curve is not in box - // 1 - curve may be in box; needs precise check - // 2 - curve is in box - - // midpoint - var midX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var midY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { // (x1, y1) in box - return 1; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { // (x3, y3) in box - return 1; - } else if (midX >= boxMinX && midX <= boxMaxX && midY >= boxMinY && midY <= boxMaxY) { // (midX, midY) in box - return 1; - } else if (x2 >= boxMinX && x2 <= boxMaxX && y2 >= boxMinY && y2 <= boxMaxY) { // ctrl pt in box - return 1; - } - - var curveMinX = Math.min(x1, midX, x3); - var curveMinY = Math.min(y1, midY, y3); - var curveMaxX = Math.max(x1, midX, x3); - var curveMaxY = Math.max(y1, midY, y3); - - /* - console.log(curveMinX + ", " + curveMinY + ", " + curveMaxX - + ", " + curveMaxY); - if (curveMinX == undefined) { - console.log("undefined curveMinX: " + x1 + ", " + x2 + ", " + x3); - } - */ - - if (curveMinX > boxMaxX - || curveMaxX < boxMinX - || curveMinY > boxMaxY - || curveMaxY < boxMinY) { - - return 0; - } - - return 1; - } - - CanvasRenderer.prototype.checkBezierInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - - function qbezierAt(p0, p1, p2, t){ - return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2; - } - - function sampleInBox(t){ - var x = qbezierAt(x1, x2, x3, t); - var y = qbezierAt(y1, y2, y3, t); - - return x1box <= x && x <= x2box - && y1box <= y && y <= y2box - ; - } - - for( var t = 0; t <= 1; t += 0.25 ){ - if( !sampleInBox(t) ){ - return false; - } - } - - return true; - }; - - CanvasRenderer.prototype.checkStraightEdgeInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - return x1box <= x1 && x1 <= x2box - && x1box <= x2 && x2 <= x2box - && y1box <= y1 && y1 <= y2box - && y1box <= y2 && y2 <= y2box - ; - }; - - CanvasRenderer.prototype.checkStraightEdgeCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - //console.log(arguments); - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - // Check left + right bounds - var aX = x2 - x1; - var bX = x1; - var yValue; - - // Top and bottom - var aY = y2 - y1; - var bY = y1; - var xValue; - - if (Math.abs(aX) < 0.0001) { - return (x1 >= boxMinX && x1 <= boxMaxX - && Math.min(y1, y2) <= boxMinY - && Math.max(y1, y2) >= boxMaxY); - } - - var tLeft = (boxMinX - bX) / aX; - if (tLeft > 0 && tLeft <= 1) { - yValue = aY * tLeft + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tRight = (boxMaxX - bX) / aX; - if (tRight > 0 && tRight <= 1) { - yValue = aY * tRight + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tTop = (boxMinY - bY) / aY; - if (tTop > 0 && tTop <= 1) { - xValue = aX * tTop + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - var tBottom = (boxMaxY - bY) / aY; - if (tBottom > 0 && tBottom <= 1) { - xValue = aX * tBottom + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - return false; - } - - CanvasRenderer.prototype.checkBezierCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { - return true; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { - return true; - } - - var aX = x1 - 2 * x2 + x3; - var bX = -2 * x1 + 2 * x2; - var cX = x1; - - var xIntervals = []; - - if (Math.abs(aX) < 0.0001) { - var leftParam = (boxMinX - x1) / bX; - var rightParam = (boxMaxX - x1) / bX; - - xIntervals.push(leftParam, rightParam); - } else { - // Find when x coordinate of the curve crosses the left side of the box - var discriminantX1 = bX * bX - 4 * aX * (cX - boxMinX); - var tX1, tX2; - if (discriminantX1 > 0) { - var sqrt = Math.sqrt(discriminantX1); - tX1 = (-bX + sqrt) / (2 * aX); - tX2 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX1, tX2); - } - - var discriminantX2 = bX * bX - 4 * aX * (cX - boxMaxX); - var tX3, tX4; - if (discriminantX2 > 0) { - var sqrt = Math.sqrt(discriminantX2); - tX3 = (-bX + sqrt) / (2 * aX); - tX4 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX3, tX4); - } - } - - xIntervals.sort(function(a, b) { return a - b; }); - - var aY = y1 - 2 * y2 + y3; - var bY = -2 * y1 + 2 * y2; - var cY = y1; - - var yIntervals = []; - - if (Math.abs(aY) < 0.0001) { - var topParam = (boxMinY - y1) / bY; - var bottomParam = (boxMaxY - y1) / bY; - - yIntervals.push(topParam, bottomParam); - } else { - var discriminantY1 = bY * bY - 4 * aY * (cY - boxMinY); - - var tY1, tY2; - if (discriminantY1 > 0) { - var sqrt = Math.sqrt(discriminantY1); - tY1 = (-bY + sqrt) / (2 * aY); - tY2 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY1, tY2); - } - - var discriminantY2 = bY * bY - 4 * aY * (cY - boxMaxY); - - var tY3, tY4; - if (discriminantY2 > 0) { - var sqrt = Math.sqrt(discriminantY2); - tY3 = (-bY + sqrt) / (2 * aY); - tY4 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY3, tY4); - } - } - - yIntervals.sort(function(a, b) { return a - b; }); - - for (var index = 0; index < xIntervals.length; index += 2) { - for (var yIndex = 1; yIndex < yIntervals.length; yIndex += 2) { - - // Check if there exists values for the Bezier curve - // parameter between 0 and 1 where both the curve's - // x and y coordinates are within the bounds specified by the box - if (xIntervals[index] < yIntervals[yIndex] - && yIntervals[yIndex] >= 0.0 - && xIntervals[index] <= 1.0 - && xIntervals[index + 1] > yIntervals[yIndex - 1] - && yIntervals[yIndex - 1] <= 1.0 - && xIntervals[index + 1] >= 0.0) { - - return true; - } - } - } - - return false; - } - - CanvasRenderer.prototype.inLineVicinity = function(x, y, lx1, ly1, lx2, ly2, tolerance){ - var t = tolerance; - - var x1 = Math.min(lx1, lx2); - var x2 = Math.max(lx1, lx2); - var y1 = Math.min(ly1, ly2); - var y2 = Math.max(ly1, ly2); - - return x1 - t <= x && x <= x2 + t - && y1 - t <= y && y <= y2 + t; - }; - - CanvasRenderer.prototype.inBezierVicinity = function( - x, y, x1, y1, x2, y2, x3, y3, toleranceSquared) { - - // Middle point occurs when t = 0.5, this is when the Bezier - // is closest to (x2, y2) - var middlePointX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var middlePointY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - // a rough bounding box of the bezier curve - var bb = { - x1: Math.min( x1, x3, middlePointX ), - x2: Math.max( x1, x3, middlePointX ), - y1: Math.min( y1, y3, middlePointY ), - y2: Math.max( y1, y3, middlePointY ) - }; - - // if outside the rough bounding box for the bezier, then it can't be a hit - if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){ - // console.log('bezier out of rough bb') - return false; - } else { - // console.log('do more expensive check'); - } - - var displacementX, displacementY, offsetX, offsetY; - var dotProduct, dotSquared, hypSquared; - var outside = function(x, y, startX, startY, endX, endY, - toleranceSquared, counterClockwise) { - - dotProduct = (endY - startY) * (x - startX) + (startX - endX) * (y - startY); - dotSquared = dotProduct * dotProduct; - sideSquared = (endY - startY) * (endY - startY) - + (startX - endX) * (startX - endX); - - if (counterClockwise) { - if (dotProduct > 0) { - return false; - } - } else { - if (dotProduct < 0) { - return false; - } - } - - return (dotSquared / sideSquared > toleranceSquared); - }; - - // Used to check if the test polygon winding is clockwise or counterclockwise - var testPointX = (middlePointX + x2) / 2.0; - var testPointY = (middlePointY + y2) / 2.0; - - var counterClockwise = true; - - // The test point is always inside - if (outside(testPointX, testPointY, x1, y1, x2, y2, 0, counterClockwise)) { - counterClockwise = !counterClockwise; - } - - /* - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, middlePointX, middlePointY, toleranceSquared, - counterClockwise) - && !outside(x, y, middlePointX, middlePointY, x1, y1, toleranceSquared, - counterClockwise) - ); - */ - - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, x1, y1, toleranceSquared, - counterClockwise) - ); - } - - CanvasRenderer.prototype.solveCubic = function(a, b, c, d, result) { - - // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where - // r is the real component, i is the imaginary component - - // An implementation of the Cardano method from the year 1545 - // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots - - b /= a; - c /= a; - d /= a; - - var discriminant, q, r, dum1, s, t, term1, r13; - - q = (3.0 * c - (b * b)) / 9.0; - r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); - r /= 54.0; - - discriminant = q * q * q + r * r; - result[1] = 0; - term1 = (b / 3.0); - - if (discriminant > 0) { - s = r + Math.sqrt(discriminant); - s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0))); - t = r - Math.sqrt(discriminant); - t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0))); - result[0] = -term1 + s + t; - term1 += (s + t) / 2.0; - result[4] = result[2] = -term1; - term1 = Math.sqrt(3.0) * (-t + s) / 2; - result[3] = term1; - result[5] = -term1; - return; - } - - result[5] = result[3] = 0; - - if (discriminant == 0) { - r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0))); - result[0] = -term1 + 2.0 * r13; - result[4] = result[2] = -(r13 + term1); - return; - } - - q = -q; - dum1 = q * q * q; - dum1 = Math.acos(r / Math.sqrt(dum1)); - r13 = 2.0 * Math.sqrt(q); - result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); - result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); - result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); - - return; - } - - CanvasRenderer.prototype.sqDistanceToQuadraticBezier = function( - x, y, x1, y1, x2, y2, x3, y3) { - - // Find minimum distance by using the minimum of the distance - // function between the given point and the curve - - // This gives the coefficients of the resulting cubic equation - // whose roots tell us where a possible minimum is - // (Coefficients are divided by 4) - - var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3 - + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3; - - var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3 - + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3; - - var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x - + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y; - - var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x - + y1*y2 - y1*y1 + y1*y - y2*y; - - debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); - - var roots = []; - - // Use the cubic solving algorithm - this.solveCubic(a, b, c, d, roots); - - var zeroThreshold = 0.0000001; - - var params = []; - - for (var index = 0; index < 6; index += 2) { - if (Math.abs(roots[index + 1]) < zeroThreshold - && roots[index] >= 0 - && roots[index] <= 1.0) { - params.push(roots[index]); - } - } - - params.push(1.0); - params.push(0.0); - - var minDistanceSquared = -1; - var closestParam; - - var curX, curY, distSquared; - for (var i = 0; i < params.length; i++) { - curX = Math.pow(1.0 - params[i], 2.0) * x1 - + 2.0 * (1 - params[i]) * params[i] * x2 - + params[i] * params[i] * x3; - - curY = Math.pow(1 - params[i], 2.0) * y1 - + 2 * (1.0 - params[i]) * params[i] * y2 - + params[i] * params[i] * y3; - - distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); - debug("distance for param " + params[i] + ": " + Math.sqrt(distSquared)); - if (minDistanceSquared >= 0) { - if (distSquared < minDistanceSquared) { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } else { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } - - /* - debugStats.clickX = x; - debugStats.clickY = y; - - debugStats.closestX = Math.pow(1.0 - closestParam, 2.0) * x1 - + 2.0 * (1.0 - closestParam) * closestParam * x2 - + closestParam * closestParam * x3; - - debugStats.closestY = Math.pow(1.0 - closestParam, 2.0) * y1 - + 2.0 * (1.0 - closestParam) * closestParam * y2 - + closestParam * closestParam * y3; - */ - - debug("given: " - + "( " + x + ", " + y + "), " - + "( " + x1 + ", " + y1 + "), " - + "( " + x2 + ", " + y2 + "), " - + "( " + x3 + ", " + y3 + ")"); - - - debug("roots: " + roots); - debug("params: " + params); - debug("closest param: " + closestParam); - return minDistanceSquared; - } - - CanvasRenderer.prototype.sqDistanceToFiniteLine = function(x, y, x1, y1, x2, y2) { - var offset = [x - x1, y - y1]; - var line = [x2 - x1, y2 - y1]; - - var lineSq = line[0] * line[0] + line[1] * line[1]; - var hypSq = offset[0] * offset[0] + offset[1] * offset[1]; - - var dotProduct = offset[0] * line[0] + offset[1] * line[1]; - var adjSq = dotProduct * dotProduct / lineSq; - - if (dotProduct < 0) { - return hypSq; - } - - if (adjSq > lineSq) { - return (x - x2) * (x - x2) + (y - y2) * (y - y2); - } - - return (hypSq - adjSq) - } - - } - } - - var debug = function(){}; - $$("renderer", "canvas", CanvasRenderer); - -})( cytoscape ); - -;(function($$){ - - // default layout options - var defaults = { - ready: function(){}, - stop: function(){} - }; - - // constructor - // options : object containing layout options - function NullLayout( options ){ - this.options = $$.util.extend(true, {}, defaults, options); - } - - // runs the layout - NullLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; // cy is automatically populated for us in the constructor - - // puts all nodes at (0, 0) - cy.nodes().positions(function(){ - return { - x: 0, - y: 0 - }; - }); - - // trigger layoutready when each node has had its position set at least once - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - // trigger layoutstop when the layout stops (e.g. finishes) - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - // called on continuous layouts to stop them before they finish - NullLayout.prototype.stop = function(){ - var options = this.options; - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - // register the layout - $$("layout", "null", NullLayout); - -})(cytoscape); - -;(function($$){ - - var defaults = { - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - fit: true, // whether to fit to viewport - padding: 30 // fit padding - }; - - function RandomLayout( options ){ - this.options = $$.util.extend(true, {}, defaults, options); - } - - RandomLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - - nodes.positions(function(i, element){ - - if( element.locked() ){ - return false; - } - - return { - x: Math.round( Math.random() * width ), - y: Math.round( Math.random() * height ) - }; - }); - - // layoutready should be triggered when the layout has set each node's - // position at least once - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - if( options.fit ){ - cy.fit( options.padding ); - } - - // layoutstop should be triggered when the layout stops running - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - RandomLayout.prototype.stop = function(){ - // stop the layout if it were running continuously - }; - - // register the layout - $$( - "layout", // we're registering a layout - "random", // the layout name - RandomLayout // the layout prototype - ); - -})(cytoscape); - -;(function($$){ - - var defaults = { - fit: true, // whether to fit the viewport to the graph - rows: undefined, // force num of rows in the grid - columns: undefined, // force num of cols in the grid - ready: undefined, // callback on layoutready - stop: undefined // callback on layoutstop - }; - - function GridLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - GridLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - if( height == 0 || width == 0){ - nodes.positions(function(){ - return { x: 0, y: 0 }; - }); - - } else { - - // width/height * splits^2 = cells where splits is number of times to split width - var cells = nodes.size(); - var splits = Math.sqrt( cells * height/width ); - var rows = Math.round( splits ); - var cols = Math.round( width/height * splits ); - - function small(val){ - if( val == undefined ){ - return Math.min(rows, cols); - } else { - var min = Math.min(rows, cols); - if( min == rows ){ - rows = val; - } else { - cols = val; - } - } - } - - function large(val){ - if( val == undefined ){ - return Math.max(rows, cols); - } else { - var max = Math.max(rows, cols); - if( max == rows ){ - rows = val; - } else { - cols = val; - } - } - } - - // if rows or columns were set in options, use those values - if( options.rows != null && options.columns != null ){ - rows = options.rows; - cols = options.columns; - } else if( options.rows != null && options.columns == null ){ - rows = options.rows; - cols = Math.ceil( cells / rows ); - } else if( options.rows == null && options.columns != null ){ - cols = options.columns; - rows = Math.ceil( cells / cols ); - } - - // otherwise use the automatic values and adjust accordingly - - // if rounding was up, see if we can reduce rows or columns - else if( cols * rows > cells ){ - var sm = small(); - var lg = large(); - - // reducing the small side takes away the most cells, so try it first - if( (sm - 1) * lg >= cells ){ - small(sm - 1); - } else if( (lg - 1) * sm >= cells ){ - large(lg - 1); - } - } else { - - // if rounding was too low, add rows or columns - while( cols * rows < cells ){ - var sm = small(); - var lg = large(); - - // try to add to larger side first (adds less in multiplication) - if( (lg + 1) * sm >= cells ){ - large(lg + 1); - } else { - small(sm + 1); - } - } - } - - var cellWidth = width / cols; - var cellHeight = height / rows; - - var row = 0; - var col = 0; - nodes.positions(function(i, element){ - - if( element.locked() ){ - return false; - } - - var x = col * cellWidth + cellWidth/2; - var y = row * cellHeight + cellHeight/2; - - col++; - if( col >= cols ){ - col = 0; - row++; - } - - return { x: x, y: y }; - - }); - } - - if( params.fit ){ - cy.reset(); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - GridLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "grid", GridLayout); - -})( cytoscape ); - -;(function($$){ - - var defaults = { - fit: true, // whether to fit to viewport - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - positions: undefined, // map of (node id) => (position obj) - zoom: undefined, // the zoom level to set (prob want fit = false if set) - pan: undefined, // the pan level to set (prob want fit = false if set) - padding: 30 // padding on fit - }; - - function PresetLayout( options ){ - this.options = $$.util.extend(true, {}, defaults, options); - } - - PresetLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - function getPosition(node){ - if( options.positions == null ){ - return null; - } - - if( options.positions[node._private.data.id] == null ){ - return null; - } - - return options.positions[node._private.data.id]; - } - - nodes.positions(function(i, node){ - var position = getPosition(node); - - if( node.locked() || position == null ){ - return false; - } - - return position; - }); - - if( options.pan != null ){ - cy.pan( options.pan ); - } - - if( options.zoom != null ){ - cy.zoom( options.zoom ); - } - - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - if( options.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - $$("layout", "preset", PresetLayout); - - $$("core", "presetLayout", function(){ - var cy = this; - var layout = {}; - var elements = {}; - - cy.nodes().each(function(i, ele){ - elements[ ele.data("id") ] = ele.position(); - }); - - layout.positions = elements; - layout.name = "preset"; - layout.zoom = cy.zoom(); - layout.pan = cy.pan(); - - return layout; - }); - -})(cytoscape); - -;(function($$){ - - var defaults = { - liveUpdate: true, // whether to show the layout as it's running - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - maxSimulationTime: 4000, // max length in ms to run the layout - fit: true, // fit to viewport - padding: [ 50, 50, 50, 50 ], // top, right, bottom, left - ungrabifyWhileSimulating: true, // so you can't drag nodes during layout - - // forces used by arbor (use arbor default on undefined) - repulsion: undefined, - stiffness: undefined, - friction: undefined, - gravity: true, - fps: undefined, - precision: undefined, - - // static numbers or functions that dynamically return what these - // values should be for each element - nodeMass: undefined, - edgeLength: undefined, - - stepSize: 1, // size of timestep in simulation - - // function that returns true if the system is stable to indicate - // that the layout can be stopped - stableEnergy: function( energy ){ - var e = energy; - return (e.max <= 0.5) || (e.mean <= 0.3); - } - }; - - function ArborLayout(options){ - this.options = $$.util.extend({}, defaults, options); - } - - ArborLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - - // arbor doesn't work with just 1 node - if( cy.nodes().size() <= 1 ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().position({ - x: Math.round( width/2 ), - y: Math.round( height/2 ) - }); - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - - return; - } - - var sys = this.system = arbor.ParticleSystem(options.repulsion, options.stiffness, options.friction, options.gravity, options.fps, options.dt, options.precision); - this.system = sys; - - if( options.liveUpdate && options.fit ){ - cy.reset(); - }; - - var doneTime = 250; - var doneTimeout; - - var ready = false; - - var lastDraw = +new Date; - var sysRenderer = { - init: function(system){ - }, - redraw: function(){ - var energy = sys.energy(); - - // if we're stable (according to the client), we're done - if( options.stableEnergy != null && energy != null && energy.n > 0 && options.stableEnergy(energy) ){ - sys.stop(); - return; - } - - clearTimeout(doneTimeout); - doneTimeout = setTimeout(doneHandler, doneTime); - - var movedNodes = []; - - sys.eachNode(function(n, point){ - var id = n.name; - var data = n.data; - var node = data.element; - - if( node == null ){ - return; - } - var pos = node._private.position; - - if( !node.locked() && !node.grabbed() ){ - pos.x = point.x; - pos.y = point.y; - - movedNodes.push( node ); - } - }); - - - var timeToDraw = (+new Date - lastDraw) >= 16; - if( options.liveUpdate && movedNodes.length > 0 && timeToDraw ){ - new $$.Collection(cy, movedNodes).rtrigger("position"); - lastDraw = +new Date; - } - - - if( !ready ){ - ready = true; - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - } - } - - }; - sys.renderer = sysRenderer; - sys.screenSize( width, height ); - sys.screenPadding( options.padding[0], options.padding[1], options.padding[2], options.padding[3] ); - sys.screenStep( options.stepSize ); - - function calculateValueForElement(element, value){ - if( value == null ){ - return undefined; - } else if( typeof value == typeof function(){} ){ - return value.apply(element, [element._private.data, { - nodes: nodes.length, - edges: edges.length, - element: element - }]); - } else { - return value; - } - } - - // TODO we're using a hack; sys.toScreen should work :( - function fromScreen(pos){ - var x = pos.x; - var y = pos.y; - var w = width; - var h = height; - - var left = -2; - var right = 2; - var top = -2; - var bottom = 2; - - var d = 4; - - return { - x: x/w * d + left, - y: y/h * d + right - }; - } - - var grabHandler = function(e){ - grabbed = this; - var pos = sys.fromScreen( this.position() ); - var p = arbor.Point(pos.x, pos.y); - this.scratch().arbor.p = p; - - switch( e.type ){ - case "grab": - this.scratch().arbor.fixed = true; - break; - case "dragstop": - this.scratch().arbor.fixed = false; - this.scratch().arbor.tempMass = 1000 - break; - } - }; - nodes.bind("grab drag dragstop", grabHandler); - - nodes.each(function(i, node){ - var id = this._private.data.id; - var mass = calculateValueForElement(this, options.nodeMass); - var locked = this._private.locked; - - var pos = fromScreen({ - x: node.position().x, - y: node.position().y - }); - - if( node.locked() ){ - return; - } - - this.scratch().arbor = sys.addNode(id, { - element: this, - mass: mass, - fixed: locked, - x: locked ? pos.x : undefined, - y: locked ? pos.y : undefined - }); - }); - - edges.each(function(){ - var id = this.id(); - var src = this.source().id(); - var tgt = this.target().id(); - var length = calculateValueForElement(this, options.edgeLength); - - this.scratch().arbor = sys.addEdge(src, tgt, { - length: length - }); - }); - - function packToCenter(callback){ - // TODO implement this for IE :( - - if( options.fit ){ - cy.fit(); - } - callback(); - }; - - var grabbableNodes = nodes.filter(":grabbable"); - // disable grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.ungrabify(); - } - - var doneHandler = function(){ - if( window.isIE ){ - packToCenter(function(){ - done(); - }); - } else { - done(); - } - - function done(){ - if( !options.liveUpdate ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().rtrigger("position"); - } - - // unbind handlers - nodes.unbind("grab drag dragstop", grabHandler); - - // enable back grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.grabify(); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - } - }; - - sys.start(); - setTimeout(function(){ - sys.stop(); - }, options.maxSimulationTime); - - }; - - ArborLayout.prototype.stop = function(){ - if( this.system != null ){ - system.stop(); - } - }; - - $$("layout", "arbor", ArborLayout); - - -})(cytoscape); - -;(function($$){ - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - rStepSize: 10, // the step size for increasing the radius if the nodes don't fit on screen - padding: 30, // the padding on fit - startAngle: 3/2 * Math.PI, // the position of the first node - counterclockwise: false // whether the layout should go counterclockwise (true) or clockwise (false) - }; - - function CircleLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - CircleLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var center = { - x: width/2, - y: height/2 - }; - - var padding = 50; - - var theta = options.startAngle; - var dTheta = 2 * Math.PI / nodes.length; - var maxNodeSize = 0; - - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - - maxNodeSize = Math.max( node.outerWidth(), node.outerHeight() ); - } - - var r = width/2 - maxNodeSize; - - function distanceBetweenNodes(){ - var t1 = 0; - var t2 = dTheta; - - var p1 = { - x: center.x + r * Math.cos(t1), - y: center.y + r * Math.sin(t1) - }; - - var p2 = { - x: center.x + r * Math.cos(t2), - y: center.y + r * Math.sin(t2) - }; - - var dist = Math.sqrt( (p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y) ); - - return dist; - } - - while( distanceBetweenNodes() < maxNodeSize ){ - r += options.rStepSize; - } - - - var i = 0; - nodes.positions(function(){ - var node = this; - var rx = r * Math.cos( theta ); - var ry = r * Math.sin( theta ); - var pos = { - x: center.x + rx, - y: center.y + ry - }; - - i++; - theta = options.counterclockwise ? theta - dTheta : theta + dTheta; - return pos; - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - CircleLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "circle", CircleLayout); - -})( cytoscape ); - -;(function($$){ - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - directed: true, // whether the tree is directed downwards (or edges can point in any direction if false) - padding: 30, // padding on fit - circle: false, // put depths in concentric circles if true, put depths top down if false - roots: undefined // the roots of the trees - }; - - function BreadthFirstLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - BreadthFirstLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var roots; - if( $$.is.elementOrCollection(options.roots) ){ - roots = options.roots; - } else if( $$.is.array(options.roots) ){ - var rootsArray = []; - - for( var i = 0; i < options.roots.length; i++ ){ - var id = options.roots[i]; - var ele = cy.getElementById( id ); - roots.push( ele ); - } - - roots = new $$.Collection( cy, rootsArray ); - } else { - roots = nodes.roots(); - } - - - var depths = []; - var foundByBfs = {}; - var id2depth = {}; - - // find the depths of the nodes - roots.bfs(function(i, depth){ - var ele = this[0]; - - if( !depths[depth] ){ - depths[depth] = []; - } - - depths[depth].push( ele ); - foundByBfs[ ele.id() ] = true; - id2depth[ ele.id() ] = depth; - }, options.directed); - - // check for nodes not found by bfs - var orphanNodes = []; - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - - if( foundByBfs[ ele.id() ] ){ - continue; - } else { - orphanNodes.push( ele ); - } - } - - // assign orphan nodes a depth from their neighborhood - var maxChecks = orphanNodes.length * 3; - var checks = 0; - while( orphanNodes.length !== 0 && checks < maxChecks ){ - var node = orphanNodes.shift(); - var neighbors = node.neighborhood().nodes(); - var assignedDepth = false; - - for( var i = 0; i < neighbors.length; i++ ){ - var depth = id2depth[ neighbors[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ - orphanNodes.push( node ); - } - - checks++; - } - - // assign orphan nodes that are still left to the depth of their subgraph - while( orphanNodes.length !== 0 ){ - var node = orphanNodes.shift(); - var subgraph = node.bfs(); - var assignedDepth = false; - - for( var i = 0; i < subgraph.length; i++ ){ - var depth = id2depth[ subgraph[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0 - if( depths.length === 0 ){ - depths.push([]); - } - - depths[0].push( node ); - } - } - - // assign the nodes a depth and index - function assignDepthsToEles(){ - for( var i = 0; i < depths.length; i++ ){ - var eles = depths[i]; - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - - ele._private.scratch.BreadthFirstLayout = { - depth: i, - index: j - }; - } - } - } - assignDepthsToEles(); - - // find min distance we need to leave between nodes - var minDistance = 0; - for( var i = 0; i < nodes.length; i++ ){ - var w = nodes[i].outerWidth(); - var h = nodes[i].outerHeight(); - - minDistance = Math.max(minDistance, w, h); - } - minDistance *= 1.75; // just to have some nice spacing - - // get the weighted percent for an element based on its connectivity to other levels - var cachedWeightedPercent = {}; - function getWeightedPercent( ele ){ - if( cachedWeightedPercent[ ele.id() ] ){ - return cachedWeightedPercent[ ele.id() ]; - } - - var eleDepth = ele._private.scratch.BreadthFirstLayout.depth; - var neighbors = ele.neighborhood().nodes(); - var percent = 0; - var samples = 0; - - for( var i = 0; i < neighbors.length; i++ ){ - var neighbor = neighbors[i]; - var nEdges = neighbor.edgesWith( ele ); - var index = neighbor._private.scratch.BreadthFirstLayout.index; - var depth = neighbor._private.scratch.BreadthFirstLayout.depth; - var nDepth = depths[depth].length; - - if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above - percent += index / nDepth; - samples++; - } - } - - samples = Math.max(1, samples); - percent = percent / samples; - - if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting - percent = undefined; - } - - cachedWeightedPercent[ ele.id() ] = percent; - return percent; - } - - // rearrange the indices in each depth level based on connectivity - for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result - - for( var i = 0; i < depths.length; i++ ){ - var depth = i; - var newDepths = []; - - depths[i] = depths[i].sort(function(a, b){ - var apct = getWeightedPercent( a ); - var bpct = getWeightedPercent( b ); - - - return apct - bpct; - }); - } - assignDepthsToEles(); // and update - - } - - var center = { - x: width/2, - y: height/2 - }; - nodes.positions(function(){ - var ele = this[0]; - var info = ele._private.scratch.BreadthFirstLayout; - var depth = info.depth; - var index = info.index; - - var distanceX = Math.max( width / (depths[depth].length + 1), minDistance ); - var distanceY = Math.max( height / (depths.length + 1), minDistance ); - var radiusStepSize = Math.min( width / 2 / depths.length, height / 2 / depths.length ); - radiusStepSize = Math.max( radiusStepSize, minDistance ); - - if( options.circle ){ - var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0); - var theta = 2 * Math.PI / depths[depth].length * index; - - if( depth === 0 && depths[0].length === 1 ){ - radius = 1; - } - - return { - x: center.x + radius * Math.cos(theta), - y: center.y + radius * Math.sin(theta) - }; - - } else { - return { - x: (index + 1) * distanceX, - y: (depth + 1) * distanceY - }; - } - - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - BreadthFirstLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "breadthfirst", BreadthFirstLayout); - -})( cytoscape ); diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.min.js deleted file mode 100755 index b84eb45650..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/cytoscape.min.js +++ /dev/null @@ -1,377 +0,0 @@ - -/* cytoscape.min.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -var cytoscape;(function(){var a=cytoscape=function(){return cytoscape.init.apply(cytoscape,arguments)};a.init=function(b){if(b===undefined){b={}}if(a.is.plainObject(b)){return new a.Core(b)}else{if(a.is.string(b)){return a.extension.apply(a.extension,arguments)}}};a.fn={};if(typeof exports!=="undefined"){exports=module.exports=cytoscape}window.cytoscape=cytoscape})();(function(a){a.is={string:function(b){return b!=null&&typeof b==typeof""},fn:function(b){return b!=null&&typeof b===typeof function(){} -},array:function(b){return b!=null&&b instanceof Array},plainObject:function(b){return b!=null&&typeof b===typeof{}&&!a.is.array(b)&&b.constructor===Object},number:function(b){return b!=null&&typeof b===typeof 1&&!isNaN(b)},integer:function(b){return a.is.number(b)&&Math.floor(b)===b},color:function(b){return b!=null&&typeof b===typeof""&&$.Color(b).toString()!==""},bool:function(b){return b!=null&&typeof b===typeof true},elementOrCollection:function(b){return a.is.element(b)||a.is.collection(b)},element:function(b){return b instanceof a.Element&&b._private.single -},collection:function(b){return b instanceof a.Collection&&!b._private.single},core:function(b){return b instanceof a.Core},style:function(b){return b instanceof a.Style},stylesheet:function(b){return b instanceof a.Stylesheet},event:function(b){return b instanceof a.Event},emptyString:function(b){if(!b){return true}else{if(a.is.string(b)){if(b===""||b.match(/^\s+$/)){return true}}}return false},nonemptyString:function(b){if(b&&a.is.string(b)&&b!==""&&!b.match(/^\s+$/)){return true}return false},domElement:function(b){if(typeof HTMLElement==="undefined"){return false -}else{return b instanceof HTMLElement}}}})(cytoscape);(function(a){a.util={extend:function(){var l,d,b,c,h,j,g=arguments[0]||{},f=1,e=arguments.length,k=false;if(typeof g==="boolean"){k=g;g=arguments[1]||{};f=2}if(typeof g!=="object"&&!a.is.fn(g)){g={}}if(e===f){g=this;--f}for(;fc&&d[b]===" ";b--){}return d.substring(c,b+1)},hex2tuple:function(h){if(!(h.length===4||h.length===7)||h[0]!=="#"){return -}var f=h.length===4;var e,d,c;var i=16;if(f){e=parseInt(h[1]+h[1],i);d=parseInt(h[2]+h[2],i);c=parseInt(h[3]+h[3],i)}else{e=parseInt(h[1]+h[2],i);d=parseInt(h[3]+h[4],i);c=parseInt(h[5]+h[6],i)}return[e,d,c]},hsl2tuple:function(z){var u;var k=a.util.regex.number;var o,A,j,w,c,t,v;var i=new RegExp("^"+a.util.regex.hsla+"$").exec(z);if(i){o=parseInt(i[1]);if(o<0){o=(360-(-1*o%360))%360}else{if(o>360){o=o%360}}o/=360;A=parseFloat(i[2]);if(A<0||A>100){return}A=A/100;j=parseFloat(i[3]);if(j<0||j>100){return -}j=j/100;w=i[4];if(w!==undefined){w=parseFloat(w);if(w<0||w>1){return}}if(A===0){c=t=v=Math.round(j*255)}else{function f(h,g,b){if(b<0){b+=1}if(b>1){b-=1}if(b<1/6){return h+(g-h)*6*b}if(b<1/2){return g}if(b<2/3){return h+(g-h)*(2/3-b)*6}return h}var d=j<0.5?j*(1+A):j+A-j*A;var e=2*j-d;c=Math.round(255*f(e,d,o+1/3));t=Math.round(255*f(e,d,o));v=Math.round(255*f(e,d,o-1/3))}u=[c,t,v,w]}return u},rgb2tuple:function(k){var h;var d=a.util.regex.number;var b=new RegExp("^"+a.util.regex.rgba+"$").exec(k); -if(b){h=[];var l=[];for(var e=1;e<=3;e++){var g=b[e];if(g[g.length-1]==="%"){l[e]=true}g=parseFloat(g);if(l[e]){g=g/100*255}if(g<0||g>255){return}h.push(Math.floor(g))}var f=l[1]||l[2]||l[3];var j=l[1]&&l[2]&&l[3];if(f&&!j){return}var c=b[4];if(c!==undefined){c=parseFloat(c);if(c<0||c>1){return}h.push(c)}}return h},colorname2tuple:function(b){return a.util.colors[b.toLowerCase()]},color2tuple:function(b){return a.util.colorname2tuple(b)||a.util.hex2tuple(b)||a.util.rgb2tuple(b)||a.util.hsl2tuple(b) -},tuple2hex:function(d){var f=d[0];var e=d[1];var c=d[2];function h(b){var g=b.toString(16);if(g.length===1){g="0"+g}return g}return"#"+h(f)+h(e)+h(c)},colors:{transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}}; -a.util.regex={};a.util.regex.number="(?:\\d*\\.\\d+|\\d+|\\d*\\.\\d+[eE]\\d+)";a.util.regex.rgba="rgb[a]?\\(("+a.util.regex.number+"[%]?)\\s*,\\s*("+a.util.regex.number+"[%]?)\\s*,\\s*("+a.util.regex.number+"[%]?)(?:\\s*,\\s*("+a.util.regex.number+"))?\\)";a.util.regex.rgbaNoBackRefs="rgb[a]?\\((?:"+a.util.regex.number+"[%]?)\\s*,\\s*(?:"+a.util.regex.number+"[%]?)\\s*,\\s*(?:"+a.util.regex.number+"[%]?)(?:\\s*,\\s*(?:"+a.util.regex.number+"))?\\)";a.util.regex.hsla="hsl[a]?\\(("+a.util.regex.number+")\\s*,\\s*("+a.util.regex.number+"[%])\\s*,\\s*("+a.util.regex.number+"[%])(?:\\s*,\\s*("+a.util.regex.number+"))?\\)"; -a.util.regex.hslaNoBackRefs="hsl[a]?\\((?:"+a.util.regex.number+")\\s*,\\s*(?:"+a.util.regex.number+"[%])\\s*,\\s*(?:"+a.util.regex.number+"[%])(?:\\s*,\\s*(?:"+a.util.regex.number+"))?\\)";a.util.regex.hex3="\\#[0-9a-fA-F]{3}";a.util.regex.hex6="\\#[0-9a-fA-F]{6}"})(cytoscape);(function(b){b.math={};b.math.boxInBezierVicinity=function(o,j,u,k,q,i,p,h,l,f,m){var v=Math.min(o,u)-m;var s=Math.min(j,k)-m;var t=Math.max(o,u)+m;var r=Math.max(j,k)+m;if(q>=v&&q<=t&&i>=s&&i<=r){return 2}else{if(l>=v&&l<=t&&f>=s&&f<=r){return 2 -}else{if(p>=v&&p<=t&&h>=s&&h<=r){return 1}}}var g=Math.min(q,p,l);var e=Math.min(i,h,f);var d=Math.max(q,p,l);var c=Math.max(i,h,f);if(g>t||dr||c=B&&t<=z&&Math.min(g,d)<=w&&Math.max(g,d)>=v)}var c=(B-m)/h;if(c>0&&c<=1){u=e*c+l;if(u>=w&&u<=v){return true -}}var j=(z-m)/h;if(j>0&&j<=1){u=e*j+l;if(u>=w&&u<=v){return true}}var f=(w-l)/e;if(f>0&&f<=1){p=h*f+m;if(p>=B&&p<=z){return true}}var i=(v-l)/e;if(i>0&&i<=1){p=h*i+m;if(p>=B&&p<=z){return true}}return false};b.math.checkBezierCrossesBox=function(w,h,L,A,q,U,l,R,j,O,d){var s=Math.min(w,L)-d;var p=Math.min(h,A)-d;var T=Math.max(w,L)+d;var Q=Math.max(h,A)+d;if(q>=s&&q<=T&&U>=p&&U<=Q){return true}else{if(j>=s&&j<=T&&O>=p&&O<=Q){return true}}var v=q-2*l+j;var g=-2*q+2*l;var H=q;var B=[];if(Math.abs(v)<0.0001){var M=(s-q)/g; -var z=(T-q)/g;B.push(M,z)}else{var E=g*g-4*v*(H-s);var t,r;if(E>0){var F=Math.sqrt(E);t=(-g+F)/(2*v);r=(-g-F)/(2*v);B.push(t,r)}var D=g*g-4*v*(H-T);var o,k;if(D>0){var F=Math.sqrt(D);o=(-g+F)/(2*v);k=(-g-F)/(2*v);B.push(o,k)}}B.sort(function(W,V){return W-V});var u=U-2*R+O;var e=-2*U+2*R;var G=U;var K=[];if(Math.abs(u)<0.0001){var f=(p-U)/e;var I=(Q-U)/e;K.push(f,I)}else{var m=e*e-4*u*(G-p);var c,S;if(m>0){var F=Math.sqrt(m);c=(-e+F)/(2*u);S=(-e-F)/(2*u);K.push(c,S)}var i=e*e-4*u*(G-Q);var P,N;if(i>0){var F=Math.sqrt(i); -P=(-e+F)/(2*u);N=(-e-F)/(2*u);K.push(P,N)}}K.sort(function(W,V){return W-V});for(var C=0;C=0&&B[C]<=1&&B[C+1]>K[J-1]&&K[J-1]<=1&&B[C+1]>=0){return true}}}return false};b.math.inBezierVicinity=function(i,h,t,e,s,d,r,c,A){var k=0.25*t+0.5*s+0.25*r;var j=0.25*e+0.5*d+0.25*c;var o,m,w,u;var g,f,l;var z=function(C,I,D,B,H,G,E,F){g=(G-B)*(C-D)+(D-H)*(I-B);f=g*g;sideSquared=(G-B)*(G-B)+(D-H)*(D-H);if(F){if(g>0){return false}}else{if(g<0){return false -}}return(f/sideSquared>E)};var q=(k+s)/2;var p=(j+d)/2;var v=true;if(z(q,p,t,e,s,d,0,v)){v=!v}return(!z(i,h,t,e,s,d,A,v)&&!z(i,h,s,d,r,c,A,v)&&!z(i,h,r,c,t,e,A,v))};b.math.solveCubic=function(o,m,l,k,v){m/=o;l/=o;k/=o;var f,g,e,i,u,p,h,j;g=(3*l-(m*m))/9;e=-(27*k)+m*(9*l-2*(m*m));e/=54;f=g*g*g+e*e;v[1]=0;h=(m/3);if(f>0){u=e+Math.sqrt(f);u=((u<0)?-Math.pow(-u,(1/3)):Math.pow(u,(1/3)));p=e-Math.sqrt(f);p=((p<0)?-Math.pow(-p,(1/3)):Math.pow(p,(1/3)));v[0]=-h+u+p;h+=(u+p)/2;v[4]=v[2]=-h;h=Math.sqrt(3)*(-p+u)/2; -v[3]=h;v[5]=-h;return}v[5]=v[3]=0;if(f==0){j=((e<0)?-Math.pow(-e,(1/3)):Math.pow(e,(1/3)));v[0]=-h+2*j;v[4]=v[2]=-(j+h);return}g=-g;i=g*g*g;i=Math.acos(e/Math.sqrt(i));j=2*Math.sqrt(g);v[0]=-h+j*Math.cos(i/3);v[2]=-h+j*Math.cos((i+2*Math.PI)/3);v[4]=-h+j*Math.cos((i+4*Math.PI)/3);return};b.math.sqDistanceToQuadraticBezier=function(q,p,v,j,u,h,t,g){var D=1*v*v-4*v*u+2*v*t+4*u*u-4*u*t+t*t+j*j-4*j*h+2*j*g+4*h*h-4*h*g+g*g;var C=1*9*v*u-3*v*v-3*v*t-6*u*u+3*u*t+9*j*h-3*j*j-3*j*g-6*h*h+3*h*g;var A=1*3*v*v-6*v*u+v*t-v*q+2*u*u+2*u*q-t*q+3*j*j-6*j*h+j*g-j*p+2*h*h+2*h*p-g*p; -var z=1*v*u-v*v+v*q-u*q+j*h-j*j+j*p-h*p;a("coefficients: "+D/D+", "+C/D+", "+A/D+", "+z/D);var k=[];this.solveCubic(D,C,A,z,k);var e=1e-7;var B=[];for(var l=0;l<6;l+=2){if(Math.abs(k[l+1])=0&&k[l]<=1){B.push(k[l])}}B.push(1);B.push(0);var f=-1;var w;var o,m,r;for(var s=0;s=0){if(r=0;c--){var d=a.instances[c];if(d.domElement===e){return d}}}}}})(cytoscape);(function(c){var f={};c.extensions=f;var d={};c.modules=d; -function b(j,i,k){var h={};h[i]=k;switch(j){case"core":case"collection":c.fn[j](h)}return c.util.setMap({map:f,keys:[j,i],value:k})}function g(i,h){return c.util.getMap({map:f,keys:[i,h]})}function e(k,i,j,h,l){return c.util.setMap({map:d,keys:[k,i,j,h],value:l})}function a(k,i,j,h){return c.util.getMap({map:d,keys:[k,i,j,h]})}c.extension=function(){if(arguments.length==2){return g.apply(this,arguments)}else{if(arguments.length==3){return b.apply(this,arguments)}else{if(arguments.length==4){return a.apply(this,arguments) -}else{if(arguments.length==5){return e.apply(this,arguments)}else{$.error("Invalid extension access syntax")}}}}}})(cytoscape);(function(b,a){if(!b){return}b.fn.cytoscape=function(h){var k=b(this);if(h==="get"){var g=a.getRegistrationForInstance(k[0]);return g.cy}else{if(a.is.fn(h)){var f=h;var c=k[0];var g=a.getRegistrationForInstance(c);if(!g){g=a.registerInstance(c)}if(g&&g.cy&&g.cy.ready()){g.cy.trigger("ready",[],f)}else{g.readies.push(f)}}else{if(a.is.plainObject(h)){return k.each(function(){var i=b.extend({},h,{container:b(this)[0]}); -cytoscape(i)})}else{var c=k[0];var j=[];var d=[];for(var e=1;e node").css({width:"auto",height:"auto",shape:"rectangle","background-opacity":0.5,"padding-top":10,"padding-right":10,"padding-left":10,"padding-bottom":10}).selector("edge").css({width:1,}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":0.25}).selector("core").css({"selection-box-color":"#ddd","selection-box-opacity":0.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"panning-cursor":"grabbing","active-bg-color":"black","active-bg-opacity":0.15,"active-bg-size":isTouch?40:15}) -};$$.styfn.clear=function(){this._private.newStyle=true;for(var i=0;itype.max)){return null}var ret={name:name,value:value,strValue:""+value+(units?units:""),units:units,bypass:propIsBypass,pxValue:type.unitless||units==="%"?undefined:(units==="px"||!units?(value):(this.getEmSizeInPixels()*value))};return ret}else{if(type.color){var tuple=$$.util.color2tuple(value);return{name:name,value:tuple,strValue:value,bypass:propIsBypass}}else{if(type.enums){for(var i=0;i0;var props=context.properties;if(contextSelectorMatches){for(var j=0;j0){d.remove() -}i.notifications(false);var c=[];if(f!=null){if(a.is.plainObject(f)||a.is.array(f)){i.add(f)}}function h(){i.one("layoutready",function(j){i.notifications(true);i.trigger(j);i.notify({type:"load",collection:i.elements(),style:i._private.style});i.one("load",g);i.trigger("load")}).one("layoutstop",function(){i.one("done",e);i.trigger("done")});i.layout(i._private.options.layout)}if(true||b&&b.chrome){setTimeout(function(){h()},30)}else{h()}return this}})})(cytoscape,typeof window==="undefined"?null:window); -(function(a){a.fn.core({addToAnimationPool:function(b){var h=this;var c=h._private.aniEles;var e=[];for(var d=0;d0?o.shift():null;if(u!=null){u.callTime=+new Date;z.push(u)}}var A=[];for(var t=0;t0){g.notify({type:"draw",collection:C})}for(var t=0;t0||v.length>0;if(!m){C.splice(t,1);t--}}}function e(F,w,s){var o=g._private.style;var C=w.properties;var v=w.params;var t=w.callTime;var B;if(w.duration===0){B=1}else{B=Math.min(1,(s-t)/w.duration) -}if(B<0){B=0}else{if(B>1){B=1}}if(C.delay==null){var A=w.startPosition;var r=C.position;var E=F._private.position;if(r){if(b(A.x,r.x)){E.x=h(A.x,r.x,B)}if(b(A.y,r.y)){E.y=h(A.y,r.y,B)}}if(C.css){var D=a.style.properties;for(var z=0;z=1){w.done=true}return B}function b(o,m){if(o==null||m==null){return false}if(a.is.number(o)&&a.is.number(m)){return true -}else{if((o)&&(m)){return true}}return false}function h(p,q,v){if(v<0){v=0}else{if(v>1){v=1}}if(a.is.number(p)&&a.is.number(q)){return p+(q-p)*v}else{if(a.is.number(p[0])&&a.is.number(q[0])){var t=p;var s=q;function o(A,r){var B=r-A;var z=A;return Math.round(v*B+z)}var m=o(t[0],s[0]);var u=o(t[1],s[1]);var w=o(t[2],s[2]);return"rgb("+m+", "+u+", "+w+")"}}return undefined}}})})(cytoscape);(function(a){a.fn.core({data:a.define.data({field:"data",bindingEvent:"data",allowBinding:true,allowSetting:true,settingEvent:"data",settingTriggersEvent:true,triggerFnName:"trigger",allowGetting:true}),removeData:a.define.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:true}),batchData:a.define.batchData({field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{id:true,source:true,target:true,parent:true},updateMappers:true}),scratch:a.define.data({field:"scratch",allowBinding:false,allowSetting:true,settingTriggersEvent:false,allowGetting:true}),removeScratch:a.define.removeData({field:"scratch",triggerEvent:false}),}) -})(cytoscape);(function(a){a.fn.core({on:a.define.on(),one:a.define.on({unbindSelfOnTrigger:true}),once:a.define.on({unbindAllBindersOnTrigger:true}),off:a.define.off(),trigger:a.define.trigger(),});a.corefn.bind=a.corefn.on;a.corefn.unbind=a.corefn.off;a.define.event.aliasesOn(a.corefn)})(cytoscape);(function(a){a.fn.core({png:function(){var c=this;var b=this._private.renderer;return b.png()}})})(cytoscape);(function(a){a.fn.core({layout:function(b){var c=this;if(this._private.layoutRunning){return this -}if(b==null){b=this._private.options.layout}this.initLayout(b);c.trigger("layoutstart");this._private.layoutRunning=true;this.one("layoutstop",function(){this._private.layoutRunning=false});this._private.layout.run();return this},initLayout:function(d){if(d==null){a.util.error("Layout options must be specified to run a layout");return}if(d.name==null){a.util.error("A `name` must be specified to run a layout");return}var c=d.name;var b=a.extension("layout",c);if(b==null){a.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?",c); -return}this._private.layout=new b(a.util.extend({},d,{renderer:this._private.renderer,cy:this}));this._private.options.layout=d}})})(cytoscape);(function(a){a.fn.core({notify:function(e){if(!this._private.notificationsEnabled){return}var d=this.renderer();var f=this;if(a.is.element(e.collection)){var b=e.collection;e.collection=new a.Collection(f,[b])}else{if(a.is.array(e.collection)){var c=e.collection;e.collection=new a.Collection(f,c)}}d.notify(e)},notifications:function(b){var c=this._private; -if(b===undefined){return c.notificationsEnabled}else{c.notificationsEnabled=b?true:false}},noNotifications:function(b){this.notifications(false);b();this.notifications(true)}})})(cytoscape);(function(a){a.fn.core({renderTo:function(b,d,e){var c=this._private.renderer;c.renderTo(b,d,e)},renderer:function(){return this._private.renderer},initRenderer:function(c){var d=this;var b=a.extension("renderer",c.name);if(b==null){a.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?",c.name); -return}this._private.renderer=new b(a.util.extend({},c,{cy:d,style:d._private.style}))}})})(cytoscape);(function(a){a.fn.core({collection:function(b){if(a.is.string(b)){return this.$(b)}else{if(a.is.elementOrCollection(b)){return b.collection()}}return new a.Collection(this)},nodes:function(b){var c=this.$("node");if(b){return c.filter(b)}return c},edges:function(b){var c=this.$("edge");if(b){return c.filter(b)}return c},$:function(c){var b=new a.Collection(this,this._private.elements);if(c){return b.filter(c) -}return b}});a.corefn.elements=a.corefn.filter=a.corefn.$})(cytoscape);(function(a){a.fn.core({style:function(b){return this._private.style}})})(cytoscape);(function(a){a.fn.core({panningEnabled:function(b){if(b!==undefined){this._private.panEnabled=b?true:false}else{return this._private.panEnabled}return this},zoomingEnabled:function(b){if(b!==undefined){this._private.zoomEnabled=b?true:false}else{return this._private.zoomEnabled}return this},boxSelectionEnabled:function(b){if(b!==undefined){this._private.boxSelectionEnabled=b?true:false -}else{return this._private.boxSelectionEnabled}return this},pan:function(){var c=arguments;var g=this._private.pan;var d,f,e,b,h;switch(c.length){case 0:return g;case 1:if(!this._private.panEnabled){return this}else{if(a.is.string(c[0])){d=c[0];return g[d]}else{if(a.is.plainObject(c[0])){e=c[0];b=e.x;h=e.y;if(a.is.number(b)){g.x=b}if(a.is.number(h)){g.y=h}this.trigger("pan")}}}break;case 2:if(!this._private.panEnabled){return this}d=c[0];f=c[1];if((d==="x"||d==="y")&&a.is.number(f)){g[d]=f}this.trigger("pan"); -break;default:break}this.notify({type:"viewport"});return this},panBy:function(h){var c=arguments;var g=this._private.pan;var d,f,e,b,i;if(!this._private.panEnabled){return this}switch(c.length){case 1:if(a.is.plainObject(c[0])){e=c[0];b=e.x;i=e.y;if(a.is.number(b)){g.x+=b}if(a.is.number(i)){g.y+=i}this.trigger("pan")}break;case 2:d=c[0];f=c[1];if((d==="x"||d==="y")&&a.is.number(f)){g[d]+=f}this.trigger("pan");break;default:break}this.notify({type:"viewport"});return this},fit:function(g,i){if(a.is.number(g)&&i===undefined){i=g; -g=undefined}if(!this._private.panEnabled||!this._private.zoomEnabled){return this}if(a.is.string(g)){var f=g;g=this.$(f)}else{if(!a.is.elementOrCollection(g)){g=this.elements()}}var j=g.boundingBox();var d=this.style();var b=parseFloat(d.containerCss("width"));var c=parseFloat(d.containerCss("height"));var e;i=a.is.number(i)?i:0;if(!isNaN(b)&&!isNaN(c)){e=this._private.zoom=Math.min((b-2*i)/j.w,(c-2*i)/j.h);e=e>this._private.maxZoom?this._private.maxZoom:e;e=ethis._private.maxZoom?this._private.maxZoom:k;k=k1&&this._private.minZoom<1){this.zoom(1)}this.notify({type:"viewport"});return this}})})(cytoscape);(function(b){b.fn.collection=b.fn.eles=function(c,e){for(var d in c){var f=c[d];b.Collection.prototype[d]=f -}};var a={prefix:{nodes:"n",edges:"e"},id:{nodes:0,edges:0},generate:function(h,d,g){var c=b.is.element(d)?d._private:d;var e=c.group;var f=g!=null?g:this.prefix[e]+this.id[e];if(h.getElementById(f).empty()){this.id[e]++}else{while(!h.getElementById(f).empty()){f=this.prefix[e]+(++this.id[e])}}return f}};b.Element=function(d,f,h){if(!(this instanceof b.Element)){return new b.Element(d,f,h)}var o=this;h=(h===undefined||h?true:false);if(d===undefined||f===undefined||!b.is.core(d)){b.util.error("An element must have a core reference and parameters set"); -return}if(f.group!=="nodes"&&f.group!=="edges"){b.util.error("An element must be of type `nodes` or `edges`; you specified `"+f.group+"`");return}this.length=1;this[0]=this;this._private={cy:d,single:true,data:f.data||{},position:f.position||{},autoWidth:undefined,autoHeight:undefined,listeners:[],group:f.group,style:{},rstyle:{},styleCxts:[],removed:true,selected:f.selected?true:false,selectable:f.selectable===undefined?true:(f.selectable?true:false),locked:f.locked?true:false,grabbed:false,grabbable:f.grabbable===undefined?true:(f.grabbable?true:false),active:false,classes:{},animation:{current:[],queue:[]},rscratch:{},scratch:{},edges:[],children:[]}; -if(f.renderedPosition){var p=f.renderedPosition;var j=d.pan();var m=d.zoom();this._private.position={x:(p.x-j.x)/m,y:(p.y-j.y)/m}}if(b.is.string(f.classes)){var e=f.classes.split(/\s+/);for(var g=0,c=e.length;g0&&b.is.plainObject(c[0])&&!b.is.element(c[0])){p=true;var s=[];var j={};for(var o=0,g=c.length;o0){var H=J.add(J.connectedNodes()).add(J.parent());H.updateStyle(s);if(s){J.rtrigger("add")}else{J.trigger("add")}}return r};b.elesfn.removed=function(){var c=this[0];return c&&c._private.removed};b.elesfn.inside=function(){var c=this[0]; -return c&&!c._private.removed};b.elesfn.remove=function(r){var q=this;var A=[];var C=[];var f={};var c=q._private.cy;if(r===undefined){r=true}function B(E){var l=E._private.edges;for(var D=0;D0){if(r){this.cy().notify({type:"remove",collection:v})}v.trigger("remove")}var e={};for(var w=0;w0 -}},clearQueue:function(){for(var b=0;b0){new a.Collection(this._private.cy,k).updateStyle()}c.trigger("class");return c},hasClass:function(b){var c=this[0]; -return c!=null&&c._private.classes[b]},toggleClass:function(h,g){var b=h.split(/\s+/);var o=this;var e=[];for(var f=0,k=o.length;f0){new a.Collection(this._private.cy,e).updateStyle()}o.trigger("class");return o},removeClass:function(g){g=g.split(/\s+/); -var c=this;var k=[];for(var f=0;f0){new a.Collection(c._private.cy,k).updateStyle()}c.trigger("class");return c}})})(cytoscape);(function(a){a.fn.eles({allAre:function(b){return this.filter(b).length===this.length},is:function(b){return this.filter(b).length>0},same:function(b){b=this.cy().collection(b);if(this.length!==b.length){return false -}return this.intersect(b).length===this.length},anySame:function(b){b=this.cy().collection(b);return this.intersect(b).length>0},allAreNeighbors:function(b){b=this.cy().collection(b);return this.neighborhood().intersect(b).length===b.length}})})(cytoscape);(function(b){var a=1.4;var c=1;b.fn.eles({updateStyle:function(d){var f=this._private.cy;var e=f.style();d=d||d===undefined?true:false;e.apply(this);if(d){this.rtrigger("style")}else{this.trigger("style")}return this},updateMappers:function(d){var h=this._private.cy; -var f=h.style();d=d||d===undefined?true:false;for(var e=0;eo?A:o;V=mT?l:T}else{var z=U.source()[0]._private.position;var d=U.target()[0]._private.position;var D=U._private.rstyle;G=D.labelX;F=D.labelY;B=z.x;A=d.x;m=z.y;l=d.y;if(B>A){var f=B;B=A;A=f}if(m>l){var f=m;m=l;l=f}p=Bo?A:o;V=mT?l:T;var k=D.bezierPts||[];var H=U._private.style.width.value; -for(var Q=0;Qo?P.x+H:o;V=P.y-HT?P.y+H:T}}var O=U._private.style;var N=O.content.value;var q=O["font-size"];var u=O["text-halign"];var I=O["text-valign"];var g=U._private.rstyle.labelWidth;if(N&&q&&g!=undefined&&u&&I){var E=q.value;var t=g;var M,K,s,r;switch(u.value){case"left":M=B-t;K=B;break;case"center":M=G-t/2;K=G+t/2;break;case"right":M=A;K=A+t;break}if(U.isEdge()){M=G-t/2;K=G+t/2}switch(I.value){case"top":s=m-E;r=m;break; -case"center":s=F-E/2;r=F+E/2;break;case"bottom":s=l;r=l+E;break}if(U.isEdge()){s=F-E/2;r=F+E/2}p=Mo?K:o;V=sT?r:T}}return{x1:p,x2:o,y1:V,y2:T,w:o-p,h:T-V}}})})(cytoscape);(function(b){function a(d){return function(){var f=this;if(f.length===0){return}if(f.isNode()&&!f.removed()){var k=0;var j=f[0];var e=j._private.edges;for(var g=0;gd}),minIndegree:c("indegree",function(e,d){return ed -}),minOutdegree:c("outdegree",function(e,d){return ed})});b.fn.eles({totalDegree:function(){var f=0;var d=this.nodes();for(var e=0;e=0&&d0;if(!j){g.push(k)}}return new b.Collection(this._private.cy,g).filter(f)},kruskal:function(l){l=l||function(){return 1};function m(v){for(var u=0; -u0){e.push(o[0])}e.push(g[0])}}return(new b.Collection(l,e)).filter(m)},closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}});b.fn.eles({source:d({attr:"source"}),target:d({attr:"target"})});function d(e){return function(f){var h=[];var g=this.edges(); -var o=this._private.cy;for(var j=0;j0){h.push(l)}}return new b.Collection(o,h).filter(f)}}b.fn.eles({edgesWith:a(),edgesTo:a({thisIs:"source"})});function a(e){return function(r){var f=[];var j=this._private.cy;var g=e||{};if(b.is.string(r)){r=j.$(r)}var l=r.connectedEdges();var s=this._private.ids;for(var m=0;m0){f.push(h)}}return new b.Collection(k,f).filter(e)},parents:function(f){var g=[];var e=this.parent();while(e.nonempty()){for(var h=0; -h\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]";var variable="(?:[\\w-]|(?:\\\\"+metaChar+"))+";var comparatorOp="=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=";var boolOp="\\?|\\!|\\^"; -var string="\"(?:\\\\\"|[^\"])+\"|'(?:\\\\'|[^'])+'";var number=$$.util.regex.number;var value=string+"|"+number;var meta="degree|indegree|outdegree";var separator="\\s*,\\s*";var className=variable;var descendant="\\s+";var child="\\s+>\\s+";var subject="\\$";var id=variable;function cleanMetaChars(str){return str.replace(new RegExp("\\\\("+metaChar+")","g"),"\1")}var ops=comparatorOp.split("|");for(var i=0;i=0; -break;case"$=":matches=new RegExp(valStr+"$").exec(fieldStr)!=null;break;case"^=":matches=new RegExp("^"+valStr).exec(fieldStr)!=null;break;default:if(caseInsensitive){var expr="fieldStr "+operator+" valStr";matches=eval(expr)}else{var expr=params.fieldRef(field)+" "+operator+" "+value;matches=eval(expr)}}}else{if(operator!=null){switch(operator){case"?":matches=params.fieldTruthy(field);break;case"!":matches=!params.fieldTruthy(field);break;case"^":matches=params.fieldUndefined(field);break}}else{matches=!params.fieldUndefined(field) -}}if(!matches){allDataMatches=false;break}}return allDataMatches}var allDataMatches=operandsMatch({name:"data",fieldValue:function(field){return element._private.data[field]},fieldRef:function(field){return"element._private.data."+field},fieldUndefined:function(field){return element._private.data[field]===undefined},fieldTruthy:function(field){if(element._private.data[field]){return true}return false}});if(!allDataMatches){return false}var allMetaMatches=operandsMatch({name:"meta",fieldValue:function(field){return element[field]() -},fieldRef:function(field){return"element."+field+"()"},fieldUndefined:function(field){return element[field]()==undefined},fieldTruthy:function(field){if(element[field]()){return true}return false}});if(!allMetaMatches){return false}if(query.collection!=null){var matchesAny=query.collection._private.ids[element.id()]!=null;if(!matchesAny){return false}}if(query.filter!=null&&element.collection().filter(query.filter).size()==0){return false}function confirmRelations(query,elements){if(query!=null){var matches=false; -elements=elements();for(var i=0;i "+str}if(query.ancestor!=null){str=queryToString(query.ancestor)+" "+str}if(query.child!=null){str+=" > "+queryToString(query.child)}if(query.descendant!=null){str+=" "+queryToString(query.descendant)}return str}for(var i=0;i1&&i0&&this.data.container.clientWidth>0){context=H.bufferCanvases[1].getContext("2d");context.globalCompositeOperation="copy";context.drawImage(H.canvases[4],0,0);context.globalCompositeOperation="source-over";context.drawImage(H.canvases[2],0,0); -context.drawImage(H.canvases[0],0,0);context=H.bufferCanvases[0].getContext("2d");context.globalCompositeOperation="copy";context.drawImage(H.bufferCanvases[1],0,0)}var i=this.data.bufferCanvases[0];return i.toDataURL("image/png")};z.prototype.load=function(){var R=this;var P=function(ad,Y,ae){if(!Y){var ab=ad.parents();for(var ac=0;acag[0]&&ap.pageXag[1]&&ap.pageY=p)&&(Math.abs(aj[3]-aj[1])+Math.abs(aj[2]-aj[0])<4)&&aa.panningEnabled()){R.hoverData.dragging=true;aj[4]=0}else{if(aa.boxSelectionEnabled()&&Math.pow(aj[2]-aj[0],2)+Math.pow(aj[3]-aj[1],2)>7&&aj[4]){clearTimeout(R.bgActiveTimeout)}if(ai&&ai.isEdge()&&ai.active()){ai.unactivate()}if(aq!=ah){if(ah){ah.trigger(new w.Event(ap,{type:"mouseout"})) -}if(aq){aq.trigger(new w.Event(ap,{type:"mouseover"}))}R.hoverData.last=aq}if(ai&&ai.isNode()&&R.nodeIsDraggable(ai)){R.dragData.didDrag=true;var ar=[];for(var ao=0;ao7&&ak[4])&&!R.hoverData.dragging){Z.$(":selected").unselect();if(ac.length>0){R.data.canvasNeedsRedraw[G]=true;R.data.canvasRedrawReason[G].push("De-select")}R.dragData.possibleDragElements=ac=[]}if(Math.pow(ak[2]-ak[0],2)+Math.pow(ak[3]-ak[1],2)==0){if(au!=null){au.trigger(new w.Event(at,{type:"click"})).trigger(new w.Event(at,{type:"tap"})).trigger(new w.Event(at,{type:"vclick"})) -}else{if(au==null){Z.trigger(new w.Event(at,{type:"click"})).trigger(new w.Event(at,{type:"tap"})).trigger(new w.Event(at,{type:"vclick"}))}}}if(au!=null){au.trigger(new w.Event(at,{type:"mouseup"})).trigger(new w.Event(at,{type:"tapend"})).trigger(new w.Event(at,{type:"vmouseup"}))}else{if(au==null){Z.trigger(new w.Event(at,{type:"mouseup"})).trigger(new w.Event(at,{type:"tapend"})).trigger(new w.Event(at,{type:"vmouseup"}))}}if(au==ag&&!R.dragData.didDrag){if(au!=null&&au._private.selectable){if(!ab){Z.$(":selected").unselect() -}if(au.selected()){au.unselect()}else{au.select()}W(au,false);R.data.canvasNeedsRedraw[G]=true;R.data.canvasRedrawReason[G].push("sglslct")}}else{if(au==ag){if(au!=null&&au._private.grabbed){var an=Z.$(":grabbed");for(var aq=0;aq7&&ak[4]){if(!ab){Z.$(":selected").unselect() -}var aa=[];var af=R.getAllInBox(ak[0],ak[1],ak[2],ak[3]);var ao=new w.Event(at,{type:"select"});for(var aq=0;aq0){R.data.canvasNeedsRedraw[G]=true;R.data.canvasRedrawReason[G].push("Selection")}}R.hoverData.dragging=false;if(!ak[4]){var ar=new w.Event(at,{type:"free"});for(var aq=0;aq250){if(R.touchData.start){R.touchData.start.trigger(new w.Event(au,{type:"taphold"})) -}else{R.data.cy.trigger(new w.Event(au,{type:"taphold"}));ab.$(":selected").unselect()}}},1000)}}}R.redraw()},false);R.registerBinding(window,"touchmove",function(aH){var aA=R.data.select;var an=R.touchData.capture;an&&aH.preventDefault();var al=R.data.cy;var aw=R.getCachedNodes();var af=R.getCachedEdges();var az=R.touchData.now;var Z=R.touchData.earlier;if(aH.touches[0]){var aq=R.projectIntoViewport(aH.touches[0].pageX,aH.touches[0].pageY);az[0]=aq[0];az[1]=aq[1]}if(aH.touches[1]){var aq=R.projectIntoViewport(aH.touches[1].pageX,aH.touches[1].pageY); -az[2]=aq[0];az[3]=aq[1]}if(aH.touches[2]){var aq=R.projectIntoViewport(aH.touches[2].pageX,aH.touches[2].pageY);az[4]=aq[0];az[5]=aq[1]}var ab=[];for(var aE=0;aE=1.5||au>=150){R.touchData.cxt=false;if(R.touchData.start){R.touchData.start.unactivate();R.touchData.start=null}R.data.bgActivePosistion=undefined; -R.data.canvasNeedsRedraw[D]=true;var aa=new w.Event(aH,{type:"cxttapend"});if(R.touchData.start){R.touchData.start.trigger(aa)}else{al.trigger(aa)}}}if(an&&R.touchData.cxt){var aa=new w.Event(aH,{type:"cxtdrag"});R.data.bgActivePosistion=undefined;R.data.canvasNeedsRedraw[D]=true;if(R.touchData.start){R.touchData.start.trigger(aa)}else{al.trigger(aa)}if(R.touchData.start){R.touchData.start._private.grabbed=false}R.touchData.cxtDragged=true}else{if(an&&aH.touches[2]&&al.boxSelectionEnabled()){R.data.bgActivePosistion=undefined; -clearTimeout(this.threeFingerSelectTimeout);this.lastThreeTouch=+new Date;R.data.canvasNeedsRedraw[D]=true;R.data.canvasRedrawReason[D].push("Touch moved, redraw selection box");if(!aA||aA.length===0||aA[0]===undefined){aA[0]=(az[0]+az[2]+az[4])/3;aA[1]=(az[1]+az[3]+az[5])/3;aA[2]=(az[0]+az[2]+az[4])/3+1;aA[3]=(az[1]+az[3]+az[5])/3+1}else{aA[2]=(az[0]+az[2]+az[4])/3;aA[3]=(az[1]+az[3]+az[5])/3}aA[4]=1}else{if(an&&aH.touches[1]&&al.zoomingEnabled()&&al.panningEnabled()){R.data.bgActivePosistion=undefined; -R.data.canvasNeedsRedraw[D]=true;var ap=aH.touches[0].pageX-L,ac=aH.touches[0].pageY-V;var ak=aH.touches[1].pageX-L,Y=aH.touches[1].pageY-V;var au=I(ap,ac,ak,Y);var aF=au/U;if(aF!=1&&i){var aJ=ap-H;var aI=ac-N;var av=ak-T;var at=Y-X;var aD=(aJ+av)/2;var aB=(aI+at)/2;var ae=al.zoom();var ad=ae*aF;var ah=al.pan();var ay=J[0]*ae+ah.x;var ax=J[1]*ae+ah.y;var ag={x:-ad/ae*(ay-ah.x-aD)+ay,y:-ad/ae*(ax-ah.y-aB)+ax};al._private.zoom=ad;al._private.pan=ag;al.trigger("pan zoom").notify("viewport");U=au;H=ap; -N=ac;T=ak;X=Y;R.pinching=true}if(aH.touches[0]){var aq=R.projectIntoViewport(aH.touches[0].pageX,aH.touches[0].pageY);az[0]=aq[0];az[1]=aq[1]}if(aH.touches[1]){var aq=R.projectIntoViewport(aH.touches[1].pageX,aH.touches[1].pageY);az[2]=aq[0];az[3]=aq[1]}if(aH.touches[2]){var aq=R.projectIntoViewport(aH.touches[2].pageX,aH.touches[2].pageY);az[4]=aq[0];az[5]=aq[1]}}else{if(aH.touches[0]){var ao=R.touchData.start;var ai=R.touchData.last;if(ao!=null&&ao._private.group=="nodes"&&R.nodeIsDraggable(ao)){var aj=R.dragData.touchDragEles; -for(var aC=0;aC4){R.touchData.singleTouchMoved=true -}}if(an&&(ao==null||ao.isEdge())&&al.panningEnabled()){if(ao){ao.unactivate();if(!R.data.bgActivePosistion){R.data.bgActivePosistion={x:az[0],y:az[1]}}R.data.canvasNeedsRedraw[D]=true;R.data.canvasRedrawReason[D].push("bgactive")}al.panBy({x:ab[0]*al.zoom(),y:ab[1]*al.zoom()});R.swipePanning=true;var aq=R.projectIntoViewport(aH.touches[0].pageX,aH.touches[0].pageY);az[0]=aq[0];az[1]=aq[1]}}}}}for(var aE=0;aE0){R.data.canvasNeedsRedraw[G]=true;R.data.canvasRedrawReason[G].push("Selection")}},100)}if(!aq.touches[1]){R.pinching=false -}var al=false;if(ac!=null){ac._private.active=false;al=true;ac.trigger(new w.Event(aq,{type:"unactivate"}))}if(aq.touches[2]){R.data.bgActivePosistion=undefined}else{if(aq.touches[1]){}else{if(aq.touches[0]){}else{if(!aq.touches[0]){R.data.bgActivePosistion=undefined;if(ac!=null){if(ac._private.grabbed==true){ac._private.grabbed=false;ac.trigger(new w.Event(aq,{type:"free"}));ac._private.rscratch.inDragLayer=false}var af=ac._private.edges;for(var am=0;amthis.sqDistanceToQuadraticBezier(V,U,N.startX,N.startY,N.cp2ax,N.cp2ay,N.selfEdgeMidX,N.selfEdgeMidY)))||(this.inBezierVicinity(V,U,N.selfEdgeMidX,N.selfEdgeMidY,N.cp2cx,N.cp2cy,N.endX,N.endY,Math.pow(O[P]._private.style.width.value/2,2))&&(Math.pow(O[P]._private.style.width.value/2,2)+M>this.sqDistanceToQuadraticBezier(V,U,N.selfEdgeMidX,N.selfEdgeMidY,N.cp2cx,N.cp2cy,N.endX,N.endY)))){I=true -}}else{if(N.edgeType=="straight"){if(this.inLineVicinity(V,U,N.startX,N.startY,N.endX,N.endY,O[P]._private.style.width.value*2)&&Math.pow(O[P]._private.style.width.value/2,2)+M>this.sqDistanceToFiniteLine(V,U,N.startX,N.startY,N.endX,N.endY)){I=true}}else{if(N.edgeType=="bezier"){if(this.inBezierVicinity(V,U,N.startX,N.startY,N.cp2x,N.cp2y,N.endX,N.endY,Math.pow(O[P]._private.style.width.value/2,2))&&(Math.pow(O[P]._private.style.width.value/2,2)+M>this.sqDistanceToQuadraticBezier(V,U,N.startX,N.startY,N.cp2x,N.cp2y,N.endX,N.endY))){I=true -}}}}if(!R.length||R[R.length-1]!=O[P]){if((b[O[P]._private.style["source-arrow-shape"].value].roughCollide(V,U,O[P]._private.rscratch.arrowStartX,O[P]._private.rscratch.arrowStartY,this.getArrowWidth(O[P]._private.style.width.value),this.getArrowHeight(O[P]._private.style.width.value),[O[P]._private.rscratch.arrowStartX-O[P].source()[0]._private.position.x,O[P]._private.rscratch.arrowStartY-O[P].source()[0]._private.position.y],0)&&b[O[P]._private.style["source-arrow-shape"].value].collide(V,U,O[P]._private.rscratch.arrowStartX,O[P]._private.rscratch.arrowStartY,this.getArrowWidth(O[P]._private.style.width.value),this.getArrowHeight(O[P]._private.style.width.value),[O[P]._private.rscratch.arrowStartX-O[P].source()[0]._private.position.x,O[P]._private.rscratch.arrowStartY-O[P].source()[0]._private.position.y],0))||(b[O[P]._private.style["target-arrow-shape"].value].roughCollide(V,U,O[P]._private.rscratch.arrowEndX,O[P]._private.rscratch.arrowEndY,this.getArrowWidth(O[P]._private.style.width.value),this.getArrowHeight(O[P]._private.style.width.value),[O[P]._private.rscratch.arrowEndX-O[P].target()[0]._private.position.x,O[P]._private.rscratch.arrowEndY-O[P].target()[0]._private.position.y],0)&&b[O[P]._private.style["target-arrow-shape"].value].collide(V,U,O[P]._private.rscratch.arrowEndX,O[P]._private.rscratch.arrowEndY,this.getArrowWidth(O[P]._private.style.width.value),this.getArrowHeight(O[P]._private.style.width.value),[O[P]._private.rscratch.arrowEndX-O[P].target()[0]._private.position.x,O[P]._private.rscratch.arrowEndY-O[P].target()[0]._private.position.y],0))){I=true -}}if(I){if(J){var H=Q.cy.getElementById(O[P]._private.data.source);var S=Q.cy.getElementById(O[P]._private.data.target);if(O[P]._private.style.opacity.value!=0&&O[P]._private.style.visibility.value=="visible"&&H._private.style.opacity.value!=0&&H._private.style.visibility.value=="visible"&&S._private.style.opacity.value!=0&&S._private.style.visibility.value=="visible"){R.push(O[P])}}else{R.push(O[P])}}}R.sort(C);if(R.length>0){return R[R.length-1]}else{return null}};z.prototype.getAllInBox=function(J,T,H,S){var O=this.data; -var I=this.getCachedNodes();var M=this.getCachedEdges();var P=[];var R=Math.min(J,H);var L=Math.max(J,H);var U=Math.min(T,S);var Q=Math.max(T,S);J=R;H=L;T=U;S=Q;var K;for(var N=0;N=0;H--){if(K[H].isNode()&&(K[H]._private.style.width.value=="auto"||K[H]._private.style.height.value=="auto")&&K[H].children().length>0){var J=K[H];var I=this.calcCompoundBounds(J);J._private.position.x=I.x;J._private.position.y=I.y;J._private.autoWidth=I.width;J._private.autoHeight=I.height}}};z.prototype.calcCompoundBounds=function(N){var M=N.descendants().not(":removed");var H={x:N._private.position.x,y:N._private.position.y,width:N._private.autoWidth,height:N._private.autoHeight}; -if(N._private.style.visibility.value!="visible"){return H}var I=[];for(var P=0;PP){P=O}}else{if(R=="top"){var M=Math.min(N.y-N.height/2,I.top);if(MP){P=K}}}}}}if((R=="left")||(R=="top")){return S -}else{return P}};z.prototype.getNodeWidth=function(i){if(i._private.style.width.value=="auto"||i._private.style.height.value=="auto"){return i._private.autoWidth}else{return i._private.style.width.value}};z.prototype.getNodeHeight=function(i){if(i._private.style.width.value=="auto"||i._private.style.height.value=="auto"){return i._private.autoHeight}else{return i._private.style.height.value}};z.prototype.getNodeShape=function(H){var i=H._private.style.shape.value;if(H.isParent()){if(i==="rectangle"||i==="roundrectangle"){return i -}else{return"rectangle"}}return i};z.prototype.getNodePadding=function(I){var K=I._private.style["padding-left"].value;var H=I._private.style["padding-right"].value;var J=I._private.style["padding-top"].value;var i=I._private.style["padding-bottom"].value;if(isNaN(K)){K=0}if(isNaN(H)){H=0}if(isNaN(J)){J=0}if(isNaN(i)){i=0}return{left:K,right:H,top:J,bottom:i}};z.prototype.matchCanvasSize=function(J){var O=this.data;var N=J.clientWidth;var I=J.clientHeight;var L,H=N,K=I;if("devicePixelRatio" in window){H*=devicePixelRatio; -K*=devicePixelRatio}for(var M=0;M=N;if(!M){if(!L){clearTimeout(this.redrawTimeout);this.redrawTimeout=setTimeout(function(){i.redraw()},N);return}this.lastDrawTime=O}setTimeout(function(){var ai=O;var ad=100;var V=i.data.cy;var ar=i.data;var al=i.getCachedNodes();var U=i.getCachedEdges();i.matchCanvasSize(ar.container);var R=V.zoom();var ac=Q!==undefined?Q:R; -var ak=V.pan();var ao={x:ak.x,y:ak.y};if(I){ao=I}if("devicePixelRatio" in window){ac*=devicePixelRatio;ao.x*=devicePixelRatio;ao.y*=devicePixelRatio}var ah=[];for(var am=0;am0){W.strokeStyle="rgba("+S["selection-box-border-color"].value[0]+","+S["selection-box-border-color"].value[1]+","+S["selection-box-border-color"].value[2]+","+S["selection-box-opacity"].value+")";W.strokeRect(ar.select[0],ar.select[1],ar.select[2]-ar.select[0],ar.select[3]-ar.select[1])}}if(ar.bgActivePosistion){var R=ar.cy.zoom();var ab=ar.bgActivePosistion;W.fillStyle="rgba("+S["active-bg-color"].value[0]+","+S["active-bg-color"].value[1]+","+S["active-bg-color"].value[2]+","+S["active-bg-opacity"].value+")"; -W.beginPath();W.arc(ab.x,ab.y,S["active-bg-size"].pxValue/R,0,2*Math.PI);W.fill()}if(!K){ar.canvasNeedsRedraw[D]=false;ar.canvasRedrawReason[D]=[]}}if(i.options.showOverlay){var W=ar.canvases[u].getContext("2d");W.lineJoin="round";W.font="14px helvetica";W.strokeStyle="#fff";W.lineWidth="4";W.fillStyle="#666";W.textAlign="right";var ag="cytoscape.js";var af=W.canvas.width;var an=W.canvas.height;var aj=4;var ap=W.measureText(ag).width;var Z=14;W.clearRect(0,0,af,an);W.strokeText(ag,af-aj,an-aj);W.fillText(ag,af-aj,an-aj); -ar.overlayDrawn=true}var Y=+new Date;if(i.averageRedrawTime===undefined){i.averageRedrawTime=Y-ai}i.averageRedrawTime=i.averageRedrawTime/2+(Y-ai)/2},0)};var l={};var h=30*300;z.prototype.getCachedImage=function(H,I){if(l[H]&&l[H].image){l[H].keepTime=h;return l[H].image}var i=l[H];if(i==undefined){l[H]=new Object();l[H].image=new Image();l[H].image.onload=I;l[H].image.src=H;l[H].keepTime=h;i=l[H]}return i.image};z.prototype.swapCachedImage=function(H){if(l[H]){if(l[H].image&&l[H].image.complete){var I=l[H].image; -var i=document.createElement("canvas");i.width=I.width;i.height=I.height;i.getContext("2d").drawImage(I,0,0);l[H].image=i;l[H].swappedWithCanvas=true;return i}else{return null}}else{return null}};z.prototype.updateImageCaches=function(){for(var i in l){if(l[i].keepTime<=0){if(l[i].image!=undefined){l[i].image.src=undefined;l[i].image=undefined}l[i]=undefined}else{l[i]-=1}}};z.prototype.drawImage=function(i,N,M,K,J,O,I){I.widthScale=0.5;I.heightScale=0.5;I.rotate=O;var L;var H;canvas.drawImage(I,N,M) -};z.prototype.drawEdge=function(I,K,L){if(this.hideEdgesOnViewport&&(this.dragData.didDrag||this.pinching||this.hoverData.dragging||this.data.wheel||this.swipePanning)){return}var M,Q;M=K.source()[0];Q=K.target()[0];if(K._private.style.visibility.value!="visible"||M._private.style.visibility.value!="visible"||Q._private.style.visibility.value!="visible"){return}var U=K._private.style["overlay-padding"].value;var S=K._private.style["overlay-opacity"].value;var T=K._private.style["overlay-color"].value; -if(L){I.strokeStyle="rgba( "+T[0]+", "+T[1]+", "+T[2]+", "+S+" )";I.lineCap="round";if(K._private.rscratch.edgeType=="self"){I.lineCap="butt"}}else{I.strokeStyle="rgba("+K._private.style["line-color"].value[0]+","+K._private.style["line-color"].value[1]+","+K._private.style["line-color"].value[2]+","+K._private.style.opacity.value+")"}if(K._private.style.width.value<=0){return}var R=K._private.style.width.value+(L?2*U:0);var O=L?"solid":K._private.style["line-style"].value;I.lineWidth=R;this.findEndpoints(K); -if(K._private.rscratch.edgeType=="self"){var i=K._private.rscratch;this.drawStyledEdge(K,I,[i.startX,i.startY,i.cp2ax,i.cp2ay,i.selfEdgeMidX,i.selfEdgeMidY],O,R);this.drawStyledEdge(K,I,[i.selfEdgeMidX,i.selfEdgeMidY,i.cp2cx,i.cp2cy,i.endX,i.endY],O,R)}else{if(K._private.rscratch.edgeType=="straight"){var J=Q._private.position.x-M._private.position.x;var H=Q._private.position.y-M._private.position.y;var P=K._private.rscratch.endX-K._private.rscratch.startX;var N=K._private.rscratch.endY-K._private.rscratch.startY; -if(J*P+H*N<0){K._private.rscratch.straightEdgeTooShort=true}else{var i=K._private.rscratch;this.drawStyledEdge(K,I,[i.startX,i.startY,i.endX,i.endY],O,R);K._private.rscratch.straightEdgeTooShort=false}}else{var i=K._private.rscratch;this.drawStyledEdge(K,I,[i.startX,i.startY,i.cp2x,i.cp2y,i.endX,i.endY],O,R)}}if(K._private.rscratch.noArrowPlacement!==true&&K._private.rscratch.startX!==undefined){this.drawArrowheads(I,K,L)}};var t=function(P,L,J){var I=Math.sqrt(Math.pow(P[4]-P[0],2)+Math.pow(P[5]-P[1],2)); -I+=Math.sqrt(Math.pow((P[4]+P[0])/2-P[2],2)+Math.pow((P[5]+P[1])/2-P[3],2));var O=Math.ceil(I/L);var H=I/L;var M;if(O>0){M=new Array(O*2)}else{return null}for(var K=0;K0){M=new Array(O*2)}else{return null}var H=[P[2]-P[0],P[3]-P[1]];for(var K=0;K=12){O._private.rstyle.bezierPts=[]}else{}}else{O._private.rstyle.bezierPts=[]}var R=O._private.rstyle.bezierPts;if(ab.length===6){R.push({x:aa(ab[0],ab[2],ab[4],0.05),y:aa(ab[1],ab[3],ab[5],0.05)});R.push({x:aa(ab[0],ab[2],ab[4],0.25),y:aa(ab[1],ab[3],ab[5],0.25)});R.push({x:aa(ab[0],ab[2],ab[4],0.35),y:aa(ab[1],ab[3],ab[5],0.35)});R.push({x:aa(ab[0],ab[2],ab[4],0.65),y:aa(ab[1],ab[3],ab[5],0.65)});R.push({x:aa(ab[0],ab[2],ab[4],0.75),y:aa(ab[1],ab[3],ab[5],0.75)});R.push({x:aa(ab[0],ab[2],ab[4],0.95),y:aa(ab[1],ab[3],ab[5],0.95)}) -}if(L=="solid"){K.beginPath();K.moveTo(ab[0],ab[1]);if(ab.length==3*2){K.quadraticCurveTo(ab[2],ab[3],ab[4],ab[5])}else{K.lineTo(ab[2],ab[3])}K.stroke()}else{if(L=="dotted"){var T;if(ab.length==3*2){T=t(ab,16,true)}else{T=s(ab,16,true)}if(!T){return}var N=Math.max(U*1.6,3.4)*I;var M=N*2,Q=N*2;M=Math.max(M,1);Q=Math.max(Q,1);var X=this.createBuffer(M,Q);var V=X[1];V.setTransform(1,0,0,1,0,0);V.clearRect(0,0,M,Q);V.fillStyle=K.strokeStyle;V.beginPath();V.arc(M/2,Q/2,N*0.5,0,Math.PI*2,false);V.fill(); -K.beginPath();for(var Y=0;Y0){K.stroke()}}else{var V=M._private.style["overlay-padding"].value;var Q=M._private.style["overlay-opacity"].value; -var R=M._private.style["overlay-color"].value;if(Q>0){K.fillStyle="rgba( "+R[0]+", "+R[1]+", "+R[2]+", "+Q+" )";q[this.getNodeShape(M)].draw(K,M._private.position.x,M._private.position.y,U+V*2,J+V*2)}}};z.prototype.drawInscribedImage=function(I,N,L){var i=this;var P=this.data.cy._private.zoom;var K=L._private.position.x;var J=L._private.position.y;var O=this.getNodeWidth(L);var H=this.getNodeHeight(L);I.save();q[i.getNodeShape(L)].drawPath(I,K,J,O,H);I.clip();var M=[N.width,N.height];I.drawImage(N,K-M[0]/2,J-M[1]/2,M[0],M[1]); -I.restore();if(L._private.style["border-width"].value>0){I.stroke()}};z.prototype.drawNodeText=function(I,J){if(J._private.style.visibility.value!="visible"){return}var M=J._private.style["font-size"].pxValue*J.cy().zoom();var i=J._private.style["min-zoomed-font-size"].pxValue;if(M0){H.lineWidth=P;H.strokeText(V,O,N)}if(isNaN(O)){O=0}if(isNaN(N)){N=0}H.fillText(""+V,O,N);L._private.rstyle.labelWidth=H.measureText(V).width}};z.prototype.drawBackground=function(I,H,i,J,K){};z.prototype.findEdgeControlPoints=function(Z){var H={};var ac=this.data.cy;var M=[];var V;for(var aq=0;aqZ[aq]._private.data.target?Z[aq]._private.data.target+"-"+Z[aq]._private.data.source:Z[aq]._private.data.source+"-"+Z[aq]._private.data.target; -if(H[V]==undefined){H[V]=[]}H[V].push(Z[aq]);M.push(V)}var ad,aj;for(var al=0;al1){U=aj._private.position.y-ad._private.position.y;T=ad._private.position.x-aj._private.position.x;var S=Math.sqrt(U*U+T*T);U/=S;T/=S}var R;for(var aq=0;aq=0&&J<=1){K.push(J) -}if(L>=0&&L<=1){K.push(L)}if(K.length==0){return[]}var aa=K[0]*U[0]+S;var Z=K[0]*U[1]+H;if(K.length>1){if(K[0]==K[1]){return[aa,Z]}else{var P=K[1]*U[0]+S;var O=K[1]*U[1]+H;return[aa,Z,P,O]}}else{return[aa,Z]}};z.prototype.findCircleNearPoint=function(K,J,L,P,O){var H=P-K;var i=O-J;var I=Math.sqrt(H*H+i*i);var N=H/I;var M=i/I;return[K+N*L,J+M*L]};z.prototype.findMaxSqDistanceToOrigin=function(K){var H=0.000001;var J;for(var I=0;IH){H=J}}return H -};z.prototype.finiteLinesIntersect=function(L,S,J,Q,H,P,T,N,R){var M=(T-H)*(S-P)-(N-P)*(L-H);var O=(J-L)*(S-P)-(Q-S)*(L-H);var K=(N-P)*(J-L)-(T-H)*(Q-S);if(K!=0){var I=M/K;var i=O/K;if(0<=I&&I<=1&&0<=i&&i<=1){return[L+I*(J-L),S+I*(Q-S)]}else{if(!R){return[]}else{return[L+I*(J-L),S+I*(Q-S)]}}}else{if(M==0||O==0){if([L,J,T].sort()[1]==T){return[T,N]}if([L,J,H].sort()[1]==H){return[H,P]}if([H,T,J].sort()[1]==J){return[J,Q]}return[]}else{return[]}}};z.prototype.boxIntersectEllipse=function(I,R,i,P,Q,H,U,M,K){if(iO[0]){return false}if(R>N[1]){return false}if(PQ){Q=S[aa*2]}if(S[aa*2]O){O=S[aa*2+1]}if(S[aa*2+1]Q+U){return false}if(KO+U){return false}var Z;if(U>0){var ai=B.expandPolygon(S,-U);Z=B.joinLines(ai)}else{Z=S}for(var aa=0;aa0){return true}if(B.finiteLinesIntersect(Y,X,ag,af,ad,K,ab,K,false).length>0){return true}if(B.finiteLinesIntersect(Y,X,ag,af,ad,N,ad,K,false).length>0){return true}if(B.finiteLinesIntersect(Y,X,ag,af,ab,N,ab,K,false).length>0){return true}}return false};z.prototype.polygonIntersectLine=function(N,M,H,K,I,Q,P,O){var Y=[];var L;var J=new Array(H.length); -for(var U=0;U0){var X=B.expandPolygon(J,-O);T=B.joinLines(X)}else{T=J}var S,R,W,V;for(var U=0;UR)){R=Math.abs(P[2*K])}if(Math.abs(P[2*K+1]>Q)){Q=Math.abs(P[2*K+1])}}var M=0.0005;var O=Math.max(R,Q);for(var K=0;KM){P[2*K]*=(1/O);P[2*K+1]*=(1/O)}}return P};var B=c;q.ellipse={draw:function(H,K,J,I,i){q.ellipse.drawPath(H,K,J,I,i);H.fill()},drawPath:function(H,K,J,I,i){H.beginPath();H.translate(K,J);H.scale(I/2,i/2);H.arc(0,0,1,0,Math.PI*2*0.999,false);H.closePath();H.scale(2/I,2/i);H.translate(-K,-J)},intersectLine:function(L,K,J,I,H,N,M){var i=c.intersectLineEllipse(H,N,L,K,J/2+M,I/2+M); -return i},intersectBox:function(I,N,i,L,H,O,K,J,M){return z.prototype.boxIntersectEllipse(I,N,i,L,M,H,O,K,J)},checkPointRough:function(H,M,L,I,i,K,J){return true},checkPoint:function(H,M,L,I,i,K,J){H-=K;M-=J;H/=(I/2+L);M/=(i/2+L);return(Math.pow(H,2)+Math.pow(M,2)<=1)}};q.triangle={points:k(3,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.triangle.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.triangle.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.triangle.points,K,J,I/2,H/2,L) -},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.triangle.points;return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.triangle.points,L,I,i,K,J)},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.triangle.points,K,J,I,i,[0,-1],L)}};q.square={points:k(4,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.square.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.square.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.square.points,K,J,I/2,H/2,L) -},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.square.points;return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.square.points,L,I,i,K,J)},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.square.points,K,J,I,i,[0,-1],L)}};q.rectangle=q.square;q.octogon={};q.roundrectangle={points:k(4,0),draw:function(H,K,J,I,i){B.drawRoundRectangle(H,K,J,I,i,10)},drawPath:function(H,K,J,I,i){B.drawRoundRectanglePath(H,K,J,I,i,10) -},intersectLine:function(K,J,I,H,i,M,L){return B.roundRectangleIntersectLine(i,M,K,J,I,H,L)},intersectBox:function(I,N,i,L,H,O,K,J,M){return B.roundRectangleIntersectBox(I,N,i,L,H,O,K,J,M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.roundrectangle.points,L,I,i,K,J)},checkPoint:function(N,L,M,i,O,J,H){var K=B.getRoundRectangleRadius(i,O);if(B.pointInsidePolygon(N,L,q.roundrectangle.points,J,H,i,O-2*K,[0,-1],M)){return true}if(B.pointInsidePolygon(N,L,q.roundrectangle.points,J,H,i-2*K,O,[0,-1],M)){return true -}var I=function(Q,V,U,S,R,P,T){Q-=U;V-=S;Q/=(R/2+T);V/=(P/2+T);return(Math.pow(Q,2)+Math.pow(V,2)<=1)};if(I(N,L,J-i/2+K,H-O/2+K,K*2,K*2,M)){return true}if(I(N,L,J+i/2-K,H-O/2+K,K*2,K*2,M)){return true}if(I(N,L,J+i/2-K,H+O/2-K,K*2,K*2,M)){return true}if(I(N,L,J-i/2+K,H+O/2-K,K*2,K*2,M)){return true}return false}};q.roundrectangle2={roundness:4.99,draw:function(I,H,i){if(H<=roundness*2){return}B.drawPolygon(I._private.position.x,I._private.position.y,H,i,nodeSapes.roundrectangle2.points)},intersectLine:function(J,I,H,i,K){return B.findPolygonIntersection(J,I,H,i,K,q.square.points) -},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.square.points}};q.pentagon={points:k(5,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.pentagon.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.pentagon.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.pentagon.points,K,J,I/2,H/2,L)},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.pentagon.points;return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.pentagon.points,L,I,i,K,J) -},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.pentagon.points,K,J,I,i,[0,-1],L)}};q.hexagon={points:k(6,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.hexagon.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.hexagon.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.hexagon.points,K,J,I/2,H/2,L)},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.hexagon.points;return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M) -},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.hexagon.points,L,I,i,K,J)},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.hexagon.points,K,J,I,i,[0,-1],L)}};q.heptagon={points:k(7,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.heptagon.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.heptagon.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.heptagon.points,K,J,I/2,H/2,L)},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.heptagon.points; -return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.heptagon.points,L,I,i,K,J)},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.heptagon.points,K,J,I,i,[0,-1],L)}};q.octagon={points:k(8,0),draw:function(H,K,J,I,i){B.drawPolygon(H,K,J,I,i,q.octagon.points)},drawPath:function(H,K,J,I,i){B.drawPolygonPath(H,K,J,I,i,q.octagon.points)},intersectLine:function(K,J,I,H,i,M,L){return B.polygonIntersectLine(i,M,q.octagon.points,K,J,I/2,H/2,L) -},intersectBox:function(I,N,i,L,H,P,K,J,M){var O=q.octagon.points;return B.boxIntersectPolygon(I,N,i,L,O,H,P,K,J,[0,-1],M)},checkPointRough:function(H,M,L,I,i,K,J){return B.checkInBoundingBox(H,M,q.octagon.points,L,I,i,K,J)},checkPoint:function(H,M,L,I,i,K,J){return B.pointInsidePolygon(H,M,q.octagon.points,K,J,I,i,[0,-1],L)}};var j=new Array(20);var g=k(5,0);var F=k(5,Math.PI/5);var o=0.5*(3-Math.sqrt(5));o*=1.57;for(var E=0;E0){var ad=B.expandPolygon(O,-U);X=B.joinLines(ad)}else{X=O}var aa,L,Z,K;var I;var R=0;var T=0;for(var Y=0;Y=S&&S>=Z)||(aa<=S&&S<=Z)){I=(S-aa)/(Z-aa)*(K-L)+L;if(I>Q){R++}if(I0){return I}var ah=ap+U+ai;var af=am-K+ag-ai;var i=ah;var an=am+K-ag+ai;I=this.finiteLinesIntersect(ae,ad,ap,am,ah,af,i,an,false);if(I.length>0){return I}var ab=ap-U+ag-ai;var Z=am+K+ai;var S=ap+U-ag+ai;var R=Z;I=this.finiteLinesIntersect(ae,ad,ap,am,ab,Z,S,R,false);if(I.length>0){return I}var Y=ap-U-ai;var X=am-K+ag-ai;var W=Y;var V=am+K-ag+ai;I=this.finiteLinesIntersect(ae,ad,ap,am,Y,X,W,V,false);if(I.length>0){return I -}var T;var Q=ap-U+ag;var P=am-K+ag;T=this.intersectLineCircle(ae,ad,ap,am,Q,P,ag+ai);if(T.length>0&&T[0]<=Q&&T[1]<=P){return[T[0],T[1]]}var M=ap+U-ag;var L=am-K+ag;T=this.intersectLineCircle(ae,ad,ap,am,M,L,ag+ai);if(T.length>0&&T[0]>=M&&T[1]<=L){return[T[0],T[1]]}var ao=ap+U-ag;var al=am+K-ag;T=this.intersectLineCircle(ae,ad,ap,am,ao,al,ag+ai);if(T.length>0&&T[0]>=ao&&T[1]>=al){return[T[0],T[1]]}var ac=ap-U+ag;var aa=am+K-ag;T=this.intersectLineCircle(ae,ad,ap,am,ac,aa,ag+ai);if(T.length>0&&T[0]<=ac&&T[1]>=aa){return[T[0],T[1]] -}};z.prototype.roundRectangleIntersectBox=function(M,S,L,R,T,Q,O,N,P){var I=this.getRoundRectangleRadius(T,Q);var H=O-T/2-P;var i=N-Q/2+I-P;var V=O+T/2+P;var U=N+Q/2-I+P;var Y=O-T/2+I-P;var W=N-Q/2-P;var K=O+T/2-I+P;var J=N+Q/2+P;var ab=Math.min(M,L);var aa=Math.max(M,L);var Z=Math.min(S,R);var X=Math.max(S,R);if(aaV){return false}}if(XJ){return false}}if(H>=ab&&H<=aa&&i>=Z&&i<=X){return true}if(V>=ab&&V<=aa&&i>=Z&&i<=X){return true}if(V>=ab&&V<=aa&&U>=Z&&U<=X){return true -}if(H>=ab&&H<=aa&&U>=Z&&U<=X){return true}if(ab>=H&&ab<=V&&Z>=i&&Z<=U){return true}if(aa>=H&&aa<=V&&Z>=i&&Z<=U){return true}if(aa>=H&&aa<=V&&X>=i&&X<=U){return true}if(ab>=H&&ab<=V&&X>=i&&X<=U){return true}if(Y>=ab&&Y<=aa&&W>=Z&&W<=X){return true}if(K>=ab&&K<=aa&&W>=Z&&W<=X){return true}if(K>=ab&&K<=aa&&J>=Z&&J<=X){return true}if(Y>=ab&&Y<=aa&&J>=Z&&J<=X){return true}if(ab>=Y&&ab<=K&&Z>=W&&Z<=J){return true}if(aa>=Y&&aa<=K&&Z>=W&&Z<=J){return true}if(aa>=Y&&aa<=K&&X>=W&&X<=J){return true}if(ab>=Y&&ab<=K&&X>=W&&X<=J){return true -}if(this.boxIntersectEllipse(ab,Z,aa,X,P,I*2,I*2,Y+P,i+P)){return true}if(this.boxIntersectEllipse(ab,Z,aa,X,P,I*2,I*2,K-P,i+P)){return true}if(this.boxIntersectEllipse(ab,Z,aa,X,P,I*2,I*2,K-P,U-P)){return true}if(this.boxIntersectEllipse(ab,Z,aa,X,P,I*2,I*2,Y+P,U-P)){return true}return false};z.prototype.checkInBoundingCircle=function(H,N,I,M,J,i,L,K){H=(H-L)/(J+M);N=(N-K)/(i+M);return(H*H+N*N)<=I};z.prototype.checkInBoundingBox=function(R,P,S,Q,J,T,N,M){var L=S[0],K=S[1];var I=S[0],H=S[1];for(var O=1; -OI){I=S[O*2]}}if(S[O*2+1]H){H=S[O*2+1]}}}R-=N;P-=M;R/=J;P/=T;if(RI){return false}}if(PH){return false}}return true};z.prototype.boxInBezierVicinity=function(T,N,Z,Q,V,M,U,L,R,J,S){var P=0.25*V+0.5*U+0.25*R;var O=0.25*M+0.5*L+0.25*J;var aa=Math.min(T,Z)-S;var X=Math.min(N,Q)-S;var Y=Math.max(T,Z)+S;var W=Math.max(N,Q)+S;if(V>=aa&&V<=Y&&M>=X&&M<=W){return 1}else{if(R>=aa&&R<=Y&&J>=X&&J<=W){return 1 -}else{if(P>=aa&&P<=Y&&O>=X&&O<=W){return 1}else{if(U>=aa&&U<=Y&&L>=X&&L<=W){return 1}}}}var K=Math.min(V,P,R);var I=Math.min(M,O,J);var H=Math.max(V,P,R);var i=Math.max(M,O,J);if(K>Y||HW||i=ac&&W<=aa&&Math.min(K,H)<=Z&&Math.max(K,H)>=Y)}var i=(ac-Q)/L;if(i>0&&i<=1){X=I*i+P;if(X>=Z&&X<=Y){return true}}var N=(aa-Q)/L;if(N>0&&N<=1){X=I*N+P;if(X>=Z&&X<=Y){return true}}var J=(Z-P)/I;if(J>0&&J<=1){S=L*J+Q;if(S>=ac&&S<=aa){return true}}var M=(Y-P)/I; -if(M>0&&M<=1){S=L*M+Q;if(S>=ac&&S<=aa){return true}}return false};z.prototype.checkBezierCrossesBox=function(Z,L,am,ab,T,aw,P,at,N,ap,H){var V=Math.min(Z,am)-H;var S=Math.min(L,ab)-H;var av=Math.max(Z,am)+H;var ar=Math.max(L,ab)+H;if(T>=V&&T<=av&&aw>=S&&aw<=ar){return true}else{if(N>=V&&N<=av&&ap>=S&&ap<=ar){return true}}var Y=T-2*P+N;var K=-2*T+2*P;var ai=T;var ac=[];if(Math.abs(Y)<0.0001){var an=(V-T)/K;var aa=(av-T)/K;ac.push(an,aa)}else{var af=K*K-4*Y*(ai-V);var W,U;if(af>0){var ag=Math.sqrt(af); -W=(-K+ag)/(2*Y);U=(-K-ag)/(2*Y);ac.push(W,U)}var ae=K*K-4*Y*(ai-av);var R,O;if(ae>0){var ag=Math.sqrt(ae);R=(-K+ag)/(2*Y);O=(-K-ag)/(2*Y);ac.push(R,O)}}ac.sort(function(ay,ax){return ay-ax});var X=aw-2*at+ap;var I=-2*aw+2*at;var ah=aw;var al=[];if(Math.abs(X)<0.0001){var J=(S-aw)/I;var aj=(ar-aw)/I;al.push(J,aj)}else{var Q=I*I-4*X*(ah-S);var i,au;if(Q>0){var ag=Math.sqrt(Q);i=(-I+ag)/(2*X);au=(-I-ag)/(2*X);al.push(i,au)}var M=I*I-4*X*(ah-ar);var aq,ao;if(M>0){var ag=Math.sqrt(M);aq=(-I+ag)/(2*X); -ao=(-I-ag)/(2*X);al.push(aq,ao)}}al.sort(function(ay,ax){return ay-ax});for(var ad=0;ad=0&&ac[ad]<=1&&ac[ad+1]>al[ak-1]&&al[ak-1]<=1&&ac[ad+1]>=0){return true}}}return false};z.prototype.inLineVicinity=function(Q,O,L,J,K,I,M){var R=M;var H=Math.min(L,K);var i=Math.max(L,K);var P=Math.min(J,I);var N=Math.max(J,I);return H-R<=Q&&Q<=i+R&&P-R<=O&&O<=N+R};z.prototype.inBezierVicinity=function(N,M,X,I,W,H,V,i,ac){var P=0.25*X+0.5*W+0.25*V; -var O=0.25*I+0.5*H+0.25*i;var K={x1:Math.min(X,V,P),x2:Math.max(X,V,P),y1:Math.min(I,i,O),y2:Math.max(I,i,O)};if(NK.x2||MK.y2){return false}else{}var S,R,aa,Y;var L,J,Q;var ab=function(ae,ak,af,ad,aj,ai,ag,ah){L=(ai-ad)*(ae-af)+(af-aj)*(ak-ad);J=L*L;sideSquared=(ai-ad)*(ai-ad)+(af-aj)*(af-aj);if(ah){if(L>0){return false}}else{if(L<0){return false}}return(J/sideSquared>ag)};var U=(P+W)/2;var T=(O+H)/2;var Z=true;if(ab(U,T,X,I,W,H,0,Z)){Z=!Z}return(!ab(N,M,X,I,W,H,ac,Z)&&!ab(N,M,W,H,V,i,ac,Z)&&!ab(N,M,V,i,X,I,ac,Z)) -};z.prototype.solveCubic=function(O,N,M,L,S){N/=O;M/=O;L/=O;var Q,H,i,J,R,P,I,K;H=(3*M-(N*N))/9;i=-(27*L)+N*(9*M-2*(N*N));i/=54;Q=H*H*H+i*i;S[1]=0;I=(N/3);if(Q>0){R=i+Math.sqrt(Q);R=((R<0)?-Math.pow(-R,(1/3)):Math.pow(R,(1/3)));P=i-Math.sqrt(Q);P=((P<0)?-Math.pow(-P,(1/3)):Math.pow(P,(1/3)));S[0]=-I+R+P;I+=(R+P)/2;S[4]=S[2]=-I;I=Math.sqrt(3)*(-P+R)/2;S[3]=I;S[5]=-I;return}S[5]=S[3]=0;if(Q==0){K=((i<0)?-Math.pow(-i,(1/3)):Math.pow(i,(1/3)));S[0]=-I+2*K;S[4]=S[2]=-(K+I);return}H=-H;J=H*H*H;J=Math.acos(i/Math.sqrt(J)); -K=2*Math.sqrt(H);S[0]=-I+K*Math.cos(J/3);S[2]=-I+K*Math.cos((J+2*Math.PI)/3);S[4]=-I+K*Math.cos((J+4*Math.PI)/3);return};z.prototype.sqDistanceToQuadraticBezier=function(R,Q,W,L,V,K,U,J){var ac=1*W*W-4*W*V+2*W*U+4*V*V-4*V*U+U*U+L*L-4*L*K+2*L*J+4*K*K-4*K*J+J*J;var ab=1*9*W*V-3*W*W-3*W*U-6*V*V+3*V*U+9*L*K-3*L*L-3*L*J-6*K*K+3*K*J;var Z=1*3*W*W-6*W*V+W*U-W*R+2*V*V+2*V*R-U*R+3*L*L-6*L*K+L*J-L*Q+2*K*K+2*K*Q-J*Q;var Y=1*W*V-W*W+W*R-V*R+L*K-L*L+L*Q-K*Q;A("coefficients: "+ac/ac+", "+ab/ac+", "+Z/ac+", "+Y/ac); -var M=[];this.solveCubic(ac,ab,Z,Y,M);var H=1e-7;var aa=[];for(var N=0;N<6;N+=2){if(Math.abs(M[N+1])=0&&M[N]<=1){aa.push(M[N])}}aa.push(1);aa.push(0);var I=-1;var X;var P,O,S;for(var T=0;T=0){if(SJ){return(O-i)*(O-i)+(L-M)*(L-M)}return(Q-K)};var A=function(){};w("renderer","canvas",z)})(cytoscape);(function(a){var b={ready:function(){},stop:function(){}};function c(d){this.options=a.util.extend(true,{},b,d)}c.prototype.run=function(){var d=this.options; -var e=d.cy;e.nodes().positions(function(){return{x:0,y:0}});e.one("layoutready",d.ready);e.trigger("layoutready");e.one("layoutstop",d.stop);e.trigger("layoutstop")};c.prototype.stop=function(){var d=this.options;cy.one("layoutstop",d.stop);cy.trigger("layoutstop")};a("layout","null",c)})(cytoscape);(function(a){var c={ready:undefined,stop:undefined,fit:true,padding:30};function b(d){this.options=a.util.extend(true,{},c,d)}b.prototype.run=function(){var h=this.options;var j=h.cy;var g=j.nodes();var f=j.edges(); -var e=j.container();var i=e.clientWidth;var d=e.clientHeight;g.positions(function(l,k){if(k.locked()){return false}return{x:Math.round(Math.random()*i),y:Math.round(Math.random()*d)}});j.one("layoutready",h.ready);j.trigger("layoutready");if(h.fit){j.fit(h.padding)}j.one("layoutstop",h.stop);j.trigger("layoutstop")};b.prototype.stop=function(){};a("layout","random",b)})(cytoscape);(function(a){var c={fit:true,rows:undefined,columns:undefined,ready:undefined,stop:undefined};function b(d){this.options=a.util.extend({},c,d) -}b.prototype.run=function(){var z=this.options;var h=z;var g=z.cy;var u=g.nodes();var f=g.edges();var q=g.container();var t=q.clientWidth;var s=q.clientHeight;if(s==0||t==0){u.positions(function(){return{x:0,y:0}})}else{var i=u.size();var o=Math.sqrt(i*s/t);var m=Math.round(o);var p=Math.round(t/s*o);function l(B){if(B==undefined){return Math.min(m,p)}else{var A=Math.min(m,p);if(A==m){m=B}else{p=B}}}function e(B){if(B==undefined){return Math.max(m,p)}else{var A=Math.max(m,p);if(A==m){m=B}else{p=B -}}}if(h.rows!=null&&h.columns!=null){m=h.rows;p=h.columns}else{if(h.rows!=null&&h.columns==null){m=h.rows;p=Math.ceil(i/m)}else{if(h.rows==null&&h.columns!=null){p=h.columns;m=Math.ceil(i/p)}else{if(p*m>i){var w=l();var r=e();if((w-1)*r>=i){l(w-1)}else{if((r-1)*w>=i){e(r-1)}}}else{while(p*m=i){e(r+1)}else{l(w+1)}}}}}}var v=t/p;var d=s/m;var k=0;var j=0;u.positions(function(C,B){if(B.locked()){return false}var A=j*v+v/2;var D=k*d+d/2;j++;if(j>=p){j=0;k++}return{x:A,y:D} -})}if(z.fit){g.reset()}g.one("layoutready",z.ready);g.trigger("layoutready");g.one("layoutstop",z.stop);g.trigger("layoutstop")};b.prototype.stop=function(){};a("layout","grid",b)})(cytoscape);(function(a){var c={fit:true,ready:undefined,stop:undefined,positions:undefined,zoom:undefined,pan:undefined,padding:30};function b(d){this.options=a.util.extend(true,{},c,d)}b.prototype.run=function(){var g=this.options;var i=g.cy;var f=i.nodes();var e=i.edges();var d=i.container();function h(j){if(g.positions==null){return null -}if(g.positions[j._private.data.id]==null){return null}return g.positions[j._private.data.id]}f.positions(function(k,l){var j=h(l);if(l.locked()||j==null){return false}return j});if(g.pan!=null){i.pan(g.pan)}if(g.zoom!=null){i.zoom(g.zoom)}i.one("layoutready",g.ready);i.trigger("layoutready");if(g.fit){i.fit(g.padding)}i.one("layoutstop",g.stop);i.trigger("layoutstop")};a("layout","preset",b);a("core","presetLayout",function(){var f=this;var d={};var e={};f.nodes().each(function(g,h){e[h.data("id")]=h.position() -});d.positions=e;d.name="preset";d.zoom=f.zoom();d.pan=f.pan();return d})})(cytoscape);(function(a){var b={liveUpdate:true,ready:undefined,stop:undefined,maxSimulationTime:4000,fit:true,padding:[50,50,50,50],ungrabifyWhileSimulating:true,repulsion:undefined,stiffness:undefined,friction:undefined,gravity:true,fps:undefined,precision:undefined,nodeMass:undefined,edgeLength:undefined,stepSize:1,stableEnergy:function(d){var f=d;return(f.max<=0.5)||(f.mean<=0.3)}};function c(d){this.options=a.util.extend({},b,d) -}c.prototype.run=function(){var k=this.options;var j=k.cy;var v=j.nodes();var i=j.edges();var q=j.container();var u=q.clientWidth;var s=q.clientHeight;if(j.nodes().size()<=1){if(k.fit){j.reset()}j.nodes().position({x:Math.round(u/2),y:Math.round(s/2)});j.one("layoutstop",k.stop);j.trigger("layoutstop");j.one("layoutstop",k.stop);j.trigger("layoutstop");return}var m=this.system=arbor.ParticleSystem(k.repulsion,k.stiffness,k.friction,k.gravity,k.fps,k.dt,k.precision);this.system=m;if(k.liveUpdate&&k.fit){j.reset() -}var t=250;var g;var p=false;var f=+new Date;var r={init:function(z){},redraw:function(){var A=m.energy();if(k.stableEnergy!=null&&A!=null&&A.n>0&&k.stableEnergy(A)){m.stop();return}clearTimeout(g);g=setTimeout(w,t);var B=[];m.eachNode(function(H,C){var G=H.name;var E=H.data;var D=E.element;if(D==null){return}var F=D._private.position;if(!D.locked()&&!D.grabbed()){F.x=C.x;F.y=C.y;B.push(D)}});var z=(+new Date-f)>=16;if(k.liveUpdate&&B.length>0&&z){new a.Collection(j,B).rtrigger("position");f=+new Date -}if(!p){p=true;j.one("layoutready",k.ready);j.trigger("layoutready")}}};m.renderer=r;m.screenSize(u,s);m.screenPadding(k.padding[0],k.padding[1],k.padding[2],k.padding[3]);m.screenStep(k.stepSize);function o(z,A){if(A==null){return undefined}else{if(typeof A==typeof function(){}){return A.apply(z,[z._private.data,{nodes:v.length,edges:i.length,element:z}])}else{return A}}}function d(D){var G=D.x;var E=D.y;var H=u;var B=s;var A=-2;var I=2;var F=-2;var z=2;var C=4;return{x:G/H*C+A,y:E/B*C+I}}var l=function(A){grabbed=this; -var B=m.fromScreen(this.position());var z=arbor.Point(B.x,B.y);this.scratch().arbor.p=z;switch(A.type){case"grab":this.scratch().arbor.fixed=true;break;case"dragstop":this.scratch().arbor.fixed=false;this.scratch().arbor.tempMass=1000;break}};v.bind("grab drag dragstop",l);v.each(function(B,C){var E=this._private.data.id;var A=o(this,k.nodeMass);var z=this._private.locked;var D=d({x:C.position().x,y:C.position().y});if(C.locked()){return}this.scratch().arbor=m.addNode(E,{element:this,mass:A,fixed:z,x:z?D.x:undefined,y:z?D.y:undefined}) -});i.each(function(){var C=this.id();var A=this.source().id();var B=this.target().id();var z=o(this,k.edgeLength);this.scratch().arbor=m.addEdge(A,B,{length:z})});function h(z){if(k.fit){j.fit()}z()}var e=v.filter(":grabbable");if(k.ungrabifyWhileSimulating){e.ungrabify()}var w=function(){if(window.isIE){h(function(){z()})}else{z()}function z(){if(!k.liveUpdate){if(k.fit){j.reset()}j.nodes().rtrigger("position")}v.unbind("grab drag dragstop",l);if(k.ungrabifyWhileSimulating){e.grabify()}j.one("layoutstop",k.stop); -j.trigger("layoutstop")}};m.start();setTimeout(function(){m.stop()},k.maxSimulationTime)};c.prototype.stop=function(){if(this.system!=null){system.stop()}};a("layout","arbor",c)})(cytoscape);(function(a){var c={fit:true,ready:undefined,stop:undefined,rStepSize:10,padding:30,startAngle:3/2*Math.PI,counterclockwise:false};function b(d){this.options=a.util.extend({},c,d)}b.prototype.run=function(){var o=this.options;var w=o;var m=o.cy;var f=m.nodes();var p=m.edges();var g=m.container();var h=g.clientWidth; -var v=g.clientHeight;var e={x:h/2,y:v/2};var u=50;var j=w.startAngle;var s=2*Math.PI/f.length;var t=0;for(var q=0;qh||Q===0){S+=R/W;T++}}T=Math.max(1,T);S=S/T;if(T===0){S=undefined -}e[Y.id()]=S;return S}for(var t=0;t<3;t++){for(var J=0;J0&&q[0].length<=3?S/2:0);var h=2*Math.PI/q[w].length*Q; -if(w===0&&q[0].length===1){R=1}return{x:O.x+R*Math.cos(h),y:O.y+R*Math.sin(h)}}else{return{x:(Q+1)*U,y:(w+1)*T}}});if(N.fit){j.fit(m.padding)}j.one("layoutready",N.ready);j.trigger("layoutready");j.one("layoutstop",N.stop);j.trigger("layoutstop")};c.prototype.stop=function(){};a("layout","breadthfirst",c)})(cytoscape); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.js deleted file mode 100755 index ddaf7db957..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.js +++ /dev/null @@ -1,348 +0,0 @@ - -/* jquery.cxtmenu.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -;(function($){ - - var defaults = { - menuRadius: 100, - cytoscape: true, - selector: undefined, - commands: [], - fillColor: 'rgba(0, 0, 0, 0.75)', - activeFillColor: 'rgba(92, 194, 237, 0.75)', - activePadding: 20, - indicatorSize: 30, - indicatorColor: 'black', - separatorWidth: 3, - spotlightPadding: 4, - itemColor: 'white', - itemTextShadowColor: 'black' - }; - - $.fn.cxtmenu = function(params){ - var options = $.extend(true, {}, defaults, params); - var fn = params; - var $container = $(this); - var cy; - - $container.cytoscape(function(e){ - cy = this; - }); - - var functions = { - destroy: function(){ - - }, - - init: function(){ - var $parent = $('
                      '); - var $canvas = $(''); - var c2d = $canvas[0].getContext('2d'); - var r = options.menuRadius; - var offset = $container.offset(); - var containerSize = (r + options.activePadding)*2; - var activeCommandI = undefined; - - $container.append( $parent ); - $parent.append( $canvas ); - - $parent.css({ - width: containerSize + 'px', - height: containerSize + 'px', - position: 'fixed', - zIndex: 999999, - marginLeft: offset.left - options.activePadding + 'px', - marginTop: offset.top - options.activePadding + 'px' - }).hide(); - - $canvas[0].width = containerSize; - $canvas[0].height = containerSize; - - var commands = options.commands; - var dtheta = 2*Math.PI/(commands.length); - var theta1 = commands.length % 2 !== 0 ? Math.PI/2 : 0; - var theta2 = theta1 + dtheta; - var $items = []; - - for( var i = 0; i < commands.length; i++ ){ - var command = commands[i]; - - var midtheta = (theta1 + theta2)/2; - var rx1 = 0.66 * r * Math.cos( midtheta ); - var ry1 = 0.66 * r * Math.sin( midtheta ); - - // console.log(rx1, ry1, theta1, theta2) - - var $item = $('
                      '); - $item.css({ - color: options.itemColor, - cursor: 'default', - display: 'table', - 'text-align': 'center', - //background: 'red', - position: 'absolute', - 'text-shadow': '-1px -1px ' + options.itemTextShadowColor + ', 1px -1px ' + options.itemTextShadowColor + ', -1px 1px ' + options.itemTextShadowColor + ', 1px 1px ' + options.itemTextShadowColor, - left: '50%', - top: '50%', - 'min-height': r * 0.66, - width: r * 0.66, - height: r * 0.66, - marginLeft: rx1 - r * 0.33, - marginTop: -ry1 -r * 0.33 - }); - - var $content = $('
                      ' + command.content + '
                      '); - $content.css({ - 'width': r * 0.66, - 'height': r * 0.66, - 'vertical-align': 'middle', - 'display': 'table-cell' - }); - - $parent.append( $item ); - $item.append( $content ); - - - theta1 += dtheta; - theta2 += dtheta; - } - - function drawBg( rspotlight ){ - rspotlight = rspotlight !== undefined ? rspotlight : rs; - - c2d.globalCompositeOperation = 'source-over'; - - c2d.clearRect(0, 0, containerSize, containerSize); - - c2d.fillStyle = options.fillColor; - c2d.beginPath(); - c2d.arc(r + options.activePadding, r + options.activePadding, r, 0, Math.PI*2, true); - c2d.closePath(); - c2d.fill(); - - c2d.globalCompositeOperation = 'destination-out'; - c2d.strokeStyle = 'white'; - c2d.lineWidth = options.separatorWidth; - var commands = options.commands; - var dtheta = 2*Math.PI/(commands.length); - var theta1 = commands.length % 2 !== 0 ? Math.PI/2 : 0; - var theta2 = theta1 + dtheta; - - for( var i = 0; i < commands.length; i++ ){ - var command = commands[i]; - - var rx1 = r * Math.cos(theta1); - var ry1 = r * Math.sin(theta1); - c2d.beginPath(); - c2d.moveTo(r + options.activePadding, r + options.activePadding); - c2d.lineTo(r + options.activePadding + rx1, r + options.activePadding - ry1); - c2d.closePath(); - c2d.stroke(); - - // var rx2 = r * Math.cos(theta2); - // var ry2 = r * Math.sin(theta2); - // c2d.moveTo(r, r); - // c2d.lineTo(r + rx2, r + ry2); - // c2d.stroke(); - - theta1 += dtheta; - theta2 += dtheta; - } - - - c2d.fillStyle = 'white'; - c2d.globalCompositeOperation = 'destination-out'; - c2d.beginPath(); - c2d.arc(r + options.activePadding, r + options.activePadding, rspotlight + options.spotlightPadding, 0, Math.PI*2, true); - c2d.closePath(); - c2d.fill(); - - c2d.globalCompositeOperation = 'source-over'; - } - - var lastCallTime = 0; - var minCallDelta = 1000/30; - var endCallTimeout; - var firstCall = true; - function rateLimitedCall( fn ){ - var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame; - var now = +new Date; - - clearTimeout( endCallTimeout ); - - if( firstCall || now >= lastCallTime + minCallDelta ){ - requestAnimationFrame(fn); - lastCallTime = now; - firstCall = false; - } else { - endCallTimeout = setTimeout(function(){ - requestAnimationFrame(fn); - lastCallTime = now; - }, minCallDelta * 2); - } - } - - var ctrx, ctry, rs; - var tapendHandler; - - cy - .on('cxttapstart', options.selector, function(e){ - var ele = this; - var rp = ele.renderedPosition(); - var rw = ele.renderedWidth(); - var rh = ele.renderedHeight(); - var scrollLeft = $(window).scrollLeft(); - var scrollTop = $(window).scrollTop(); - - ctrx = rp.x; - ctry = rp.y; - - $parent.show().css({ - 'left': rp.x - r - scrollLeft, - 'top': rp.y - r - scrollTop - }); - - rs = Math.max(rw, rh); - rs = 32; - - drawBg(); - - activeCommandI = undefined; - }) - - .on('cxtdrag', options.selector, function(e){ rateLimitedCall(function(){ - - var dx = e.originalEvent.pageX - $container.offset().left - ctrx; - var dy = e.originalEvent.pageY - $container.offset().top - ctry; - - if( dx === 0 ){ dx = 0.01; } - - var d = Math.sqrt( dx*dx + dy*dy ); - var cosTheta = (dy*dy - d*d - dx*dx)/(-2 * d * dx); - var theta = Math.acos( cosTheta ); - - activeCommandI = undefined; - - if( d < rs + options.spotlightPadding ){ - drawBg(); - return; - } - - drawBg(); - - var rx = dx*r / d; - var ry = dy*r / d; - - if( dy > 0 ){ - theta = Math.PI + Math.abs(theta - Math.PI); - } - - var commands = options.commands; - var dtheta = 2*Math.PI/(commands.length); - var theta1 = commands.length % 2 !== 0 ? Math.PI/2 : 0; - var theta2 = theta1 + dtheta; - - for( var i = 0; i < commands.length; i++ ){ - var command = commands[i]; - - - // console.log(i, theta1, theta, theta2); - - var inThisCommand = theta1 <= theta && theta <= theta2 - || theta1 <= theta + 2*Math.PI && theta + 2*Math.PI <= theta2; - - if( inThisCommand ){ - // console.log('in command ' + i) - - c2d.fillStyle = options.activeFillColor; - c2d.strokeStyle = 'black'; - c2d.lineWidth = 1; - c2d.beginPath(); - c2d.moveTo(r + options.activePadding, r + options.activePadding); - c2d.arc(r + options.activePadding, r + options.activePadding, r + options.activePadding, 2*Math.PI - theta1, 2*Math.PI - theta2, true); - c2d.closePath(); - c2d.fill(); - //c2d.stroke(); - - activeCommandI = i; - - break; - } - - theta1 += dtheta; - theta2 += dtheta; - } - - c2d.fillStyle = 'white'; - c2d.globalCompositeOperation = 'destination-out'; - - // clear the indicator - c2d.beginPath(); - //c2d.arc(r + rx/r*(rs + options.spotlightPadding), r + ry/r*(rs + options.spotlightPadding), options.indicatorSize, 0, 2*Math.PI, true); - - c2d.translate( r + options.activePadding + rx/r*(rs + options.spotlightPadding - options.indicatorSize/4), r + options.activePadding + ry/r*(rs + options.spotlightPadding - options.indicatorSize/4) ); - c2d.rotate( Math.PI/4 - theta ); - c2d.fillRect(-options.indicatorSize/2, -options.indicatorSize/2, options.indicatorSize, options.indicatorSize); - c2d.closePath(); - c2d.fill(); - - c2d.setTransform(1, 0, 0, 1, 0, 0); - - // clear the spotlight - c2d.beginPath(); - c2d.arc(r + options.activePadding, r + options.activePadding, rs + options.spotlightPadding, 0, Math.PI*2, true); - c2d.closePath(); - c2d.fill(); - - c2d.globalCompositeOperation = 'source-over'; - }) }) - - .on('cxttapend', options.selector, function(e){ - var ele = this; - $parent.hide(); - - if( activeCommandI !== undefined ){ - var select = options.commands[ activeCommandI ].select; - - if( select ){ - select.apply( ele ); - } - } - }) - - .on('cxttapend', function(e){ - $parent.hide(); - }) - ; - } - }; - - if( functions[fn] ){ - return functions[fn].apply(this, Array.prototype.slice.call( arguments, 1 )); - } else if( typeof fn == 'object' || !fn ) { - return functions.init.apply( this, arguments ); - } else { - $.error("No such function `"+ fn +"` for jquery.cxtmenu"); - } - - return $(this); - }; - -})(jQuery); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.min.js deleted file mode 100755 index b42a48a940..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cxtmenu.min.js +++ /dev/null @@ -1,30 +0,0 @@ - -/* jquery.cxtmenu.min.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -(function(a){var b={menuRadius:100,cytoscape:true,selector:undefined,commands:[],fillColor:"rgba(0, 0, 0, 0.75)",activeFillColor:"rgba(92, 194, 237, 0.75)",activePadding:20,indicatorSize:30,indicatorColor:"black",separatorWidth:3,spotlightPadding:4,itemColor:"white",itemTextShadowColor:"black"};a.fn.cxtmenu=function(g){var c=a.extend(true,{},b,g);var d=g;var f=a(this);var h;f.cytoscape(function(i){h=this});var e={destroy:function(){},init:function(){var D=a('
                      ');var w=a(""); -var F=w[0].getContext("2d");var A=c.menuRadius;var u=f.offset();var H=(A+c.activePadding)*2;var y=undefined;f.append(D);D.append(w);D.css({width:H+"px",height:H+"px",position:"fixed",zIndex:999999,marginLeft:u.left-c.activePadding+"px",marginTop:u.top-c.activePadding+"px"}).hide();w[0].width=H;w[0].height=H;var v=c.commands;var z=2*Math.PI/(v.length);var E=v.length%2!==0?Math.PI/2:0;var C=E+z;var o=[];for(var J=0;J
                      ');j.css({color:c.itemColor,cursor:"default",display:"table","text-align":"center",position:"absolute","text-shadow":"-1px -1px "+c.itemTextShadowColor+", 1px -1px "+c.itemTextShadowColor+", -1px 1px "+c.itemTextShadowColor+", 1px 1px "+c.itemTextShadowColor,left:"50%",top:"50%","min-height":A*0.66,width:A*0.66,height:A*0.66,marginLeft:K-A*0.33,marginTop:-t-A*0.33});var s=a('
                      '+p.content+"
                      ");s.css({width:A*0.66,height:A*0.66,"vertical-align":"middle",display:"table-cell"}); -D.append(j);j.append(s);E+=z;C+=z}function k(S){S=S!==undefined?S:x;F.globalCompositeOperation="source-over";F.clearRect(0,0,H,H);F.fillStyle=c.fillColor;F.beginPath();F.arc(A+c.activePadding,A+c.activePadding,A,0,Math.PI*2,true);F.closePath();F.fill();F.globalCompositeOperation="destination-out";F.strokeStyle="white";F.lineWidth=c.separatorWidth;var r=c.commands;var T=2*Math.PI/(r.length);var Q=r.length%2!==0?Math.PI/2:0;var P=Q+T;for(var O=0;O=q+M){N(r);q=i;L=false}else{G=setTimeout(function(){N(r);q=i},M*2)}}var n,l,x;var B;h.on("cxttapstart",c.selector,function(P){var N=this;var r=N.renderedPosition();var R=N.renderedWidth();var i=N.renderedHeight();var Q=a(window).scrollLeft();var O=a(window).scrollTop();n=r.x;l=r.y;D.show().css({left:r.x-A-Q,top:r.y-A-O});x=Math.max(R,i);x=32;k();y=undefined}).on("cxtdrag",c.selector,function(i){m(function(){var Z=i.originalEvent.pageX-f.offset().left-n;var Y=i.originalEvent.pageY-f.offset().top-l; -if(Z===0){Z=0.01}var W=Math.sqrt(Z*Z+Y*Y);var V=(Y*Y-W*W-Z*Z)/(-2*W*Z);var O=Math.acos(V);y=undefined;if(W0){O=Math.PI+Math.abs(O-Math.PI)}var P=c.commands;var X=2*Math.PI/(P.length);var U=P.length%2!==0?Math.PI/2:0;var T=U+X;for(var S=0;S. - */ - -;(function($){ - - var defaults = { - preview: true, - handleSize: 10, - handleColor: "#ff0000", - handleLineWidth: 1, - hoverDelay: 150, - enabled: true, - lineType: "draw", // can be "straight" or "draw" - edgeType: function( sourceNode, targetNode ){ - return "node"; // can return "flat" for flat edges between nodes or "node" for intermediate node between them - // returning null/undefined means an edge can't be added between the two nodes - }, - loopAllowed: function( node ){ - return false; - }, - nodeParams: function( sourceNode, targetNode ){ - return {}; - }, - edgeParams: function( sourceNode, targetNode ){ - return {}; - }, - start: function( sourceNode ){ - // fired when edgehandles interaction starts (drag on handle) - }, - complete: function( sourceNode, targetNodes, addedEntities ){ - // fired when edgehandles is done and entities are added - }, - stop: function( sourceNode ){ - // fired when edgehandles interaction is stopped (either complete with added edges or incomplete) - } - }; - - $.fn.cytoscapeEdgehandles = function( params ){ - var fn = params; - - var functions = { - destroy: function(){ - var $container = $(this); - var data = $container.data("cyedgehandles"); - - if( data == null ){ - return; - } - - data.unbind(); - $container.data("cyedgehandles", {}); - - return $container; - }, - - option: function(name, value){ - var $container = $(this); - var data = $container.data("cyedgehandles"); - - if( data == null ){ - return; - } - - var options = data.options; - - if( value === undefined ){ - if( typeof name == typeof {} ){ - var newOpts = name; - options = $.extend(true, {}, defaults, newOpts); - data.options = options; - } else { - return options[ name ]; - } - } else { - options[ name ] = value; - } - - $container.data("cyedgehandles", data); - - return $container; - }, - - disable: function(){ - return functions.option.apply(this, ["enabled", false]); - }, - - enable: function(){ - return functions.option.apply(this, ["enabled", true]); - }, - - init: function(){ - var opts = $.extend(true, {}, defaults, params); - var $container = $(this); - var cy; - var $canvas = $(''); - var handle; - var line, linePoints; - var mdownOnHandle = false; - var grabbingNode = false; - var inForceStart = false; - var hx, hy, hr; - var hoverTimeout; - var drawsClear = true; - - $container.append( $canvas ); - - function sizeCanvas(){ - $canvas - .attr('height', $container.height()) - .attr('width', $container.width()) - .css({ - 'position': 'absolute', - 'z-index': '999' - }) - ; - } - sizeCanvas(); - - $(window).bind('resize', function(){ - sizeCanvas(); - }); - - - var ctx = $canvas[0].getContext("2d"); - - // write options to data - var data = $container.data("cyedgehandles"); - if( data == null ){ - data = {}; - } - data.options = opts; - - function options(){ - return $container.data("cyedgehandles").options; - } - - function enabled(){ - return options().enabled; - } - - function disabled(){ - return !enabled(); - } - - function clearDraws(){ - - if( drawsClear ){ return; } // break early to be efficient - - var w = $container.width(); - var h = $container.height(); - - ctx.clearRect( 0, 0, w, h ); - drawsClear = true; - } - - var lastPanningEnabled, lastZoomingEnabled, lastBoxSelectionEnabled; - function disableGestures(){ - lastPanningEnabled = cy.panningEnabled(); - lastZoomingEnabled = cy.zoomingEnabled(); - lastBoxSelectionEnabled = cy.boxSelectionEnabled(); - - cy - .zoomingEnabled(false) - .panningEnabled(false) - .boxSelectionEnabled(false) - ; - } - - function resetGestures(){ - cy - .zoomingEnabled(lastZoomingEnabled) - .panningEnabled(lastPanningEnabled) - .boxSelectionEnabled(lastBoxSelectionEnabled) - ; - } - - function resetToDefaultState(){ -// console.log("resetToDefaultState"); - - clearDraws(); - - //setTimeout(function(){ - cy.nodes() - .removeClass("ui-cytoscape-edgehandles-hover") - .removeClass("ui-cytoscape-edgehandles-source") - .removeClass("ui-cytoscape-edgehandles-target") - ; - //}, 1); - - - linePoints = null; - - resetGestures(); - } - - function makePreview( source, target ){ - makeEdges( true ); - - target.trigger('cyedgehandles.addpreview'); - } - - function removePreview( source, target ){ - source.edgesWith(target).filter(".ui-cytoscape-edgehandles-preview").remove(); - - target - .neighborhood("node.ui-cytoscape-edgehandles-preview") - .closedNeighborhood(".ui-cytoscape-edgehandles-preview") - .remove(); - - target.trigger('cyedgehandles.removepreview'); - - } - - function drawHandle(hx, hy, hr){ - ctx.fillStyle = options().handleColor; - ctx.strokeStyle = options().handleColor; - - ctx.beginPath(); - ctx.arc(hx, hy, hr, 0 , 2*Math.PI); - ctx.closePath(); - ctx.fill(); - - drawsClear = false; - } - - function drawLine(hx, hy, x, y){ - ctx.fillStyle = options().handleColor; - ctx.strokeStyle = options().handleColor; - ctx.lineWidth = options().handleLineWidth; - - // draw line based on type - switch( options().lineType ){ - case "straight": - - ctx.beginPath(); - ctx.moveTo(hx, hy); - ctx.lineTo(x, y); - ctx.closePath(); - ctx.stroke(); - - break; - case "draw": - default: - - if( linePoints == null ){ - linePoints = [ [x, y] ]; - } else { - linePoints.push([ x, y ]); - } - - ctx.beginPath(); - ctx.moveTo(hx, hy); - - for( var i = 0; i < linePoints.length; i++ ){ - var pt = linePoints[i]; - - ctx.lineTo(pt[0], pt[1]); - } - - ctx.stroke(); - - break; - } - - drawsClear = false; - } - - function makeEdges( preview, src, tgt ){ - - // console.log("make edges"); - - var source = src ? src : cy.nodes(".ui-cytoscape-edgehandles-source"); - var targets = tgt ? tgt : cy.nodes(".ui-cytoscape-edgehandles-target"); - var classes = preview ? "ui-cytoscape-edgehandles-preview" : ""; - var added = cy.collection(); - - if( source.size() === 0 || targets.size() === 0 ){ - return; // nothing to do :( - } - - // just remove preview class if we already have the edges - if( !src && !tgt ){ - if( !preview && options().preview ){ - added = cy.elements(".ui-cytoscape-edgehandles-preview").removeClass("ui-cytoscape-edgehandles-preview"); - - options().complete( source, targets, added ); - source.trigger('cyedgehandles.complete'); - return; - } else { - // remove old previews - cy.elements(".ui-cytoscape-edgehandles-preview").remove(); - } - } - - for( var i = 0; i < targets.length; i++ ){ - var target = targets[i]; - - switch( options().edgeType( source, target ) ){ - case "node": - - var p1 = source.position(); - var p2 = target.position(); - var p = { - x: (p1.x + p2.x)/2, - y: (p1.y + p2.y)/2 - }; - - var interNode = cy.add($.extend( true, { - group: "nodes", - position: p - }, options().nodeParams(source, target) )).addClass(classes); - - var source2inter = cy.add($.extend( true, { - group: "edges", - data: { - source: source.id(), - target: interNode.id() - } - }, options().edgeParams(source, target) )).addClass(classes); - - var inter2target = cy.add($.extend( true, { - group: "edges", - data: { - source: interNode.id(), - target: target.id() - } - }, options().edgeParams(source, target) )).addClass(classes); - - added = added.add( interNode ).add( source2inter ).add( inter2target ); - - break; - - case "flat": - var edge = cy.add($.extend( true, { - group: "edges", - data: { - source: source.id(), - target: target.id() - } - }, options().edgeParams(source, target) )).addClass(classes); - - added = added.add( edge ); - - break; - - default: - target.removeClass("ui-cytoscape-edgehandles-target"); - break; // don't add anything - } - } - - if( !preview ){ - options().complete( source, targets, added ); - source.trigger('cyedgehandles.complete'); - } - } - - $container.cytoscape(function(e){ - cy = this; - - lastPanningEnabled = cy.panningEnabled(); - lastZoomingEnabled = cy.zoomingEnabled(); - lastBoxSelectionEnabled = cy.boxSelectionEnabled(); - - // console.log('handles on ready') - - var lastActiveId; - - var transformHandler; - cy.bind("zoom pan", transformHandler = function(){ - clearDraws(); - }); - - var lastMdownHandler; - - var startHandler, hoverHandler, leaveHandler, grabNodeHandler, freeNodeHandler, dragNodeHandler, forceStartHandler, removeHandler; - cy.on("mouseover", "node", startHandler = function(e){ - - if( disabled() || mdownOnHandle || grabbingNode || this.hasClass("ui-cytoscape-edgehandles-preview") || inForceStart ){ - return; // don't override existing handle that's being dragged - // also don't trigger when grabbing a node etc - } - - //console.log("mouseover startHandler %s %o", this.id(), this); - - if( lastMdownHandler ){ - $container[0].removeEventListener('mousedown', lastMdownHandler, true); - } - - var node = this; - var source = this; - var p = node.renderedPosition(); - var h = node.renderedOuterHeight(); - - lastActiveId = node.id(); - - // remove old handle - clearDraws(); - - hr = options().handleSize/2 * cy.zoom(); - hx = p.x; - hy = p.y - h/2 - hr/2; - - // add new handle - drawHandle(hx, hy, hr); - - node.trigger('cyedgehandles.showhandle'); - - - function mdownHandler(e){ - $container[0].removeEventListener('mousedown', mdownHandler, true); - - var x = e.pageX - $container.offset().left; - var y = e.pageY - $container.offset().top; - - if( e.button !== 0 ){ - return; // sorry, no right clicks allowed - } - - if( Math.abs(x - hx) > hr || Math.abs(y - hy) > hr ){ - return; // only consider this a proper mousedown if on the handle - } - - if( inForceStart ){ - return; // we don't want this going off if we have the forced start to consider - } - - // console.log("mdownHandler %s %o", node.id(), node); - - mdownOnHandle = true; - - e.preventDefault(); - e.stopPropagation(); - - node.addClass("ui-cytoscape-edgehandles-source"); - node.trigger('cyedgehandles.start'); - - function doneMoving(dmEvent){ - // console.log("doneMoving %s %o", node.id(), node); - - if( !mdownOnHandle || inForceStart ){ - return; - } - - var $this = $(this); - mdownOnHandle = false; - $(window).unbind("mousemove", moveHandler); - - makeEdges(); - resetToDefaultState(); - - options().stop( node ); - node.trigger('cyedgehandles.stop'); - } - - $(window).one("mouseup blur", doneMoving).bind("mousemove", moveHandler); - disableGestures(); - - options().start( node ); - - return false; - } - - function moveHandler(e){ - // console.log("mousemove moveHandler %s %o", node.id(), node); - - var x = e.pageX - $container.offset().left; - var y = e.pageY - $container.offset().top; - - clearDraws(); - drawHandle(hx, hy, hr); - drawLine(hx, hy, x, y); - - return false; - } - - $container[0].addEventListener('mousedown', mdownHandler, true); - lastMdownHandler = mdownHandler; - - - }).on("mouseover touchover", "node", hoverHandler = function(){ - var node = this; - var target = this; - -// console.log('mouseover hoverHandler') - - if( disabled() || this.hasClass("ui-cytoscape-edgehandles-preview") ){ - return; // ignore preview nodes - } - - if( mdownOnHandle ){ // only handle mdown case - - // console.log( 'mouseover hoverHandler %s $o', node.id(), node ); - - clearTimeout( hoverTimeout ); - hoverTimeout = setTimeout(function(){ - var source = cy.nodes(".ui-cytoscape-edgehandles-source"); - - var isLoop = node.hasClass("ui-cytoscape-edgehandles-source"); - var loopAllowed = options().loopAllowed( node ); - - if( !isLoop || (isLoop && loopAllowed) ){ - node.addClass("ui-cytoscape-edgehandles-hover"); - node.toggleClass("ui-cytoscape-edgehandles-target"); - - if( options().preview ){ - if( node.hasClass("ui-cytoscape-edgehandles-target") ){ - makePreview( source, target ); - } else { - removePreview( source, target ); - } - } - } - }, options().hoverDelay); - - return false; - } - - }).on("mouseout", "node", leaveHandler = function(){ - if( this.hasClass("ui-cytoscape-edgehandles-hover") ){ - this.removeClass("ui-cytoscape-edgehandles-hover"); - } - - if( mdownOnHandle ){ - clearTimeout(hoverTimeout); - } - - }).on("drag position", "node", dragNodeHandler = function(){ - setTimeout(clearDraws, 50); - - }).on("grab", "node", grabHandler = function(){ - grabbingNode = true; - - setTimeout(function(){ - clearDraws(); - }, 5); - - - }).on("free", "node", freeNodeHandler = function(){ - grabbingNode = false; - - }).on("cyedgehandles.forcestart", "node", forceStartHandler = function(){ - inForceStart = true; - clearDraws(); // clear just in case - - var node = this; - var source = node; - - lastActiveId = node.id(); - - node.trigger('cyedgehandles.start'); - node.addClass('ui-cytoscape-edgehandles-source'); - - var p = node.renderedPosition(); - var h = node.renderedOuterHeight(); - var w = node.renderedOuterWidth(); - - var hr = options().handleSize/2 * cy.zoom(); - var hx = p.x; - var hy = p.y - h/2 - hr/2; - - drawHandle(hx, hy, hr); - - node.trigger('cyedgehandles.showhandle'); - - // case: down and drag as normal - var downHandler = function(e){ - - $container[0].removeEventListener('mousedown', downHandler, true); - $container[0].removeEventListener('touchstart', downHandler, true); - - var x = (e.pageX !== undefined ? e.pageX : e.originalEvent.touches[0].pageX) - $container.offset().left; - var y = (e.pageY !== undefined ? e.pageY : e.originalEvent.touches[0].pageY) - $container.offset().top; - var d = hr/2; - var onNode = p.x - w/2 - d <= x && x <= p.x + w/2 + d - && p.y - h/2 - d <= y && y <= p.y + h/2 + d; - - if( onNode ){ - disableGestures(); - mdownOnHandle = true; // enable the regular logic for handling going over target nodes - - var moveHandler = function(me){ - var x = (me.pageX !== undefined ? me.pageX : me.originalEvent.touches[0].pageX) - $container.offset().left; - var y = (me.pageY !== undefined ? me.pageY : me.originalEvent.touches[0].pageY) - $container.offset().top; - - clearDraws(); - drawHandle(hx, hy, hr); - drawLine(hx, hy, x, y); - } - - $container[0].addEventListener('mousemove', moveHandler, true); - $container[0].addEventListener('touchmove', moveHandler, true); - - $(window).one("mouseup touchend blur", function(){ - $container[0].removeEventListener('mousemove', moveHandler, true); - $container[0].removeEventListener('touchmove', moveHandler, true); - - inForceStart = false; // now we're done so reset the flag - mdownOnHandle = false; // we're also no longer down on the node - - makeEdges(); - - options().stop( node ); - node.trigger('cyedgehandles.stop'); - - cy.off("tap", "node", tapHandler); - node.off("remove", removeBeforeHandler); - resetToDefaultState(); - }); - - e.stopPropagation(); - e.preventDefault(); - return false; - } - }; - - $container[0].addEventListener('mousedown', downHandler, true); - $container[0].addEventListener('touchstart', downHandler, true); - - var removeBeforeHandler; - node.one("remove", function(){ - $container[0].removeEventListener('mousedown', downHandler, true); - $container[0].removeEventListener('touchstart', downHandler, true); - cy.off("tap", "node", tapHandler); - }); - - // case: tap a target node - var tapHandler; - cy.one("tap", "node", tapHandler = function(){ - var target = this; - - var isLoop = source.id() === target.id(); - var loopAllowed = options().loopAllowed( target ); - - if( !isLoop || (isLoop && loopAllowed) ){ - makeEdges(false, source, target); - - //options().complete( node ); - //node.trigger('cyedgehandles.complete'); - } - - inForceStart = false; // now we're done so reset the flag - - options().stop( node ); - node.trigger('cyedgehandles.stop'); - - $container[0].removeEventListener('mousedown', downHandler, true); - $container[0].removeEventListener('touchstart', downHandler, true); - node.off("remove", removeBeforeHandler); - resetToDefaultState(); - }); - - - }).on("remove", "node", removeHandler = function(){ - var id = this.id(); - - if( id === lastActiveId ){ - setTimeout(function(){ - resetToDefaultState(); - }, 5); - } - }); - - - data.unbind = function(){ - cy - .off("mouseover", "node", startHandler) - .off("mouseover", "node", hoverHandler) - .off("mouseout", "node", leaveHandler) - .off("drag position", "node", dragNodeHandler) - .off("grab", "node", grabNodeHandler) - .off("free", "node", freeNodeHandler) - .off("cyedgehandles.forcestart", "node", forceStartHandler) - .off("remove", "node", removeHandler) - ; - - cy.unbind("zoom pan", transformHandler); - }; - }); - - $container.data("cyedgehandles", data); - }, - - start: function( id ){ - $container = $(this); - - $container.cytoscape(function(e){ - var cy = this; - - cy.$("#" + id).trigger('cyedgehandles.forcestart'); - }); - } - }; - - if( functions[fn] ){ - return functions[fn].apply(this, Array.prototype.slice.call( arguments, 1 )); - } else if( typeof fn == 'object' || !fn ) { - return functions.init.apply( this, arguments ); - } else { - $.error("No such function `"+ fn +"` for jquery.cytoscapeEdgeHandles"); - } - - return $(this); - }; - - $.fn.cyEdgehandles = $.fn.cytoscapeEdgehandles; - -})( jQuery ); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-edgehandles.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-edgehandles.min.js deleted file mode 100755 index 649d6f52d8..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-edgehandles.min.js +++ /dev/null @@ -1,37 +0,0 @@ - -/* jquery.cytoscape-edgehandles.min.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -(function(a){var b={preview:true,handleSize:10,handleColor:"#ff0000",handleLineWidth:1,hoverDelay:150,enabled:true,lineType:"draw",edgeType:function(c,d){return"node"},loopAllowed:function(c){return false},nodeParams:function(c,d){return{}},edgeParams:function(c,d){return{}},start:function(c){},complete:function(e,d,c){},stop:function(c){}};a.fn.cytoscapeEdgehandles=function(e){var c=e;var d={destroy:function(){var g=a(this);var f=g.data("cyedgehandles");if(f==null){return}f.unbind();g.data("cyedgehandles",{}); -return g},option:function(g,j){var k=a(this);var i=k.data("cyedgehandles");if(i==null){return}var f=i.options;if(j===undefined){if(typeof g==typeof{}){var h=g;f=a.extend(true,{},b,h);i.options=f}else{return f[g]}}else{f[g]=j}k.data("cyedgehandles",i);return k},disable:function(){return d.option.apply(this,["enabled",false])},enable:function(){return d.option.apply(this,["enabled",true])},init:function(){var w=a.extend(true,{},b,e);var z=a(this);var h;var p=a("");var I;var t,o;var g=false; -var L=false;var v=false;var F,D,K;var s;var u=true;z.append(p);function f(){p.attr("height",z.height()).attr("width",z.width()).css({position:"absolute","z-index":"999"})}f();a(window).bind("resize",function(){f()});var y=p[0].getContext("2d");var J=z.data("cyedgehandles");if(J==null){J={}}J.options=w;function l(){return z.data("cyedgehandles").options}function r(){return l().enabled}function m(){return !r()}function C(){if(u){return}var M=z.width();var N=z.height();y.clearRect(0,0,M,N);u=true}var H,q,i; -function G(){H=h.panningEnabled();q=h.zoomingEnabled();i=h.boxSelectionEnabled();h.zoomingEnabled(false).panningEnabled(false).boxSelectionEnabled(false)}function B(){h.zoomingEnabled(q).panningEnabled(H).boxSelectionEnabled(i)}function n(){C();h.nodes().removeClass("ui-cytoscape-edgehandles-hover").removeClass("ui-cytoscape-edgehandles-source").removeClass("ui-cytoscape-edgehandles-target");o=null;B()}function j(M,N){k(true);N.trigger("cyedgehandles.addpreview")}function A(M,N){M.edgesWith(N).filter(".ui-cytoscape-edgehandles-preview").remove(); -N.neighborhood("node.ui-cytoscape-edgehandles-preview").closedNeighborhood(".ui-cytoscape-edgehandles-preview").remove();N.trigger("cyedgehandles.removepreview")}function E(O,N,M){y.fillStyle=l().handleColor;y.strokeStyle=l().handleColor;y.beginPath();y.arc(O,N,M,0,2*Math.PI);y.closePath();y.fill();u=false}function x(R,P,M,Q){y.fillStyle=l().handleColor;y.strokeStyle=l().handleColor;y.lineWidth=l().handleLineWidth;switch(l().lineType){case"straight":y.beginPath();y.moveTo(R,P);y.lineTo(M,Q);y.closePath(); -y.stroke();break;case"draw":default:if(o==null){o=[[M,Q]]}else{o.push([M,Q])}y.beginPath();y.moveTo(R,P);for(var N=0;NK||Math.abs(ai-D)>K){return}if(v){return}g=true;ah.preventDefault();ah.stopPropagation(); -aa.addClass("ui-cytoscape-edgehandles-source");aa.trigger("cyedgehandles.start");function ag(aj){if(!g||v){return}var ak=a(this);g=false;a(window).unbind("mousemove",ab);k();n();l().stop(aa);aa.trigger("cyedgehandles.stop")}a(window).one("mouseup blur",ag).bind("mousemove",ab);G();l().start(aa);return false}function ab(ag){var af=ag.pageX-z.offset().left;var ah=ag.pageY-z.offset().top;C();E(F,D,K);x(F,D,af,ah);return false}z[0].addEventListener("mousedown",Y,true);M=Y}).on("mouseover touchover","node",P=function(){var Y=this; -var Z=this;if(m()||this.hasClass("ui-cytoscape-edgehandles-preview")){return}if(g){clearTimeout(s);s=setTimeout(function(){var ab=h.nodes(".ui-cytoscape-edgehandles-source");var aa=Y.hasClass("ui-cytoscape-edgehandles-source");var ac=l().loopAllowed(Y);if(!aa||(aa&&ac)){Y.addClass("ui-cytoscape-edgehandles-hover");Y.toggleClass("ui-cytoscape-edgehandles-target");if(l().preview){if(Y.hasClass("ui-cytoscape-edgehandles-target")){j(ab,Z)}else{A(ab,Z)}}}},l().hoverDelay);return false}}).on("mouseout","node",R=function(){if(this.hasClass("ui-cytoscape-edgehandles-hover")){this.removeClass("ui-cytoscape-edgehandles-hover") -}if(g){clearTimeout(s)}}).on("drag position","node",X=function(){setTimeout(C,50)}).on("grab","node",grabHandler=function(){L=true;setTimeout(function(){C()},5)}).on("free","node",T=function(){L=false}).on("cyedgehandles.forcestart","node",W=function(){v=true;C();var aa=this;var Y=aa;V=aa.id();aa.trigger("cyedgehandles.start");aa.addClass("ui-cytoscape-edgehandles-source");var Z=aa.renderedPosition();var ab=aa.renderedOuterHeight();var ag=aa.renderedOuterWidth();var ah=l().handleSize/2*h.zoom();var ad=Z.x; -var ac=Z.y-ab/2-ah/2;E(ad,ac,ah);aa.trigger("cyedgehandles.showhandle");var af=function(am){z[0].removeEventListener("mousedown",af,true);z[0].removeEventListener("touchstart",af,true);var aj=(am.pageX!==undefined?am.pageX:am.originalEvent.touches[0].pageX)-z.offset().left;var ao=(am.pageY!==undefined?am.pageY:am.originalEvent.touches[0].pageY)-z.offset().top;var an=ah/2;var ak=Z.x-ag/2-an<=aj&&aj<=Z.x+ag/2+an&&Z.y-ab/2-an<=ao&&ao<=Z.y+ab/2+an;if(ak){G();g=true;var al=function(aq){var ap=(aq.pageX!==undefined?aq.pageX:aq.originalEvent.touches[0].pageX)-z.offset().left; -var ar=(aq.pageY!==undefined?aq.pageY:aq.originalEvent.touches[0].pageY)-z.offset().top;C();E(ad,ac,ah);x(ad,ac,ap,ar)};z[0].addEventListener("mousemove",al,true);z[0].addEventListener("touchmove",al,true);a(window).one("mouseup touchend blur",function(){z[0].removeEventListener("mousemove",al,true);z[0].removeEventListener("touchmove",al,true);v=false;g=false;k();l().stop(aa);aa.trigger("cyedgehandles.stop");h.off("tap","node",ai);aa.off("remove",ae);n()});am.stopPropagation();am.preventDefault(); -return false}};z[0].addEventListener("mousedown",af,true);z[0].addEventListener("touchstart",af,true);var ae;aa.one("remove",function(){z[0].removeEventListener("mousedown",af,true);z[0].removeEventListener("touchstart",af,true);h.off("tap","node",ai)});var ai;h.one("tap","node",ai=function(){var ak=this;var aj=Y.id()===ak.id();var al=l().loopAllowed(ak);if(!aj||(aj&&al)){k(false,Y,ak)}v=false;l().stop(aa);aa.trigger("cyedgehandles.stop");z[0].removeEventListener("mousedown",af,true);z[0].removeEventListener("touchstart",af,true); -aa.off("remove",ae);n()})}).on("remove","node",O=function(){var Y=this.id();if(Y===V){setTimeout(function(){n()},5)}});J.unbind=function(){h.off("mouseover","node",Q).off("mouseover","node",P).off("mouseout","node",R).off("drag position","node",X).off("grab","node",S).off("free","node",T).off("cyedgehandles.forcestart","node",W).off("remove","node",O);h.unbind("zoom pan",N)}});z.data("cyedgehandles",J)},start:function(f){$container=a(this);$container.cytoscape(function(g){var h=this;h.$("#"+f).trigger("cyedgehandles.forcestart") -})}};if(d[c]){return d[c].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof c=="object"||!c){return d.init.apply(this,arguments)}else{a.error("No such function `"+c+"` for jquery.cytoscapeEdgeHandles")}}return a(this)};a.fn.cyEdgehandles=a.fn.cytoscapeEdgehandles})(jQuery); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.css b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.css deleted file mode 100755 index 24dbfe1776..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.css +++ /dev/null @@ -1,210 +0,0 @@ - -/* jquery.cytoscape-panzoom.css */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -.ui-cytoscape-panzoom { - position: absolute; - font-size: 12px; - color: #fff; - font-family: arial, helvetica, sans-serif; - line-height: 1; - color: #666; - font-size: 11px; - z-index: 99999; -} - -.ui-cytoscape-panzoom-zoom-button { - cursor: pointer; - padding: 3px; - text-align: center; - position: absolute; - border-radius: 3px; - width: 10px; - height: 10px; - left: 16px; - background: #fff; - border: 1px solid #999; - margin-left: -1px; - margin-top: -1px; - z-index: 1; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); -} - -.ui-cytoscape-panzoom-zoom-button:active, -.ui-cytoscape-panzoom-slider-handle:active, -.ui-cytoscape-panzoom-slider-handle.active { - background: #ddd; -} - -.ui-cytoscape-panzoom-pan-button { - position: absolute; - z-index: 1; - height: 16px; - width: 16px; -} - -.ui-cytoscape-panzoom-reset { - top: 55px; -} - -.ui-cytoscape-panzoom-zoom-in { - top: 80px; -} - -.ui-cytoscape-panzoom-zoom-out { - top: 197px; -} - -.ui-cytoscape-panzoom-pan-up { - top: 0; - left: 50%; - margin-left: -5px; - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-bottom: 5px solid #666; -} - -.ui-cytoscape-panzoom-pan-down { - bottom: 0; - left: 50%; - margin-left: -5px; - width: 0; - height: 0; - border-left: 5px solid transparent; - border-right: 5px solid transparent; - border-top: 5px solid #666; -} - -.ui-cytoscape-panzoom-pan-left { - top: 50%; - left: 0; - margin-top: -5px; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #666; -} - -.ui-cytoscape-panzoom-pan-right { - top: 50%; - right: 0; - margin-top: -5px; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #666; -} - -.ui-cytoscape-panzoom-pan-indicator { - position: absolute; - left: 0; - top: 0; - width: 8px; - height: 8px; - border-radius: 8px; - background: #000; - border-radius: 8px; - margin-left: -5px; - margin-top: -5px; - display: none; - z-index: 999; - opacity: 0.6; -} - -.ui-cytoscape-panzoom-slider { - position: absolute; - top: 97px; - left: 17px; - height: 100px; - width: 15px; -} - -.ui-cytoscape-panzoom-slider-background { - position: absolute; - top: 0; - width: 2px; - height: 100px; - left: 5px; - background: #fff; - box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.25); - border-left: 1px solid #999; - border-right: 1px solid #999; -} - -.ui-cytoscape-panzoom-slider-handle { - position: absolute; - width: 16px; - height: 8px; - background: #fff; - border: 1px solid #999; - border-radius: 2px; - margin-left: -2px; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); - z-index: 999; - line-height: 8px; -} - -.ui-cytoscape-panzoom-slider-handle .icon { - margin: 0 4px; - line-height: 10px; -} - -.ui-cytoscape-panzoom-no-zoom-tick { - position: absolute; - background: #666; - border: 1px solid #fff; - border-radius: 2px; - margin-left: -1px; - width: 8px; - height: 2px; - left: 3px; - z-index: 1; - margin-top: 3px; -} - -.ui-cytoscape-panzoom-panner { - position: absolute; - left: 5px; - top: 5px; - height: 40px; - width: 40px; - background: #fff; - border: 1px solid #999; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5); - border-radius: 40px; - margin-left: -1px; -} - -.ui-cytoscape-panzoom-panner-handle { - position: absolute; - left: 0; - top: 0; - outline: none; - height: 40px; - width: 40px; - position: absolute; - z-index: 999; -} - - - diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.js deleted file mode 100755 index ba545766f7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.js +++ /dev/null @@ -1,481 +0,0 @@ - -/* jquery.cytoscape-panzoom.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -;(function($){ - - var defaults = { - zoomFactor: 0.05, // zoom factor per zoom tick - zoomDelay: 45, // how many ms between zoom ticks - minZoom: 0.1, // min zoom level - maxZoom: 10, // max zoom level - fitPadding: 50, // padding when fitting - panSpeed: 10, // how many ms in between pan ticks - panDistance: 10, // max pan distance per tick - panDragAreaSize: 75, // the length of the pan drag box in which the vector for panning is calculated (bigger = finer control of pan speed and direction) - panMinPercentSpeed: 0.25, // the slowest speed we can pan by (as a percent of panSpeed) - panInactiveArea: 8, // radius of inactive area in pan drag box - panIndicatorMinOpacity: 0.5, // min opacity of pan indicator (the draggable nib); scales from this to 1.0 - autodisableForMobile: true, // disable the panzoom completely for mobile (since we don't really need it with gestures like pinch to zoom) - sliderHandleIcon: 'icon-minus', - zoomInIcon: 'icon-plus', - zoomOutIcon: 'icon-minus', - resetIcon: 'icon-resize-full' - }; - - $.fn.cytoscapePanzoom = function(params){ - var options = $.extend(true, {}, defaults, params); - var fn = params; - - var functions = { - destroy: function(){ - var $this = $(this); - - $this.find(".ui-cytoscape-panzoom").remove(); - }, - - init: function(){ - var browserIsMobile = 'ontouchstart' in window; - - if( browserIsMobile && options.autodisableForMobile ){ - return $(this); - } - - return $(this).each(function(){ - var $container = $(this); - - var $panzoom = $('
                      '); - $container.append( $panzoom ); - - if( options.staticPosition ){ - $panzoom.addClass("ui-cytoscape-panzoom-static"); - } - - // add base html elements - ///////////////////////// - - var $zoomIn = $('
                      '); - $panzoom.append( $zoomIn ); - - var $zoomOut = $('
                      '); - $panzoom.append( $zoomOut ); - - var $reset = $('
                      '); - $panzoom.append( $reset ); - - var $slider = $('
                      '); - $panzoom.append( $slider ); - - $slider.append('
                      '); - - var $sliderHandle = $('
                      '); - $slider.append( $sliderHandle ); - - var $noZoomTick = $('
                      '); - $slider.append( $noZoomTick ); - - var $panner = $('
                      '); - $panzoom.append( $panner ); - - var $pHandle = $('
                      '); - $panner.append( $pHandle ); - - var $pUp = $('
                      '); - var $pDown = $('
                      '); - var $pLeft = $('
                      '); - var $pRight = $('
                      '); - $panner.append( $pUp ).append( $pDown ).append( $pLeft ).append( $pRight ); - - var $pIndicator = $('
                      '); - $panner.append( $pIndicator ); - - // functions for calculating panning - //////////////////////////////////// - - function handle2pan(e){ - var v = { - x: e.originalEvent.pageX - $panner.offset().left - $panner.width()/2, - y: e.originalEvent.pageY - $panner.offset().top - $panner.height()/2 - } - - var r = options.panDragAreaSize; - var d = Math.sqrt( v.x*v.x + v.y*v.y ); - var percent = Math.min( d/r, 1 ); - - if( d < options.panInactiveArea ){ - return { - x: NaN, - y: NaN - }; - } - - v = { - x: v.x/d, - y: v.y/d - }; - - percent = Math.max( options.panMinPercentSpeed, percent ); - - var vnorm = { - x: -1 * v.x * (percent * options.panDistance), - y: -1 * v.y * (percent * options.panDistance) - }; - - return vnorm; - } - - function donePanning(){ - clearInterval(panInterval); - $(window).unbind("mousemove", handler); - - $pIndicator.hide(); - } - - function positionIndicator(pan){ - var v = pan; - var d = Math.sqrt( v.x*v.x + v.y*v.y ); - var vnorm = { - x: -1 * v.x/d, - y: -1 * v.y/d - }; - - var w = $panner.width(); - var h = $panner.height(); - var percent = d/options.panDistance; - var opacity = Math.max( options.panIndicatorMinOpacity, percent ); - var color = 255 - Math.round( opacity * 255 ); - - $pIndicator.show().css({ - left: w/2 * vnorm.x + w/2, - top: h/2 * vnorm.y + h/2, - background: "rgb(" + color + ", " + color + ", " + color + ")" - }); - } - - function calculateZoomCenterPoint(){ - var cy = $container.cytoscape("get"); - var pan = cy.pan(); - var zoom = cy.zoom(); - - zx = $container.width()/2; - zy = $container.height()/2; - } - - var zooming = false; - function startZooming(){ - zooming = true; - - calculateZoomCenterPoint(); - } - - - function endZooming(){ - zooming = false; - } - - var zx, zy; - function zoomTo(level){ - var cy = $container.cytoscape("get"); - - if( !zooming ){ // for non-continuous zooming (e.g. click slider at pt) - calculateZoomCenterPoint(); - } - - cy.zoom({ - level: level, - position: { x: zx, y: zy } - }); - } - - var panInterval; - - var handler = function(e){ - e.stopPropagation(); // don't trigger dragging of panzoom - e.preventDefault(); // don't cause text selection - clearInterval(panInterval); - - var pan = handle2pan(e); - - if( isNaN(pan.x) || isNaN(pan.y) ){ - $pIndicator.hide(); - return; - } - - positionIndicator(pan); - panInterval = setInterval(function(){ - $container.cytoscape("get").panBy(pan); - }, options.panSpeed); - }; - - $pHandle.bind("mousedown", function(e){ - // handle click of icon - handler(e); - - // update on mousemove - $(window).bind("mousemove", handler); - }); - - $pHandle.bind("mouseup", function(){ - donePanning(); - }); - - $(window).bind("mouseup blur", function(){ - donePanning(); - }); - - - - // set up slider behaviour - ////////////////////////// - - $slider.bind('mousedown', function(){ - return false; // so we don't pan close to the slider handle - }); - - var sliderVal; - var sliding = false; - var sliderPadding = 2; - - function setSliderFromMouse(evt, handleOffset){ - if( handleOffset === undefined ){ - handleOffset = 0; - } - - var padding = sliderPadding; - var min = 0 + padding; - var max = $slider.height() - $sliderHandle.height() - 2*padding; - var top = evt.pageY - $slider.offset().top - handleOffset; - - // constrain to slider bounds - if( top < min ){ top = min } - if( top > max ){ top = max } - - var percent = 1 - (top - min) / ( max - min ); - - // move the handle - $sliderHandle.css('top', top); - - var zmin = options.minZoom; - var zmax = options.maxZoom; - - // assume (zoom = zmax ^ p) where p ranges on (x, 1) with x negative - var x = Math.log(zmin) / Math.log(zmax); - var p = (1 - x)*percent + x; - - // change the zoom level - var z = Math.pow( zmax, p ); - - // bound the zoom value in case of floating pt rounding error - if( z < zmin ){ - z = zmin; - } else if( z > zmax ){ - z = zmax; - } - - zoomTo( z ); - } - - var sliderMdownHandler, sliderMmoveHandler; - $sliderHandle.bind('mousedown', sliderMdownHandler = function( mdEvt ){ - var handleOffset = mdEvt.target === $sliderHandle[0] ? mdEvt.offsetY : 0; - sliding = true; - - startZooming(); - $sliderHandle.addClass("active"); - - var lastMove = 0; - $(window).bind('mousemove', sliderMmoveHandler = function( mmEvt ){ - var now = +new Date; - - // throttle the zooms every 10 ms so we don't call zoom too often and cause lag - if( now > lastMove + 10 ){ - lastMove = now; - } else { - return false; - } - - setSliderFromMouse(mmEvt, handleOffset); - - return false; - }); - - // unbind when - $(window).bind('mouseup', function(){ - $(window).unbind('mousemove', sliderMmoveHandler); - sliding = false; - - $sliderHandle.removeClass("active"); - endZooming(); - }); - - return false; - }); - - $slider.bind('mousedown', function(e){ - if( e.target !== $sliderHandle[0] ){ - sliderMdownHandler(e); - setSliderFromMouse(e); - } - }); - - function positionSliderFromZoom(){ - var cy = $container.cytoscape("get"); - var z = cy.zoom(); - var zmin = options.minZoom; - var zmax = options.maxZoom; - - // assume (zoom = zmax ^ p) where p ranges on (x, 1) with x negative - var x = Math.log(zmin) / Math.log(zmax); - var p = Math.log(z) / Math.log(zmax); - var percent = 1 - (p - x) / (1 - x); // the 1- bit at the front b/c up is in the -ve y direction - - var min = sliderPadding; - var max = $slider.height() - $sliderHandle.height() - 2*sliderPadding; - var top = percent * ( max - min ); - - // constrain to slider bounds - if( top < min ){ top = min } - if( top > max ){ top = max } - - // move the handle - $sliderHandle.css('top', top); - } - - positionSliderFromZoom(); - - var cy = $container.cytoscape("get"); - cy.on('zoom', function(){ - if( !sliding ){ - positionSliderFromZoom(); - } - }); - - // set the position of the zoom=1 tick - (function(){ - var z = 1; - var zmin = options.minZoom; - var zmax = options.maxZoom; - - // assume (zoom = zmax ^ p) where p ranges on (x, 1) with x negative - var x = Math.log(zmin) / Math.log(zmax); - var p = Math.log(z) / Math.log(zmax); - var percent = 1 - (p - x) / (1 - x); // the 1- bit at the front b/c up is in the -ve y direction - - if( percent > 1 || percent < 0 ){ - $noZoomTick.hide(); - return; - } - - var min = sliderPadding; - var max = $slider.height() - $sliderHandle.height() - 2*sliderPadding; - var top = percent * ( max - min ); - - // constrain to slider bounds - if( top < min ){ top = min } - if( top > max ){ top = max } - - $noZoomTick.css('top', top); - })(); - - // set up zoom in/out buttons - ///////////////////////////// - - function bindButton($button, factor){ - var zoomInterval; - - $button.bind("mousedown", function(e){ - e.preventDefault(); - e.stopPropagation(); - - if( e.button != 0 ){ - return; - } - - var cy = $container.cytoscape("get"); - - startZooming(); - zoomInterval = setInterval(function(){ - var zoom = cy.zoom(); - var lvl = cy.zoom() * factor; - - if( lvl < options.minZoom ){ - lvl = options.minZoom; - } - - if( lvl > options.maxZoom ){ - lvl = options.maxZoom; - } - - if( (lvl == options.maxZoom && zoom == options.maxZoom) || - (lvl == options.minZoom && zoom == options.minZoom) - ){ - return; - } - - zoomTo(lvl); - }, options.zoomDelay); - - return false; - }); - - $(window).bind("mouseup blur", function(){ - clearInterval(zoomInterval); - endZooming(); - }); - } - - bindButton( $zoomIn, (1 + options.zoomFactor) ); - bindButton( $zoomOut, (1 - options.zoomFactor) ); - - $reset.bind("mousedown", function(e){ - if( e.button != 0 ){ - return; - } - - var cy = $container.cytoscape("get"); - - if( cy.elements().size() === 0 ){ - cy.reset(); - } else { - cy.fit( options.fitPadding ); - } - - return false; - }); - - - - }); - } - }; - - if( functions[fn] ){ - return functions[fn].apply(this, Array.prototype.slice.call( arguments, 1 )); - } else if( typeof fn == 'object' || !fn ) { - return functions.init.apply( this, arguments ); - } else { - $.error("No such function `"+ fn +"` for jquery.cytoscapePanzoom"); - } - - return $(this); - }; - - $.fn.cyPanzoom = $.fn.cytoscapePanzoom; - -})(jQuery); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.min.js deleted file mode 100755 index 6643aa7994..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.0.2/jquery.cytoscape-panzoom.min.js +++ /dev/null @@ -1,32 +0,0 @@ - -/* jquery.cytoscape-panzoom.min.js */ - -/** - * This file is part of cytoscape.js 2.0.2. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -(function(a){var b={zoomFactor:0.05,zoomDelay:45,minZoom:0.1,maxZoom:10,fitPadding:50,panSpeed:10,panDistance:10,panDragAreaSize:75,panMinPercentSpeed:0.25,panInactiveArea:8,panIndicatorMinOpacity:0.5,autodisableForMobile:true,sliderHandleIcon:"icon-minus",zoomInIcon:"icon-plus",zoomOutIcon:"icon-minus",resetIcon:"icon-resize-full"};a.fn.cytoscapePanzoom=function(f){var c=a.extend(true,{},b,f);var d=f;var e={destroy:function(){var g=a(this);g.find(".ui-cytoscape-panzoom").remove()},init:function(){var g="ontouchstart" in window; -if(g&&c.autodisableForMobile){return a(this)}return a(this).each(function(){var k=a(this);var J=a('
                      ');k.append(J);if(c.staticPosition){J.addClass("ui-cytoscape-panzoom-static")}var A=a('
                      ');J.append(A);var o=a('
                      '); -J.append(o);var q=a('
                      ');J.append(q);var p=a('
                      ');J.append(p);p.append('
                      ');var G=a('
                      ');p.append(G);var v=a('
                      ');p.append(v); -var x=a('
                      ');J.append(x);var P=a('
                      ');x.append(P);var H=a('
                      ');var Q=a('
                      ');var L=a('
                      ');var t=a('
                      '); -x.append(H).append(Q).append(L).append(t);var h=a('
                      ');x.append(h);function y(V){var R={x:V.originalEvent.pageX-x.offset().left-x.width()/2,y:V.originalEvent.pageY-x.offset().top-x.height()/2};var T=c.panDragAreaSize;var W=Math.sqrt(R.x*R.x+R.y*R.y);var S=Math.min(W/T,1);if(WY){X=Y}var V=1-(X-T)/(Y-T);G.css("top",X);var U=c.minZoom;var ac=c.maxZoom;var Z=Math.log(U)/Math.log(ac);var R=(1-Z)*V+Z;var W=Math.pow(ac,R);if(Wac){W=ac}}N(W)}var m,O;G.bind("mousedown",m=function(T){var S=T.target===G[0]?T.offsetY:0;n=true;j();G.addClass("active");var R=0;a(window).bind("mousemove",O=function(V){var U=+new Date;if(U>R+10){R=U}else{return false}I(V,S);return false -});a(window).bind("mouseup",function(){a(window).unbind("mousemove",O);n=false;G.removeClass("active");r()});return false});p.bind("mousedown",function(R){if(R.target!==G[0]){m(R);I(R)}});function C(){var S=k.cytoscape("get");var W=S.zoom();var U=c.minZoom;var aa=c.maxZoom;var Z=Math.log(U)/Math.log(aa);var R=Math.log(W)/Math.log(aa);var V=1-(R-Z)/(1-Z);var T=l;var Y=p.height()-G.height()-2*l;var X=V*(Y-T);if(XY){X=Y}G.css("top",X)}C();var s=k.cytoscape("get");s.on("zoom",function(){if(!n){C() -}});(function(){var V=1;var T=c.minZoom;var Z=c.maxZoom;var Y=Math.log(T)/Math.log(Z);var R=Math.log(V)/Math.log(Z);var U=1-(R-Y)/(1-Y);if(U>1||U<0){v.hide();return}var S=l;var X=p.height()-G.height()-2*l;var W=U*(X-S);if(WX){W=X}v.css("top",W)})();function E(S,R){var T;S.bind("mousedown",function(U){U.preventDefault();U.stopPropagation();if(U.button!=0){return}var V=k.cytoscape("get");j();T=setInterval(function(){var X=V.zoom();var W=V.zoom()*R;if(Wc.maxZoom){W=c.maxZoom -}if((W==c.maxZoom&&X==c.maxZoom)||(W==c.minZoom&&X==c.minZoom)){return}N(W)},c.zoomDelay);return false});a(window).bind("mouseup blur",function(){clearInterval(T);r()})}E(A,(1+c.zoomFactor));E(o,(1-c.zoomFactor));q.bind("mousedown",function(R){if(R.button!=0){return}var S=k.cytoscape("get");if(S.elements().size()===0){S.reset()}else{S.fit(c.fitPadding)}return false})})}};if(e[d]){return e[d].apply(this,Array.prototype.slice.call(arguments,1))}else{if(typeof d=="object"||!d){return e.init.apply(this,arguments) -}else{a.error("No such function `"+d+"` for jquery.cytoscapePanzoom")}}return a(this)};a.fn.cyPanzoom=a.fn.cytoscapePanzoom})(jQuery); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/LGPL-LICENSE.txt b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/LGPL-LICENSE.txt deleted file mode 100755 index 02bbb60bc4..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/LGPL-LICENSE.txt +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/arbor.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/arbor.js deleted file mode 100755 index b6ae116d31..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/arbor.js +++ /dev/null @@ -1,67 +0,0 @@ -// -// arbor.js - version 0.91 -// a graph vizualization toolkit -// -// Copyright (c) 2011 Samizdat Drafting Co. -// Physics code derived from springy.js, copyright (c) 2010 Dennis Hotson -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -(function($){ - - /* etc.js */ var trace=function(msg){if(typeof(window)=="undefined"||!window.console){return}var len=arguments.length;var args=[];for(var i=0;i0){return a[0]}else{return null}}; - /* kernel.js */ var Kernel=function(b){var k=window.location.protocol=="file:"&&navigator.userAgent.toLowerCase().indexOf("chrome")>-1;var a=(window.Worker!==undefined&&!k);var i=null;var c=null;var f=[];f.last=new Date();var l=null;var e=null;var d=null;var h=null;var g=false;var j={system:b,tween:null,nodes:{},init:function(){if(typeof(Tween)!="undefined"){c=Tween()}else{if(typeof(arbor.Tween)!="undefined"){c=arbor.Tween()}else{c={busy:function(){return false},tick:function(){return true},to:function(){trace("Please include arbor-tween.js to enable tweens");c.to=function(){};return}}}}j.tween=c;var m=b.parameters();if(a){trace("using web workers");l=setInterval(j.screenUpdate,m.timeout);i=new Worker(arbor_path()+"arbor.js");i.onmessage=j.workerMsg;i.onerror=function(n){trace("physics:",n)};i.postMessage({type:"physics",physics:objmerge(m,{timeout:Math.ceil(m.timeout)})})}else{trace("couldn't use web workers, be careful...");i=Physics(m.dt,m.stiffness,m.repulsion,m.friction,j.system._updateGeometry);j.start()}return j},graphChanged:function(m){if(a){i.postMessage({type:"changes",changes:m})}else{i._update(m)}j.start()},particleModified:function(n,m){if(a){i.postMessage({type:"modify",id:n,mods:m})}else{i.modifyNode(n,m)}j.start()},physicsModified:function(m){if(!isNaN(m.timeout)){if(a){clearInterval(l);l=setInterval(j.screenUpdate,m.timeout)}else{clearInterval(d);d=null}}if(a){i.postMessage({type:"sys",param:m})}else{i.modifyPhysics(m)}j.start()},workerMsg:function(n){var m=n.data.type;if(m=="geometry"){j.workerUpdate(n.data)}else{trace("physics:",n.data)}},_lastPositions:null,workerUpdate:function(m){j._lastPositions=m;j._lastBounds=m.bounds},_lastFrametime:new Date().valueOf(),_lastBounds:null,_currentRenderer:null,screenUpdate:function(){var n=new Date().valueOf();var m=false;if(j._lastPositions!==null){j.system._updateGeometry(j._lastPositions);j._lastPositions=null;m=true}if(c&&c.busy()){m=true}if(j.system._updateBounds(j._lastBounds)){m=true}if(m){var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}if(c){c.tick()}o.redraw();var p=f.last;f.last=new Date();f.push(f.last-p);if(f.length>50){f.shift()}}}},physicsUpdate:function(){if(c){c.tick()}i.tick();var n=j.system._updateBounds();if(c&&c.busy()){n=true}var o=j.system.renderer;var m=new Date();var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}o.redraw({timestamp:m})}var q=f.last;f.last=m;f.push(f.last-q);if(f.length>50){f.shift()}var p=i.systemEnergy();if((p.mean+p.max)/2<0.05){if(h===null){h=new Date().valueOf()}if(new Date().valueOf()-h>1000){clearInterval(d);d=null}else{}}else{h=null}},fps:function(n){if(n!==undefined){var q=1000/Math.max(1,targetFps);j.physicsModified({timeout:q})}var r=0;for(var p=0,o=f.length;p0);if(y){$.extend(c.adjacency[D][E].data,z.data);return}else{c.edges[z._id]=z;c.adjacency[D][E].push(z);var x=(z.length!==undefined)?z.length:1;k.push({t:"addSpring",id:z._id,fm:D,to:E,l:x});h._notify()}return z},pruneEdge:function(C){k.push({t:"dropSpring",id:C._id});delete c.edges[C._id];for(var z in c.adjacency){for(var D in c.adjacency[z]){var A=c.adjacency[z][D];for(var B=A.length-1;B>=0;B--){if(c.adjacency[z][D][B]._id===C._id){c.adjacency[z][D].splice(B,1)}}}}h._notify()},getEdges:function(y,x){y=h.getNode(y);x=h.getNode(x);if(!y||!x){return[]}if(typeof(c.adjacency[y._id])!=="undefined"&&typeof(c.adjacency[y._id][x._id])!=="undefined"){return c.adjacency[y._id][x._id]}return[]},getEdgesFrom:function(x){x=h.getNode(x);if(!x){return[]}if(typeof(c.adjacency[x._id])!=="undefined"){var y=[];$.each(c.adjacency[x._id],function(A,z){y=y.concat(z)});return y}return[]},getEdgesTo:function(x){x=h.getNode(x);if(!x){return[]}var y=[];$.each(c.edges,function(A,z){if(z.target==x){y.push(z)}});return y},eachEdge:function(x){$.each(c.edges,function(B,z){var A=c.nodes[z.source._id]._p;var y=c.nodes[z.target._id]._p;if(A.x==null||y.x==null){return}A=(w!==null)?h.toScreen(A):A;y=(w!==null)?h.toScreen(y):y;if(A&&y){x.call(h,z,A,y)}})},prune:function(y){var x={dropped:{nodes:[],edges:[]}};if(y===undefined){$.each(c.nodes,function(A,z){x.dropped.nodes.push(z);h.pruneNode(z)})}else{h.eachNode(function(A){var z=y.call(h,A,{from:h.getEdgesFrom(A),to:h.getEdgesTo(A)});if(z){x.dropped.nodes.push(A);h.pruneNode(A)}})}return x},graft:function(y){var x={added:{nodes:[],edges:[]}};if(y.nodes){$.each(y.nodes,function(A,z){var B=h.getNode(A);if(B){B.data=z}else{x.added.nodes.push(h.addNode(A,z))}c.kernel.start()})}if(y.edges){$.each(y.edges,function(B,z){var A=h.getNode(B);if(!A){x.added.nodes.push(h.addNode(B,{}))}$.each(z,function(F,C){var E=h.getNode(F);if(!E){x.added.nodes.push(h.addNode(F,{}))}var D=h.getEdges(B,F);if(D.length>0){D[0].data=C}else{x.added.edges.push(h.addEdge(B,F,C))}})})}return x},merge:function(y){var x={added:{nodes:[],edges:[]},dropped:{nodes:[],edges:[]}};$.each(c.edges,function(C,B){if((y.edges[B.source.name]===undefined||y.edges[B.source.name][B.target.name]===undefined)){h.pruneEdge(B);x.dropped.edges.push(B)}});var A=h.prune(function(C,B){if(y.nodes[C.name]===undefined){x.dropped.nodes.push(C);return true}});var z=h.graft(y);x.added.nodes=x.added.nodes.concat(z.added.nodes);x.added.edges=x.added.edges.concat(z.added.edges);x.dropped.nodes=x.dropped.nodes.concat(A.dropped.nodes);x.dropped.edges=x.dropped.edges.concat(A.dropped.edges);return x},tweenNode:function(A,x,z){var y=h.getNode(A);if(y){c.tween.to(y,x,z)}},tweenEdge:function(y,x,B,A){if(A===undefined){h._tweenEdge(y,x,B)}else{var z=h.getEdges(y,x);$.each(z,function(C,D){h._tweenEdge(D,B,A)})}},_tweenEdge:function(y,x,z){if(y&&y._id!==undefined){c.tween.to(y,x,z)}},_updateGeometry:function(A){if(A!=undefined){var x=(A.epoch1||C.y*w.height>1){p=_newBounds;return true}else{return false}},energy:function(){return a},bounds:function(){var y=null;var x=null;$.each(c.nodes,function(B,A){if(!y){y=new Point(A._p);x=new Point(A._p);return}var z=A._p;if(z.x===null||z.y===null){return}if(z.x>y.x){y.x=z.x}if(z.y>y.y){y.y=z.y}if(z.x0){c.kernel.graphChanged(k);k=[];i=null}}};c.kernel=Kernel(h);c.tween=c.kernel.tween||null;var e=(window.__defineGetter__==null||window.__defineSetter__==null)?function(y,x,z){if(!y.hasOwnProperty(x)){Object.defineProperty(y,x,z)}}:function(y,x,z){if(z.get){y.__defineGetter__(x,z.get)}if(z.set){y.__defineSetter__(x,z.set)}};var n=function(x){this._n=x;this._state=c};n.prototype=new Point();e(n.prototype,"x",{get:function(){return this._n._p.x},set:function(x){this._state.kernel.particleModified(this._n._id,{x:x})}});e(n.prototype,"y",{get:function(){return this._n._p.y},set:function(x){this._state.kernel.particleModified(this._n._id,{y:x})}});e(Node.prototype,"p",{get:function(){return new n(this)},set:function(x){this._p.x=x.x;this._p.y=x.y;this._state.kernel.particleModified(this._id,{x:x.x,y:x.y})}});e(Node.prototype,"mass",{get:function(){return this._mass},set:function(x){this._mass=x;this._state.kernel.particleModified(this._id,{m:x})}});e(Node.prototype,"tempMass",{set:function(x){this._state.kernel.particleModified(this._id,{_m:x})}});e(Node.prototype,"fixed",{get:function(){return this._fixed},set:function(x){this._fixed=x;this._state.kernel.particleModified(this._id,{f:x?1:0})}});return h}; - /* barnes-hut.js */ var BarnesHutTree=function(){var b=[];var a=0;var e=null;var d=0.5;var c={init:function(g,h,f){d=f;a=0;e=c._newBranch();e.origin=g;e.size=h.subtract(g)},insert:function(j){var f=e;var g=[j];while(g.length){var h=g.shift();var m=h._m||h.m;var p=c._whichQuad(h,f);if(f[p]===undefined){f[p]=h;f.mass+=m;if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}}else{if("origin" in f[p]){f.mass+=(m);if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}f=f[p];g.unshift(h)}else{var l=f.size.divide(2);var n=new Point(f.origin);if(p[0]=="s"){n.y+=l.y}if(p[1]=="e"){n.x+=l.x}var o=f[p];f[p]=c._newBranch();f[p].origin=n;f[p].size=l;f.mass=m;f.p=h.p.multiply(m);f=f[p];if(o.p.x===h.p.x&&o.p.y===h.p.y){var k=l.x*0.08;var i=l.y*0.08;o.p.x=Math.min(n.x+l.x,Math.max(n.x,o.p.x-k/2+Math.random()*k));o.p.y=Math.min(n.y+l.y,Math.max(n.y,o.p.y-i/2+Math.random()*i))}g.push(o);g.unshift(h)}}}},applyForces:function(m,g){var f=[e];while(f.length){node=f.shift();if(node===undefined){continue}if(m===node){continue}if("f" in node){var k=m.p.subtract(node.p);var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node._m||node.m)).divide(l*l))}else{var j=m.p.subtract(node.p.divide(node.mass)).magnitude();var h=Math.sqrt(node.size.x*node.size.y);if(h/j>d){f.push(node.ne);f.push(node.nw);f.push(node.se);f.push(node.sw)}else{var k=m.p.subtract(node.p.divide(node.mass));var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node.mass)).divide(l*l))}}}},_whichQuad:function(i,f){if(i.p.exploded()){return null}var h=i.p.subtract(f.origin);var g=f.size.divide(2);if(h.y-1){o.splice(p,1)}delete c.particles[r];delete l.particles[r]},modifyNode:function(r,p){if(r in c.particles){var q=c.particles[r];if("x" in p){q.p.x=p.x}if("y" in p){q.p.y=p.y}if("m" in p){q.m=p.m}if("f" in p){q.fixed=(p.f===1)}if("_m" in p){if(q._m===undefined){q._m=q.m}q.m=p._m}}},addSpring:function(t){var s=t.id;var p=t.l;var r=c.particles[t.fm];var q=c.particles[t.to];if(r!==undefined&&q!==undefined){c.springs[s]=new Spring(r,q,p,i.stiffness);k.push(c.springs[s]);r.connections++;q.connections++;delete l.particles[t.fm];delete l.particles[t.to]}},dropSpring:function(s){var r=s.id;var q=c.springs[r];q.point1.connections--;q.point2.connections--;var p=$.inArray(q,k);if(p>-1){k.splice(p,1)}delete c.springs[r]},_update:function(p){d++;$.each(p,function(q,r){if(r.t in i){i[r.t](r)}});return d},tick:function(){i.tendParticles();i.eulerIntegrator(i.dt);i.tock()},tock:function(){var p=[];$.each(c.particles,function(r,q){p.push(r);p.push(q.p.x);p.push(q.p.y)});if(h){h({geometry:p,epoch:d,energy:b,bounds:g})}},tendParticles:function(){$.each(c.particles,function(q,p){if(p._m!==undefined){if(Math.abs(p.m-p._m)<1){p.m=p._m;delete p._m}else{p.m*=0.98}}p.v.x=p.v.y=0})},eulerIntegrator:function(p){if(i.repulsion>0){if(i.theta>0){i.applyBarnesHutRepulsion()}else{i.applyBruteForceRepulsion()}}if(i.stiffness>0){i.applySprings()}i.applyCenterDrift();if(i.gravity){i.applyCenterGravity()}i.updateVelocity(p);i.updatePosition(p)},applyBruteForceRepulsion:function(){$.each(c.particles,function(q,p){$.each(c.particles,function(s,r){if(p!==r){var u=p.p.subtract(r.p);var v=Math.max(1,u.magnitude());var t=((u.magnitude()>0)?u:Point.random(1)).normalize();p.applyForce(t.multiply(i.repulsion*(r._m||r.m)*0.5).divide(v*v*0.5));r.applyForce(t.multiply(i.repulsion*(p._m||p.m)*0.5).divide(v*v*-0.5))}})})},applyBarnesHutRepulsion:function(){if(!g.topleft||!g.bottomright){return}var q=new Point(g.bottomright);var p=new Point(g.topleft);f.init(p,q,i.theta);$.each(c.particles,function(s,r){f.insert(r)});$.each(c.particles,function(s,r){f.applyForces(r,i.repulsion)})},applySprings:function(){$.each(c.springs,function(t,p){var s=p.point2.p.subtract(p.point1.p);var q=p.length-s.magnitude();var r=((s.magnitude()>0)?s:Point.random(1)).normalize();p.point1.applyForce(r.multiply(p.k*q*-0.5));p.point2.applyForce(r.multiply(p.k*q*0.5))})},applyCenterDrift:function(){var q=0;var r=new Point(0,0);$.each(c.particles,function(t,s){r.add(s.p);q++});if(q==0){return}var p=r.divide(-q);$.each(c.particles,function(t,s){s.applyForce(p)})},applyCenterGravity:function(){$.each(c.particles,function(r,p){var q=p.p.multiply(-1);p.applyForce(q.multiply(i.repulsion/100))})},updateVelocity:function(p){$.each(c.particles,function(t,q){if(q.fixed){q.v=new Point(0,0);q.f=new Point(0,0);return}var s=q.v.magnitude();q.v=q.v.add(q.f.multiply(p)).multiply(1-i.friction);q.f.x=q.f.y=0;var r=q.v.magnitude();if(r>j){q.v=q.v.divide(r*r)}})},updatePosition:function(q){var r=0,p=0,u=0;var t=null;var s=null;$.each(c.particles,function(w,v){v.p=v.p.add(v.v.multiply(q));var x=v.v.magnitude();var z=x*x;r+=z;p=Math.max(z,p);u++;if(!t){t=new Point(v.p.x,v.p.y);s=new Point(v.p.x,v.p.y);return}var y=v.p;if(y.x===null||y.y===null){return}if(y.x>t.x){t.x=y.x}if(y.y>t.y){t.y=y.y}if(y.x1000){e.stop()}else{}}else{c=null}},tock:function(h){h.type="geometry";postMessage(h)},modifyNode:function(i,h){a.modifyNode(i,h);e.go()},modifyPhysics:function(h){a.modifyPhysics(h)},update:function(h){var i=a._update(h)}};return e};var physics=PhysicsWorker();onmessage=function(a){if(!a.data.type){postMessage("ÂżkĂ©rnèl?");return}if(a.data.type=="physics"){var b=a.data.physics;physics.init(a.data.physics);return}switch(a.data.type){case"modify":physics.modifyNode(a.data.id,a.data.mods);break;case"changes":physics.update(a.data.changes);physics.go();break;case"start":physics.go();break;case"stop":physics.stop();break;case"sys":var b=a.data.param||{};if(!isNaN(b.timeout)){physics.timeout(b.timeout)}physics.modifyPhysics(b);physics.go();break}}; - })() - - - arbor = (typeof(arbor)!=='undefined') ? arbor : {} - $.extend(arbor, { - // object constructors (don't use â€new’, just call them) - ParticleSystem:ParticleSystem, - Point:function(x, y){ return new Point(x, y) }, - - // immutable object with useful methods - etc:{ - trace:trace, // Ć’(msg) -> safe console logging - dirname:dirname, // Ć’(path) -> leading part of path - basename:basename, // Ć’(path) -> trailing part of path - ordinalize:ordinalize, // Ć’(num) -> abbrev integers (and add commas) - objcopy:objcopy, // Ć’(old) -> clone an object - objcmp:objcmp, // Ć’(a, b, strict_ordering) -> t/f comparison - objkeys:objkeys, // Ć’(obj) -> array of all keys in obj - objmerge:objmerge, // Ć’(dst, src) -> like $.extend but non-destructive - uniq:uniq, // Ć’(arr) -> array of unique items in arr - arbor_path:arbor_path, // Ć’() -> guess the directory of the lib code - } - }) - -})(this.jQuery) \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.js deleted file mode 100755 index cac3e78cb7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.js +++ /dev/null @@ -1,17710 +0,0 @@ - -/* cytoscape.js */ - -/** - * This file is part of cytoscape.js 2.1.0. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - - -// this is put as a global var in the browser -// or it's just a global to this module if commonjs -var cytoscape; - -(function(window){ "use strict"; - - // the object iteself is a function that init's an instance of cytoscape - var $$ = cytoscape = function(){ - return cytoscape.init.apply(cytoscape, arguments); - }; - - // allow functional access to cytoscape.js - // e.g. var cyto = $.cytoscape({ selector: "#foo", ... }); - // var nodes = cyto.nodes(); - $$.init = function( options ){ - - // if no options specified, use default - if( options === undefined ){ - options = {}; - } - - // create instance - if( $$.is.plainObject( options ) ){ - return new $$.Core( options ); - } - - // allow for registration of extensions - // e.g. $.cytoscape("renderer", "svg", SvgRenderer); - // e.g. $.cytoscape("renderer", "svg", "nodeshape", "ellipse", SvgEllipseNodeShape); - // e.g. $.cytoscape("core", "doSomething", function(){ /* doSomething code */ }); - // e.g. $.cytoscape("collection", "doSomething", function(){ /* doSomething code */ }); - else if( $$.is.string( options ) ) { - return $$.extension.apply($$.extension, arguments); - } - }; - - // define the function namespace here, since it has members in many places - $$.fn = {}; - - // TODO test that this works: - if( typeof exports !== 'undefined' ){ // expose as a commonjs module - exports = module.exports = cytoscape; - } - - // make sure we always register in the window just in case (e.g. w/ derbyjs) - if( window ){ - window.cytoscape = cytoscape; - } - -})( typeof window === 'undefined' ? null : window ); - -// type testing utility functions - -;(function($$, window){ "use strict"; - - $$.is = { - string: function(obj){ - return obj != null && typeof obj == typeof ""; - }, - - fn: function(obj){ - return obj != null && typeof obj === typeof function(){}; - }, - - array: function(obj){ - return obj != null && obj instanceof Array; - }, - - plainObject: function(obj){ - return obj != null && typeof obj === typeof {} && !$$.is.array(obj) && obj.constructor === Object; - }, - - number: function(obj){ - return obj != null && typeof obj === typeof 1 && !isNaN(obj); - }, - - integer: function( obj ){ - return $$.is.number(obj) && Math.floor(obj) === obj; - }, - - color: function(obj){ - return obj != null && typeof obj === typeof "" && $.Color(obj).toString() !== ""; - }, - - bool: function(obj){ - return obj != null && typeof obj === typeof true; - }, - - elementOrCollection: function(obj){ - return $$.is.element(obj) || $$.is.collection(obj); - }, - - element: function(obj){ - return obj instanceof $$.Element && obj._private.single; - }, - - collection: function(obj){ - return obj instanceof $$.Collection && !obj._private.single; - }, - - core: function(obj){ - return obj instanceof $$.Core; - }, - - style: function(obj){ - return obj instanceof $$.Style; - }, - - stylesheet: function(obj){ - return obj instanceof $$.Stylesheet; - }, - - event: function(obj){ - return obj instanceof $$.Event; - }, - - emptyString: function(obj){ - if( !obj ){ // null is empty - return true; - } else if( $$.is.string(obj) ){ - if( obj === "" || obj.match(/^\s+$/) ){ - return true; // empty string is empty - } - } - - return false; // otherwise, we don't know what we've got - }, - - nonemptyString: function(obj){ - if( obj && $$.is.string(obj) && obj !== "" && !obj.match(/^\s+$/) ){ - return true; - } - - return false; - }, - - domElement: function(obj){ - if( typeof HTMLElement === 'undefined' ){ - return false; // we're not in a browser so it doesn't matter - } else { - return obj instanceof HTMLElement; - } - - - }, - - touch: function(){ - return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ); - } - }; - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ "use strict"; - - // utility functions only for internal use - - $$.util = { - - // the jquery extend() function - // NB: modified to use $$.is etc since we can't use jquery functions - extend: function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !$$.is.fn(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( $$.is.plainObject(copy) || (copyIsArray = $$.is.array(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && $$.is.array(src) ? src : []; - - } else { - clone = src && $$.is.plainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = $$.util.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; - }, - - error: function( msg ){ - if( console ){ - if( console.error ){ - console.error( msg ); - } else if( console.log ){ - console.log( msg ); - } else { - throw msg; - } - } else { - throw msg; - } - }, - - clone: function( obj ){ - var target = {}; - for (var i in obj) { - if ( obj.hasOwnProperty(i) ) { // TODO is this hasOwnProperty() call necessary for our use? - target[i] = obj[i]; - } - } - return target; - }, - - // gets a shallow copy of the argument - copy: function( obj ){ - if( obj == null ){ - return obj; - } if( $$.is.array(obj) ){ - return obj.slice(); - } else if( $$.is.plainObject(obj) ){ - return $$.util.clone( obj ); - } else { - return obj; - } - }, - - // has anything been set in the map - mapEmpty: function( map ){ - var empty = true; - - if( map != null ){ - for(var i in map){ - empty = false; - break; - } - } - - return empty; - }, - - // pushes to the array at the end of a map (map may not be built) - pushMap: function( options ){ - var array = $$.util.getMap(options); - - if( array == null ){ // if empty, put initial array - $$.util.setMap( $.extend({}, options, { - value: [ options.value ] - }) ); - } else { - array.push( options.value ); - } - }, - - // sets the value in a map (map may not be built) - setMap: function( options ){ - var obj = options.map; - var key; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to set map with object key"); - } - - if( i < keys.length - 1 ){ - - // extend the map if necessary - if( obj[key] == null ){ - obj[key] = {}; - } - - obj = obj[key]; - } else { - // set the value - obj[key] = options.value; - } - } - }, - - // gets the value in a map even if it's not built in places - getMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to get map with object key"); - } - - obj = obj[key]; - - if( obj == null ){ - return obj; - } - } - - return obj; - }, - - // deletes the entry in the map - deleteMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - var keepChildren = options.keepChildren; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to delete map with object key"); - } - - var lastKey = i === options.keys.length - 1; - if( lastKey ){ - - if( keepChildren ){ // then only delete child fields not in keepChildren - for( var child in obj ){ - if( !keepChildren[child] ){ - delete obj[child]; - } - } - } else { - delete obj[key]; - } - - } else { - obj = obj[key]; - } - } - }, - - capitalize: function(str){ - if( $$.is.emptyString(str) ){ - return str; - } - - return str.charAt(0).toUpperCase() + str.substring(1); - }, - - camel2dash: function( str ){ - var ret = []; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var chLowerCase = ch.toLowerCase(); - var isUpperCase = ch !== chLowerCase; - - if( isUpperCase ){ - ret.push( "-" ); - ret.push( chLowerCase ); - } else { - ret.push( ch ); - } - } - - var noUpperCases = ret.length === str.length; - if( noUpperCases ){ return str } // cheaper than .join() - - return ret.join(""); - }, - - dash2camel: function( str ){ - var ret = []; - var nextIsUpper = false; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var isDash = ch === "-"; - - if( isDash ){ - nextIsUpper = true; - } else { - if( nextIsUpper ){ - ret.push( ch.toUpperCase() ); - } else { - ret.push( ch ); - } - - nextIsUpper = false; - } - } - - return ret.join(""); - }, - - // strip spaces from beginning of string and end of string - trim: function( str ){ - var first, last; - - // find first non-space char - for( first = 0; first < str.length && str[first] === " "; first++ ){} - - // find last non-space char - for( last = str.length - 1; last > first && str[last] === " "; last-- ){} - - return str.substring(first, last + 1); - }, - - // get [r, g, b] from #abc or #aabbcc - hex2tuple: function( hex ){ - if( !(hex.length === 4 || hex.length === 7) || hex[0] !== "#" ){ return; } - - var shortHex = hex.length === 4; - var r, g, b; - var base = 16; - - if( shortHex ){ - r = parseInt( hex[1] + hex[1], base ); - g = parseInt( hex[2] + hex[2], base ); - b = parseInt( hex[3] + hex[3], base ); - } else { - r = parseInt( hex[1] + hex[2], base ); - g = parseInt( hex[3] + hex[4], base ); - b = parseInt( hex[5] + hex[6], base ); - } - - return [r, g, b]; - }, - - // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0) - hsl2tuple: function( hsl ){ - var ret; - var number = $$.util.regex.number; - var h, s, l, a, r, g, b; - function hue2rgb(p, q, t){ - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - var m = new RegExp("^" + $$.util.regex.hsla + "$").exec(hsl); - if( m ){ - - // get hue - h = parseInt( m[1] ); - if( h < 0 ){ - h = ( 360 - (-1*h % 360) ) % 360; - } else if( h > 360 ){ - h = h % 360; - } - h /= 360; // normalise on [0, 1] - - s = parseFloat( m[2] ); - if( s < 0 || s > 100 ){ return; } // saturation is [0, 100] - s = s/100; // normalise on [0, 1] - - l = parseFloat( m[3] ); - if( l < 0 || l > 100 ){ return; } // lightness is [0, 100] - l = l/100; // normalise on [0, 1] - - a = m[4]; - if( a !== undefined ){ - a = parseFloat( a ); - - if( a < 0 || a > 1 ){ return; } // alpha is [0, 1] - } - - // now, convert to rgb - // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - if( s === 0 ){ - r = g = b = Math.round(l * 255); // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = Math.round( 255 * hue2rgb(p, q, h + 1/3) ); - g = Math.round( 255 * hue2rgb(p, q, h) ); - b = Math.round( 255 * hue2rgb(p, q, h - 1/3) ); - } - - ret = [r, g, b, a]; - } - - return ret; - }, - - // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0) - rgb2tuple: function( rgb ){ - var ret; - var number = $$.util.regex.number; - - var m = new RegExp("^" + $$.util.regex.rgba + "$").exec(rgb); - if( m ){ - ret = []; - - var isPct = []; - for( var i = 1; i <= 3; i++ ){ - var channel = m[i]; - - if( channel[ channel.length - 1 ] === "%" ){ - isPct[i] = true; - } - channel = parseFloat( channel ); - - if( isPct[i] ){ - channel = channel/100 * 255; // normalise to [0, 255] - } - - if( channel < 0 || channel > 255 ){ return; } // invalid channel value - - ret.push( Math.floor(channel) ); - } - - var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3]; - var allArePct = isPct[1] && isPct[2] && isPct[3]; - if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is - - var alpha = m[4]; - if( alpha !== undefined ){ - alpha = parseFloat( alpha ); - - if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value - - ret.push( alpha ); - } - } - - return ret; - }, - - colorname2tuple: function( color ){ - return $$.util.colors[ color.toLowerCase() ]; - }, - - color2tuple: function( color ){ - return $$.util.colorname2tuple(color) - || $$.util.hex2tuple(color) - || $$.util.rgb2tuple(color) - || $$.util.hsl2tuple(color); - }, - - tuple2hex: function( tuple ){ - var r = tuple[0]; - var g = tuple[1]; - var b = tuple[2]; - - function ch2hex( ch ){ - var hex = ch.toString(16); - - if( hex.length === 1 ){ - hex = '0' + hex; - } - - return hex; - } - - return '#' + ch2hex(r) + ch2hex(g) + ch2hex(b); - }, - - colors: { - // special colour names - transparent: [0,0,0,0], // NB alpha === 0 - - // regular colours - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - darkkhaki: [189,183,107], - darkmagenta: [139,0,139], - darkolivegreen: [85,107,47], - darkorange: [255,140,0], - darkorchid: [153,50,204], - darkred: [139,0,0], - darksalmon: [233,150,122], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - grey: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] - } - - }; - - $$.util.regex = {}; - - $$.util.regex.number = "(?:[-]?\\d*\\.\\d+|[-]?\\d+|[-]?\\d*\\.\\d+[eE]\\d+)"; - - $$.util.regex.rgba = "rgb[a]?\\(("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.rgbaNoBackRefs = "rgb[a]?\\((?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hsla = "hsl[a]?\\(("+ $$.util.regex.number +")\\s*,\\s*("+ $$.util.regex.number +"[%])\\s*,\\s*("+ $$.util.regex.number +"[%])(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.hslaNoBackRefs = "hsl[a]?\\((?:"+ $$.util.regex.number +")\\s*,\\s*(?:"+ $$.util.regex.number +"[%])\\s*,\\s*(?:"+ $$.util.regex.number +"[%])(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hex3 = "\\#[0-9a-fA-F]{3}"; - $$.util.regex.hex6 = "\\#[0-9a-fA-F]{6}"; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.math = {}; - - $$.math.signum = function(x){ - if( x > 0 ){ - return 1; - } else if( x < 0 ){ - return -1; - } else { - return 0; - } - }; - - $$.math.distance = function( p1, p2 ){ - var dx = p2.x - p1.x; - var dy = p2.y - p1.y; - - return Math.sqrt( dx*dx + dy*dy ); - }; - - // from http://en.wikipedia.org/wiki/BĂ©zier_curve#Quadratic_curves - $$.math.qbezierAt = function(p0, p1, p2, t){ - return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2; - } - - $$.math.qbezierPtAt = function(p0, p1, p2, t){ - return { - x: $$.math.qbezierAt( p0.x, p1.x, p2.x, t ), - y: $$.math.qbezierAt( p0.y, p1.y, p2.y, t ) - }; - } - - $$.math.roundRectangleIntersectLine = function( - x, y, nodeX, nodeY, width, height, padding) { - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var halfWidth = width / 2; - var halfHeight = height / 2; - - // Check intersections with straight line segments - var straightLineIntersections; - - // Top segment, left to right - { - var topStartX = nodeX - halfWidth + cornerRadius - padding; - var topStartY = nodeY - halfHeight - padding; - var topEndX = nodeX + halfWidth - cornerRadius + padding; - var topEndY = topStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Right segment, top to bottom - { - var rightStartX = nodeX + halfWidth + padding; - var rightStartY = nodeY - halfHeight + cornerRadius - padding; - var rightEndX = rightStartX; - var rightEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Bottom segment, left to right - { - var bottomStartX = nodeX - halfWidth + cornerRadius - padding; - var bottomStartY = nodeY + halfHeight + padding; - var bottomEndX = nodeX + halfWidth - cornerRadius + padding; - var bottomEndY = bottomStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Left segment, top to bottom - { - var leftStartX = nodeX - halfWidth - padding; - var leftStartY = nodeY - halfHeight + cornerRadius - padding; - var leftEndX = leftStartX; - var leftEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Check intersections with arc segments - var arcIntersections; - - // Top Left - { - var topLeftCenterX = nodeX - halfWidth + cornerRadius; - var topLeftCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topLeftCenterX, topLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= topLeftCenterX - && arcIntersections[1] <= topLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Top Right - { - var topRightCenterX = nodeX + halfWidth - cornerRadius; - var topRightCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topRightCenterX, topRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= topRightCenterX - && arcIntersections[1] <= topRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Right - { - var bottomRightCenterX = nodeX + halfWidth - cornerRadius; - var bottomRightCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomRightCenterX, bottomRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= bottomRightCenterX - && arcIntersections[1] >= bottomRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Left - { - var bottomLeftCenterX = nodeX - halfWidth + cornerRadius; - var bottomLeftCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= bottomLeftCenterX - && arcIntersections[1] >= bottomLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - return []; // if nothing - }; - - $$.math.roundRectangleIntersectBox = function( - boxX1, boxY1, boxX2, boxY2, width, height, centerX, centerY, padding) { - - // We have the following shpae - - // _____ - // _| |_ - // | | - // |_ _| - // |_____| - // - // With a quarter circle at each corner. - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var hBoxTopLeftX = centerX - width / 2 - padding; - var hBoxTopLeftY = centerY - height / 2 + cornerRadius - padding; - var hBoxBottomRightX = centerX + width / 2 + padding; - var hBoxBottomRightY = centerY + height / 2 - cornerRadius + padding; - - var vBoxTopLeftX = centerX - width / 2 + cornerRadius - padding; - var vBoxTopLeftY = centerY - height / 2 - padding; - var vBoxBottomRightX = centerX + width / 2 - cornerRadius + padding; - var vBoxBottomRightY = centerY + height / 2 + padding; - - // Check if the box is out of bounds - var boxMinX = Math.min(boxX1, boxX2); - var boxMaxX = Math.max(boxX1, boxX2); - var boxMinY = Math.min(boxY1, boxY2); - var boxMaxY = Math.max(boxY1, boxY2); - - if (boxMaxX < hBoxTopLeftX) { - return false; - } else if (boxMinX > hBoxBottomRightX) { - return false; - } - - if (boxMaxY < vBoxTopLeftY) { - return false; - } else if (boxMinY > vBoxBottomRightY) { - return false; - } - - // Check if an hBox point is in given box - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the hBox - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - // Check if an vBox point is in given box - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the vBox - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - // Lastly, check if one of the ellipses coincide with the box - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxBottomRightY - padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxBottomRightY - padding)) { - return true; - } - - return false; - }; - - // @O Approximate collision functions - $$.math.checkInBoundingCircle = function( - x, y, farthestPointSqDistance, padding, width, height, centerX, centerY) { - - x = (x - centerX) / (width + padding); - y = (y - centerY) / (height + padding); - - return (x * x + y * y) <= farthestPointSqDistance; - }; - - $$.math.checkInBoundingBox = function( - x, y, points, padding, width, height, centerX, centerY) { - - // Assumes width, height >= 0, points.length > 0 - - var minX = points[0], minY = points[1]; - var maxX = points[0], maxY = points[1]; - - for (var i = 1; i < points.length / 2; i++) { - - if (points[i * 2] < minX) { - minX = points[i * 2]; - } else if (points[i * 2] > maxX) { - maxX = points[i * 2]; - } - - if (points[i * 2 + 1] < minY) { - minY = points[i * 2 + 1]; - } else if (points[i * 2 + 1] > maxY) { - maxY = points[i * 2 + 1]; - } - } - - x -= centerX; - y -= centerY; - - x /= width; - y /= height; - - if (x < minX) { - return false; - } else if (x > maxX) { - return false; - } - - if (y < minY) { - return false; - } else if (y > maxY) { - return false; - } - - return true; - }; - - $$.math.boxInBezierVicinity = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - // Return values: - // 0 - curve is not in box - // 1 - curve may be in box; needs precise check - // 2 - curve is in box - - // midpoint - var midX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var midY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { // (x1, y1) in box - return 1; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { // (x3, y3) in box - return 1; - } else if (midX >= boxMinX && midX <= boxMaxX && midY >= boxMinY && midY <= boxMaxY) { // (midX, midY) in box - return 1; - } else if (x2 >= boxMinX && x2 <= boxMaxX && y2 >= boxMinY && y2 <= boxMaxY) { // ctrl pt in box - return 1; - } - - var curveMinX = Math.min(x1, midX, x3); - var curveMinY = Math.min(y1, midY, y3); - var curveMaxX = Math.max(x1, midX, x3); - var curveMaxY = Math.max(y1, midY, y3); - - /* - console.log(curveMinX + ", " + curveMinY + ", " + curveMaxX - + ", " + curveMaxY); - if (curveMinX == undefined) { - console.log("undefined curveMinX: " + x1 + ", " + x2 + ", " + x3); - } - */ - - if (curveMinX > boxMaxX - || curveMaxX < boxMinX - || curveMinY > boxMaxY - || curveMaxY < boxMinY) { - - return 0; - } - - return 1; - }; - - $$.math.checkBezierInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - function sampleInBox(t){ - var x = $$.math.qbezierAt(x1, x2, x3, t); - var y = $$.math.qbezierAt(y1, y2, y3, t); - - return x1box <= x && x <= x2box - && y1box <= y && y <= y2box - ; - } - - for( var t = 0; t <= 1; t += 0.25 ){ - if( !sampleInBox(t) ){ - return false; - } - } - - return true; - }; - - $$.math.checkStraightEdgeInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - return x1box <= x1 && x1 <= x2box - && x1box <= x2 && x2 <= x2box - && y1box <= y1 && y1 <= y2box - && y1box <= y2 && y2 <= y2box - ; - }; - - $$.math.checkStraightEdgeCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - //console.log(arguments); - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - // Check left + right bounds - var aX = x2 - x1; - var bX = x1; - var yValue; - - // Top and bottom - var aY = y2 - y1; - var bY = y1; - var xValue; - - if (Math.abs(aX) < 0.0001) { - return (x1 >= boxMinX && x1 <= boxMaxX - && Math.min(y1, y2) <= boxMinY - && Math.max(y1, y2) >= boxMaxY); - } - - var tLeft = (boxMinX - bX) / aX; - if (tLeft > 0 && tLeft <= 1) { - yValue = aY * tLeft + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tRight = (boxMaxX - bX) / aX; - if (tRight > 0 && tRight <= 1) { - yValue = aY * tRight + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tTop = (boxMinY - bY) / aY; - if (tTop > 0 && tTop <= 1) { - xValue = aX * tTop + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - var tBottom = (boxMaxY - bY) / aY; - if (tBottom > 0 && tBottom <= 1) { - xValue = aX * tBottom + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - return false; - }; - - $$.math.checkBezierCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { - return true; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { - return true; - } - - var aX = x1 - 2 * x2 + x3; - var bX = -2 * x1 + 2 * x2; - var cX = x1; - - var xIntervals = []; - - if (Math.abs(aX) < 0.0001) { - var leftParam = (boxMinX - x1) / bX; - var rightParam = (boxMaxX - x1) / bX; - - xIntervals.push(leftParam, rightParam); - } else { - // Find when x coordinate of the curve crosses the left side of the box - var discriminantX1 = bX * bX - 4 * aX * (cX - boxMinX); - var tX1, tX2; - if (discriminantX1 > 0) { - var sqrt = Math.sqrt(discriminantX1); - tX1 = (-bX + sqrt) / (2 * aX); - tX2 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX1, tX2); - } - - var discriminantX2 = bX * bX - 4 * aX * (cX - boxMaxX); - var tX3, tX4; - if (discriminantX2 > 0) { - var sqrt = Math.sqrt(discriminantX2); - tX3 = (-bX + sqrt) / (2 * aX); - tX4 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX3, tX4); - } - } - - xIntervals.sort(function(a, b) { return a - b; }); - - var aY = y1 - 2 * y2 + y3; - var bY = -2 * y1 + 2 * y2; - var cY = y1; - - var yIntervals = []; - - if (Math.abs(aY) < 0.0001) { - var topParam = (boxMinY - y1) / bY; - var bottomParam = (boxMaxY - y1) / bY; - - yIntervals.push(topParam, bottomParam); - } else { - var discriminantY1 = bY * bY - 4 * aY * (cY - boxMinY); - - var tY1, tY2; - if (discriminantY1 > 0) { - var sqrt = Math.sqrt(discriminantY1); - tY1 = (-bY + sqrt) / (2 * aY); - tY2 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY1, tY2); - } - - var discriminantY2 = bY * bY - 4 * aY * (cY - boxMaxY); - - var tY3, tY4; - if (discriminantY2 > 0) { - var sqrt = Math.sqrt(discriminantY2); - tY3 = (-bY + sqrt) / (2 * aY); - tY4 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY3, tY4); - } - } - - yIntervals.sort(function(a, b) { return a - b; }); - - for (var index = 0; index < xIntervals.length; index += 2) { - for (var yIndex = 1; yIndex < yIntervals.length; yIndex += 2) { - - // Check if there exists values for the Bezier curve - // parameter between 0 and 1 where both the curve's - // x and y coordinates are within the bounds specified by the box - if (xIntervals[index] < yIntervals[yIndex] - && yIntervals[yIndex] >= 0.0 - && xIntervals[index] <= 1.0 - && xIntervals[index + 1] > yIntervals[yIndex - 1] - && yIntervals[yIndex - 1] <= 1.0 - && xIntervals[index + 1] >= 0.0) { - - return true; - } - } - } - - return false; - }; - - $$.math.inLineVicinity = function(x, y, lx1, ly1, lx2, ly2, tolerance){ - var t = tolerance; - - var x1 = Math.min(lx1, lx2); - var x2 = Math.max(lx1, lx2); - var y1 = Math.min(ly1, ly2); - var y2 = Math.max(ly1, ly2); - - return x1 - t <= x && x <= x2 + t - && y1 - t <= y && y <= y2 + t; - }; - - $$.math.inBezierVicinity = function( - x, y, x1, y1, x2, y2, x3, y3, toleranceSquared) { - - // unfortunately yue's function makes several assumptions about the beziers - // and is not generic enough to be used properly - // a rough bounding box of the bezier curve - var bb = { - x1: Math.min( x1, x3, x2 ), - x2: Math.max( x1, x3, x2 ), - y1: Math.min( y1, y3, y2 ), - y2: Math.max( y1, y3, y2 ) - }; - - // if outside the rough bounding box for the bezier, then it can't be a hit - if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){ - // console.log('bezier out of rough bb') - return false; - } else { - // console.log('do more expensive check'); - return true; - } - - /// END STOP USING YUE'S IMPL - - // Middle point occurs when t = 0.5, this is when the Bezier - // is closest to (x2, y2) - var middlePointX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var middlePointY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - // a rough bounding box of the bezier curve - var bb = { - x1: Math.min( x1, x3, middlePointX ), - x2: Math.max( x1, x3, middlePointX ), - y1: Math.min( y1, y3, middlePointY ), - y2: Math.max( y1, y3, middlePointY ) - }; - - // if outside the rough bounding box for the bezier, then it can't be a hit - if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){ - // console.log('bezier out of rough bb') - return false; - } else { - // console.log('do more expensive check'); - return true; - } - - var displacementX, displacementY, offsetX, offsetY; - var dotProduct, dotSquared, hypSquared; - var outside = function(x, y, startX, startY, endX, endY, - toleranceSquared, counterClockwise) { - - dotProduct = (endY - startY) * (x - startX) + (startX - endX) * (y - startY); - dotSquared = dotProduct * dotProduct; - sideSquared = (endY - startY) * (endY - startY) - + (startX - endX) * (startX - endX); - - if (counterClockwise) { - if (dotProduct > 0) { - return false; - } - } else { - if (dotProduct < 0) { - return false; - } - } - - return (dotSquared / sideSquared > toleranceSquared); - }; - - // Used to check if the test polygon winding is clockwise or counterclockwise - var testPointX = (middlePointX + x2) / 2.0; - var testPointY = (middlePointY + y2) / 2.0; - - var counterClockwise = true; - - // The test point is always inside - if (outside(testPointX, testPointY, x1, y1, x2, y2, 0, counterClockwise)) { - counterClockwise = !counterClockwise; - } - - /* - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, middlePointX, middlePointY, toleranceSquared, - counterClockwise) - && !outside(x, y, middlePointX, middlePointY, x1, y1, toleranceSquared, - counterClockwise) - ); - */ - - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, x1, y1, toleranceSquared, - counterClockwise) - ); - }; - - $$.math.solveCubic = function(a, b, c, d, result) { - - // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where - // r is the real component, i is the imaginary component - - // An implementation of the Cardano method from the year 1545 - // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots - - b /= a; - c /= a; - d /= a; - - var discriminant, q, r, dum1, s, t, term1, r13; - - q = (3.0 * c - (b * b)) / 9.0; - r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); - r /= 54.0; - - discriminant = q * q * q + r * r; - result[1] = 0; - term1 = (b / 3.0); - - if (discriminant > 0) { - s = r + Math.sqrt(discriminant); - s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0))); - t = r - Math.sqrt(discriminant); - t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0))); - result[0] = -term1 + s + t; - term1 += (s + t) / 2.0; - result[4] = result[2] = -term1; - term1 = Math.sqrt(3.0) * (-t + s) / 2; - result[3] = term1; - result[5] = -term1; - return; - } - - result[5] = result[3] = 0; - - if (discriminant == 0) { - r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0))); - result[0] = -term1 + 2.0 * r13; - result[4] = result[2] = -(r13 + term1); - return; - } - - q = -q; - dum1 = q * q * q; - dum1 = Math.acos(r / Math.sqrt(dum1)); - r13 = 2.0 * Math.sqrt(q); - result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); - result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); - result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); - - return; - }; - - $$.math.sqDistanceToQuadraticBezier = function( - x, y, x1, y1, x2, y2, x3, y3) { - - // Find minimum distance by using the minimum of the distance - // function between the given point and the curve - - // This gives the coefficients of the resulting cubic equation - // whose roots tell us where a possible minimum is - // (Coefficients are divided by 4) - - var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3 - + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3; - - var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3 - + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3; - - var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x - + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y; - - var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x - + y1*y2 - y1*y1 + y1*y - y2*y; - - // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); - - var roots = []; - - // Use the cubic solving algorithm - this.solveCubic(a, b, c, d, roots); - - var zeroThreshold = 0.0000001; - - var params = []; - - for (var index = 0; index < 6; index += 2) { - if (Math.abs(roots[index + 1]) < zeroThreshold - && roots[index] >= 0 - && roots[index] <= 1.0) { - params.push(roots[index]); - } - } - - params.push(1.0); - params.push(0.0); - - var minDistanceSquared = -1; - var closestParam; - - var curX, curY, distSquared; - for (var i = 0; i < params.length; i++) { - curX = Math.pow(1.0 - params[i], 2.0) * x1 - + 2.0 * (1 - params[i]) * params[i] * x2 - + params[i] * params[i] * x3; - - curY = Math.pow(1 - params[i], 2.0) * y1 - + 2 * (1.0 - params[i]) * params[i] * y2 - + params[i] * params[i] * y3; - - distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); - // debug("distance for param " + params[i] + ": " + Math.sqrt(distSquared)); - if (minDistanceSquared >= 0) { - if (distSquared < minDistanceSquared) { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } else { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } - - /* - debugStats.clickX = x; - debugStats.clickY = y; - - debugStats.closestX = Math.pow(1.0 - closestParam, 2.0) * x1 - + 2.0 * (1.0 - closestParam) * closestParam * x2 - + closestParam * closestParam * x3; - - debugStats.closestY = Math.pow(1.0 - closestParam, 2.0) * y1 - + 2.0 * (1.0 - closestParam) * closestParam * y2 - + closestParam * closestParam * y3; - */ - - // debug("given: " - // + "( " + x + ", " + y + "), " - // + "( " + x1 + ", " + y1 + "), " - // + "( " + x2 + ", " + y2 + "), " - // + "( " + x3 + ", " + y3 + ")"); - - - // debug("roots: " + roots); - // debug("params: " + params); - // debug("closest param: " + closestParam); - return minDistanceSquared; - }; - - $$.math.sqDistanceToFiniteLine = function(x, y, x1, y1, x2, y2) { - var offset = [x - x1, y - y1]; - var line = [x2 - x1, y2 - y1]; - - var lineSq = line[0] * line[0] + line[1] * line[1]; - var hypSq = offset[0] * offset[0] + offset[1] * offset[1]; - - var dotProduct = offset[0] * line[0] + offset[1] * line[1]; - var adjSq = dotProduct * dotProduct / lineSq; - - if (dotProduct < 0) { - return hypSq; - } - - if (adjSq > lineSq) { - return (x - x2) * (x - x2) + (y - y2) * (y - y2); - } - - return (hypSq - adjSq) - }; - - $$.math.pointInsidePolygon = function( - x, y, basePoints, centerX, centerY, width, height, direction, padding) { - - //var direction = arguments[6]; - var transformedPoints = new Array(basePoints.length) - - // Gives negative angle - var angle = Math.asin(direction[1] / (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - if (direction[0] < 0) { - angle = angle + Math.PI / 2; - } else { - angle = -angle - Math.PI / 2; - } - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - -// console.log("base: " + basePoints); - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = - width / 2 * (basePoints[i * 2] * cos - - basePoints[i * 2 + 1] * sin); - - transformedPoints[i * 2 + 1] = - height / 2 * (basePoints[i * 2 + 1] * cos - + basePoints[i * 2] * sin); - - transformedPoints[i * 2] += centerX; - transformedPoints[i * 2 + 1] += centerY; - } - - var points; - - if (padding > 0) { - var expandedLineSet = this.expandPolygon( - transformedPoints, - -padding); - - points = this.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - var x1, y1, x2, y2; - var y3; - - // Intersect with vertical line through (x, y) - var up = 0; - var down = 0; - for (var i = 0; i < points.length / 2; i++) { - - x1 = points[i * 2]; - y1 = points[i * 2 + 1]; - - if (i + 1 < points.length / 2) { - x2 = points[(i + 1) * 2]; - y2 = points[(i + 1) * 2 + 1]; - } else { - x2 = points[(i + 1 - points.length / 2) * 2]; - y2 = points[(i + 1 - points.length / 2) * 2 + 1]; - } - -//* console.log("line from (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")"); - -//& console.log(x1, x, x2); - - if (x1 == x && x2 == x) { - - } else if ((x1 >= x && x >= x2) - || (x1 <= x && x <= x2)) { - - y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1; - - if (y3 > y) { - up++; - } - - if (y3 < y) { - down++; - } - -//* console.log(y3, y); - - } else { -//* console.log("22"); - continue; - } - - } - -//* console.log("up: " + up + ", down: " + down); - - if (up % 2 == 0) { - return false; - } else { - return true; - } - }; - - $$.math.joinLines = function(lineSet) { - - var vertices = new Array(lineSet.length / 2); - - var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY; - var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY; - - for (var i = 0; i < lineSet.length / 4; i++) { - currentLineStartX = lineSet[i * 4]; - currentLineStartY = lineSet[i * 4 + 1]; - currentLineEndX = lineSet[i * 4 + 2]; - currentLineEndY = lineSet[i * 4 + 3]; - - if (i < lineSet.length / 4 - 1) { - nextLineStartX = lineSet[(i + 1) * 4]; - nextLineStartY = lineSet[(i + 1) * 4 + 1]; - nextLineEndX = lineSet[(i + 1) * 4 + 2]; - nextLineEndY = lineSet[(i + 1) * 4 + 3]; - } else { - nextLineStartX = lineSet[0]; - nextLineStartY = lineSet[1]; - nextLineEndX = lineSet[2]; - nextLineEndY = lineSet[3]; - } - - var intersection = this.finiteLinesIntersect( - currentLineStartX, currentLineStartY, - currentLineEndX, currentLineEndY, - nextLineStartX, nextLineStartY, - nextLineEndX, nextLineEndY, - true); - - vertices[i * 2] = intersection[0]; - vertices[i * 2 + 1] = intersection[1]; - } - - return vertices; - }; - - $$.math.expandPolygon = function(points, pad) { - - var expandedLineSet = new Array(points.length * 2); - - var currentPointX, currentPointY, nextPointX, nextPointY; - - for (var i = 0; i < points.length / 2; i++) { - currentPointX = points[i * 2]; - currentPointY = points[i * 2 + 1]; - - if (i < points.length / 2 - 1) { - nextPointX = points[(i + 1) * 2]; - nextPointY = points[(i + 1) * 2 + 1]; - } else { - nextPointX = points[0]; - nextPointY = points[1]; - } - - // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY] - - // Assume CCW polygon winding - - var offsetX = (nextPointY - currentPointY); - var offsetY = -(nextPointX - currentPointX); - - // Normalize - var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY); - var normalizedOffsetX = offsetX / offsetLength; - var normalizedOffsetY = offsetY / offsetLength; - - expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad; - expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad; - expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad; - expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad; - } - - return expandedLineSet; - }; - - $$.math.intersectLineEllipse = function( - x, y, centerX, centerY, ellipseWradius, ellipseHradius) { - - var dispX = centerX - x; - var dispY = centerY - y; - - dispX /= ellipseWradius; - dispY /= ellipseHradius; - - var len = Math.sqrt(dispX * dispX + dispY * dispY); - - var newLength = len - 1; - - if (newLength < 0) { - return []; - } - - var lenProportion = newLength / len; - - return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y]; - }; - - $$.math.dotProduct = function( - vec1, vec2) { - - if (vec1.length != 2 || vec2.length != 2) { - throw 'dot product: arguments are not vectors'; - } - - return (vec1[0] * vec2[0] + vec1[1] * vec2[1]); - }; - - // Returns intersections of increasing distance from line's start point - $$.math.intersectLineCircle = function( - x1, y1, x2, y2, centerX, centerY, radius) { - - // Calculate d, direction vector of line - var d = [x2 - x1, y2 - y1]; // Direction vector of line - var s = [x1, y1]; // Start of line - var c = [centerX, centerY]; // Center of circle - var f = [x1 - centerX, y1 - centerY] - - var a = d[0] * d[0] + d[1] * d[1]; - var b = 2 * (f[0] * d[0] + f[1] * d[1]); - var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ; - - /* - var a = this.dotProduct(d, d); - var b = 2 * this.dotProduct(s, d) - this.dotProduct(d, c); - var c = this.dotProduct(s, s) - 2 * this.dotProduct(s, c) + this.dotProduct(c, c) - radius * radius ; - */ - - var discriminant = b*b-4*a*c; - - if (discriminant < 0) { - return []; - } - - var t1 = (-b + Math.sqrt(discriminant)) / (2 * a); - var t2 = (-b - Math.sqrt(discriminant)) / (2 * a); - - var tMin = Math.min(t1, t2); - var tMax = Math.max(t1, t2); - var inRangeParams = []; - - if (tMin >= 0 && tMin <= 1) { - inRangeParams.push(tMin); - } - - if (tMax >= 0 && tMax <= 1) { - inRangeParams.push(tMax); - } - - if (inRangeParams.length == 0) { - return []; - } - - var nearIntersectionX = inRangeParams[0] * d[0] + x1; - var nearIntersectionY = inRangeParams[0] * d[1] + y1; - - if (inRangeParams.length > 1) { - - if (inRangeParams[0] == inRangeParams[1]) { - return [nearIntersectionX, nearIntersectionY]; - } else { - - var farIntersectionX = inRangeParams[1] * d[0] + x1; - var farIntersectionY = inRangeParams[1] * d[1] + y1; - - return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY]; - } - - } else { - return [nearIntersectionX, nearIntersectionY] - } - - }; - - $$.math.findCircleNearPoint = function(centerX, centerY, - radius, farX, farY) { - - var displacementX = farX - centerX; - var displacementY = farY - centerY; - var distance = Math.sqrt(displacementX * displacementX - + displacementY * displacementY); - - var unitDisplacementX = displacementX / distance; - var unitDisplacementY = displacementY / distance; - - return [centerX + unitDisplacementX * radius, - centerY + unitDisplacementY * radius]; - }; - - $$.math.findMaxSqDistanceToOrigin = function(points) { - var maxSqDistance = 0.000001; - var sqDistance; - - for (var i = 0; i < points.length / 2; i++) { - - sqDistance = points[i * 2] * points[i * 2] - + points[i * 2 + 1] * points[i * 2 + 1]; - - if (sqDistance > maxSqDistance) { - maxSqDistance = sqDistance; - } - } - - return maxSqDistance; - }; - - $$.math.finiteLinesIntersect = function( - x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { - - var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); - var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); - var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - - if (u_b != 0) { - var ua = ua_t / u_b; - var ub = ub_t / u_b; - - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - - } else { - if (!infiniteLines) { - return []; - } else { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - } - } - } else { - if (ua_t == 0 || ub_t == 0) { - - // Parallel, coincident lines. Check if overlap - - // Check endpoint of second line - if ([x1, x2, x4].sort()[1] == x4) { - return [x4, y4]; - } - - // Check start point of second line - if ([x1, x2, x3].sort()[1] == x3) { - return [x3, y3]; - } - - // Endpoint of first line - if ([x3, x4, x2].sort()[1] == x2) { - return [x2, y2]; - } - - return []; - } else { - - // Parallel, non-coincident - return []; - } - } - }; - - // (boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - // cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - - $$.math.boxIntersectEllipse = function( - x1, y1, x2, y2, padding, width, height, centerX, centerY) { - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - // 4 ortho extreme points - var west = [centerX - width / 2 - padding, centerY]; - var east = [centerX + width / 2 + padding, centerY]; - var north = [centerX, centerY - height / 2 - padding]; - var south = [centerX, centerY + height / 2 + padding]; - - // out of bounds: return false - if (x2 < west[0]) { - return false; - } - - if (x1 > east[0]) { - return false; - } - - if (y1 > south[1]) { - return false; - } - - if (y2 < north[1]) { - return false; - } - - // 1 of 4 ortho extreme points in box: return true - if (x1 <= east[0] && east[0] <= x2 - && y1 <= east[1] && east[1] <= y2) { - return true; - } - - if (x1 <= west[0] && west[0] <= x2 - && y1 <= west[1] && west[1] <= y2) { - return true; - } - - if (x1 <= north[0] && north[0] <= x2 - && y1 <= north[1] && north[1] <= y2) { - return true; - } - - if (x1 <= south[0] && south[0] <= x2 - && y1 <= south[1] && south[1] <= y2) { - return true; - } - - // box corner in ellipse: return true - x1 = (x1 - centerX) / (width / 2 + padding); - x2 = (x2 - centerX) / (width / 2 + padding); - - y1 = (y1 - centerY) / (height / 2 + padding); - y2 = (y2 - centerY) / (height / 2 + padding); - - if (x1 * x1 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y2 * y2 <= 1) { - return true; - } - - if (x1 * x1 + y2 * y2 <= 1) { - return true; - } - - return false; - }; - - $$.math.boxIntersectPolygon = function( - x1, y1, x2, y2, basePoints, width, height, centerX, centerY, direction, padding) { - -// console.log(arguments); - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - var transformedPoints = new Array(basePoints.length) - - // Gives negative of angle - var angle = Math.asin(direction[1] / (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - if (direction[0] < 0) { - angle = angle + Math.PI / 2; - } else { - angle = -angle - Math.PI / 2; - } - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = - width / 2 * (basePoints[i * 2] * cos - - basePoints[i * 2 + 1] * sin); - - transformedPoints[i * 2 + 1] = - height / 2 * (basePoints[i * 2 + 1] * cos - + basePoints[i * 2] * sin); - - transformedPoints[i * 2] += centerX; - transformedPoints[i * 2 + 1] += centerY; - } - - // Assume transformedPoints.length > 0, and check if intersection is possible - var minTransformedX = transformedPoints[0]; - var maxTransformedX = transformedPoints[0]; - var minTransformedY = transformedPoints[1]; - var maxTransformedY = transformedPoints[1]; - - for (var i = 1; i < transformedPoints.length / 2; i++) { - if (transformedPoints[i * 2] > maxTransformedX) { - maxTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2] < minTransformedX) { - minTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2 + 1] > maxTransformedY) { - maxTransformedY = transformedPoints[i * 2 + 1]; - } - - if (transformedPoints[i * 2 + 1] < minTransformedY) { - minTransformedY = transformedPoints[i * 2 + 1]; - } - } - - if (x2 < minTransformedX - padding) { - return false; - } - - if (x1 > maxTransformedX + padding) { - return false; - } - - if (y2 < minTransformedY - padding) { - return false; - } - - if (y1 > maxTransformedY + padding) { - return false; - } - - // Continue checking with padding-corrected points - var points; - - if (padding > 0) { - var expandedLineSet = $$.math.expandPolygon( - transformedPoints, - -padding); - - points = $$.math.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - // Check if a point is in box - for (var i = 0; i < transformedPoints.length / 2; i++) { - if (x1 <= transformedPoints[i * 2] - && transformedPoints[i * 2] <= x2) { - - if (y1 <= transformedPoints[i * 2 + 1] - && transformedPoints[i * 2 + 1] <= y2) { - - return true; - } - } - } - - - // Check for intersections with the selection box - for (var i = 0; i < points.length / 2; i++) { - - var currentX = points[i * 2]; - var currentY = points[i * 2 + 1]; - var nextX; - var nextY; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1] - } else { - nextX = points[0]; - nextY = points[1]; - } - - // Intersection with top of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x2, y1, false).length > 0) { - return true; - } - - // Intersection with bottom of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y2, x2, y2, false).length > 0) { - return true; - } - - // Intersection with left side of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x1, y2, false).length > 0) { - return true; - } - - // Intersection with right side of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x2, y1, x2, y2, false).length > 0) { - return true; - } - } - - /* - // Check if box corner in the polygon - if ($$.math.pointInsidePolygon( - x1, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x1, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x2, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x2, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } - */ - return false; - }; - - $$.math.polygonIntersectLine = function( - x, y, basePoints, centerX, centerY, width, height, padding) { - - var intersections = []; - var intersection; - - var transformedPoints = new Array(basePoints.length); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = basePoints[i * 2] * width + centerX; - transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY; - } - - var points; - - if (padding > 0) { - var expandedLineSet = $$.math.expandPolygon( - transformedPoints, - -padding); - - points = $$.math.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - // var points = transformedPoints; - - var currentX, currentY, nextX, nextY; - - for (var i = 0; i < points.length / 2; i++) { - - currentX = points[i * 2]; - currentY = points[i * 2 + 1]; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1]; - } else { - nextX = points[0]; - nextY = points[1]; - } - - intersection = this.finiteLinesIntersect( - x, y, centerX, centerY, - currentX, currentY, - nextX, nextY); - - if (intersection.length != 0) { - intersections.push(intersection[0], intersection[1]); - } - } - - return intersections; - }; - - $$.math.shortenIntersection = function( - intersection, offset, amount) { - - var disp = [intersection[0] - offset[0], intersection[1] - offset[1]]; - - var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]); - - var lenRatio = (length - amount) / length; - - if (lenRatio < 0) { - lenRatio = 0.00001; - } - - return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]]; - }; - - $$.math.generateUnitNgonPointsFitToSquare = function(sides, rotationRadians) { - var points = $$.math.generateUnitNgonPoints(sides, rotationRadians); - points = $$.math.fitPolygonToSquare(points); - - return points; - }; - - $$.math.fitPolygonToSquare = function(points){ - var x, y; - var sides = points.length/2; - var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - for (var i = 0; i < sides; i++) { - x = points[2 * i]; - y = points[2 * i + 1]; - - minX = Math.min( minX, x ); - maxX = Math.max( maxX, x ); - minY = Math.min( minY, y ); - maxY = Math.max( maxY, y ); - } - - // stretch factors - var sx = 2 / (maxX - minX); - var sy = 2 / (maxY - minY); - - for (var i = 0; i < sides; i++){ - x = points[2 * i] = points[2 * i] * sx; - y = points[2 * i + 1] = points[2 * i + 1] * sy; - - minX = Math.min( minX, x ); - maxX = Math.max( maxX, x ); - minY = Math.min( minY, y ); - maxY = Math.max( maxY, y ); - } - - if( minY < -1 ){ - for (var i = 0; i < sides; i++){ - y = points[2 * i + 1] = points[2 * i + 1] + (-1 -minY); - } - } - - return points; - }; - - $$.math.generateUnitNgonPoints = function(sides, rotationRadians) { - - var increment = 1.0 / sides * 2 * Math.PI; - var startAngle = sides % 2 == 0 ? - Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0; -// console.log(nodeShapes["square"]); - startAngle += rotationRadians; - - var points = new Array(sides * 2); - - var currentAngle, x, y; - for (var i = 0; i < sides; i++) { - currentAngle = i * increment + startAngle; - - x = points[2 * i] = Math.cos(currentAngle);// * (1 + i/2); - y = points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2); - } - - return points; - }; - - $$.math.getRoundRectangleRadius = function(width, height) { - - // Set the default radius, unless half of width or height is smaller than default - return Math.min(width / 2, height / 2, 10); - }; - -})( cytoscape ); - -// type testing utility functions - -;(function($$){ "use strict"; - - // list of ids with other metadata assoc'd with it - $$.instances = []; - $$.instanceCounter = 0; - $$.lastInstanceTime; - - $$.registerInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - // if we have an old reg that is empty (no cy), then - var oldReg = $$.getRegistrationForInstance(instance, domElement); - if( oldReg ){ - if( !oldReg.cy ){ - oldReg.cy = instance; - oldReg.domElement = domElement; - } else { - $$.util.error('Tried to register on a pre-existing registration'); - } - - return oldReg; - - // otherwise, just make a new registration - } else { - var time = +new Date; - var suffix; - - // add a suffix in case instances collide on the same time - if( !$$.lastInstanceTime || $$.lastInstanceTime === time ){ - $$.instanceCounter = 0; - } else { - ++$$.instanceCounter; - } - $$.lastInstanceTime = time; - suffix = $$.instanceCounter; - - var id = "cy-" + time + "-" + suffix; - - // create the registration object - var registration = { - id: id, - cy: cy, - domElement: domElement, - readies: [] // list of bound ready functions before calling init - }; - - // put the registration object in the pool - $$.instances.push( registration ); - $$.instances[ id ] = registration; - - return registration; - } - }; - - $$.removeRegistrationForInstance = function(instance, domElement){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - delete $$.instances[ id ]; - $$.instances.splice(id, 1); - - } else if( $$.is.domElement(domElement) ){ - for( var i = 0; i < $$.instances.length; i++ ){ - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - delete $$.instances[ reg.id ]; - $$.instances.splice(i, 1); - i--; - } - } - } - } - - $$.getRegistrationForInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - if( instance.registered() ){ // only want it if it's registered b/c if not it has no reg'd id - cy = instance; - } - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - return $$.instances[ id ]; - - } else if( $$.is.domElement(domElement) ){ - for( var i = $$.instances.length - 1; i >= 0; i-- ){ // look backwards, since most recent is the one we want - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - return reg; - } - } - } - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - // registered extensions to cytoscape, indexed by name - var extensions = {}; - $$.extensions = extensions; - - // registered modules for extensions, indexed by name - var modules = {}; - $$.modules = modules; - - function setExtension(type, name, registrant){ - var impl = {}; - impl[name] = registrant; - - switch( type ){ - case "core": - case "collection": - $$.fn[type]( impl ); - } - - return $$.util.setMap({ - map: extensions, - keys: [ type, name ], - value: registrant - }); - } - - function getExtension(type, name){ - return $$.util.getMap({ - map: extensions, - keys: [ type, name ] - }); - } - - function setModule(type, name, moduleType, moduleName, registrant){ - return $$.util.setMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ], - value: registrant - }); - } - - function getModule(type, name, moduleType, moduleName){ - return $$.util.getMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ] - }); - } - - $$.extension = function(){ - // e.g. $$.extension("renderer", "svg") - if( arguments.length == 2 ){ - return getExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", { ... }) - else if( arguments.length == 3 ){ - return setExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse") - else if( arguments.length == 4 ){ - return getModule.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse", { ... }) - else if( arguments.length == 5 ){ - return setModule.apply(this, arguments); - } - - else { - $.error("Invalid extension access syntax"); - } - - }; - -})( cytoscape ); - -;(function($, $$){ "use strict"; - - if( !$ ){ return } // no jquery => don't need this - - // allow calls on a jQuery selector by proxying calls to $.cytoscape - // e.g. $("#foo").cytoscape(options) => $.cytoscape(options) on #foo - $.fn.cytoscape = function(opts){ - var $this = $(this); - - // get object - if( opts === "get" ){ - var reg = $$.getRegistrationForInstance( $this[0] ); - return reg.cy; - } - - // bind to ready - else if( $$.is.fn(opts) ){ - //debugger; - - var ready = opts; - var domEle = $this[0]; - var reg = $$.getRegistrationForInstance( domEle ); - - if( !reg ){ - reg = $$.registerInstance( domEle ); - } - - if( reg && reg.cy && reg.cy.ready() ){ - // already ready so just trigger now - reg.cy.trigger("ready", [], ready); - - } else { - // not yet ready, so add to readies list - - reg.readies.push( ready ); - } - - } - - // proxy to create instance - else if( $$.is.plainObject(opts) ){ - return $this.each(function(){ - var options = $.extend({}, opts, { - container: $(this)[0] - }); - - cytoscape(options); - }); - } - - // proxy a function call - else { - var domEle = $this[0]; - var rets = []; - var args = []; - for(var i = 1; i < arguments.length; i++){ - args[i - 1] = arguments[i]; - } - - $this.each(function(){ - var reg = $$.getRegistrationForInstance( domEle ); - var cy = reg.cy; - var fnName = opts; - - if( cy && $$.is.fn( cy[fnName] ) ){ - var ret = cy[fnName].apply(cy, args); - rets.push(ret); - } - }); - - // if only one instance, don't need to return array - if( rets.length === 1 ){ - rets = rets[0]; - } else if( rets.length == 0 ){ - rets = $(this); - } - - return rets; - } - - }; - - // allow access to the global cytoscape object under jquery for legacy reasons - $.cytoscape = cytoscape; - - // use short alias (cy) if not already defined - if( $.fn.cy == null && $.cy == null ){ - $.fn.cy = $.fn.cytoscape; - $.cy = $.cytoscape; - } - -})(typeof jQuery !== 'undefined' ? jQuery : null , cytoscape); - -;(function($$){ "use strict"; - - // shamelessly taken from jQuery - // https://github.com/jquery/jquery/blob/master/src/event.js - - $$.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof $$.Event) ) { - return new $$.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - $$.util.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || +new Date; - }; - - function returnFalse() { - return false; - } - function returnTrue() { - return true; - } - - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding - // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html - $$.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - // metaprogramming makes me happy - - // use this module to cherry pick functions into your prototype - // (useful for functions shared between the core and collections, for example) - - // e.g. - // $$.fn.collection({ - // foo: $$.define.foo({ /* params... */ }) - // }); - - $$.define = { - - // access data field - data: function( params ){ - var defaults = { - field: "data", - bindingEvent: "data", - allowBinding: false, - allowSetting: false, - allowGetting: false, - settingEvent: "data", - settingTriggersEvent: false, - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false, - onSet: function( self ){}, - canSet: function( self ){ return true } - }; - params = $$.util.extend({}, defaults, params); - - return function( name, value ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .data("foo", ...) - if( $$.is.string(name) ){ // set or get property - - // .data("foo") - if( p.allowGetting && value === undefined ){ // get - - var ret; - if( single ){ - ret = single._private[ p.field ][ name ]; - } - return ret; - - // .data("foo", "bar") - } else if( p.allowSetting && value !== undefined ) { // set - var valid = !p.immutableKeys[name]; - if( valid ){ - for( var i = 0, l = all.length; i < l; i++ ){ - if( p.canSet( all[i] ) ){ - all[i]._private[ p.field ][ name ] = value; - } - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - // call onSet callback - p.onSet( self ); - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - } - } - - // .data({ "foo": "bar" }) - } else if( p.allowSetting && $$.is.plainObject(name) ){ // extend - var obj = name; - var k, v; - - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - for( var i = 0, l = all.length; i < l; i++ ){ - if( p.canSet( all[i] ) ){ - all[i]._private[ p.field ][ k ] = v; - } - } - } - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - // call onSet callback - p.onSet( self ); - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - - // .data(function(){ ... }) - } else if( p.allowBinding && $$.is.fn(name) ){ // bind to event - var fn = name; - self.bind( p.bindingEvent, fn ); - - // .data() - } else if( p.allowGetting && name === undefined ){ // get whole object - var ret; - if( single ){ - ret = single._private[ p.field ]; - } - return ret; - } - - return self; // maintain chainability - }; // function - }, // data - - batchData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false - }; - var p = params = $$.util.extend({}, defaults, params); - - return function( map ){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var eles = selfIsArrayLike ? self : self._private.elements; - - if( eles.length === 0 ){ return self; } - var cy = selfIsArrayLike ? eles[0]._private.cy : self; // NB must have at least 1 ele to get cy - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - var mapData = map[id]; - - if( mapData !== undefined && mapData !== null ){ - var obj = mapData; - var k, v; - - // set the (k, v) pairs from the map - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - ele._private[ p.field ][ k ] = v; - } - } - } // if - } // for - - // update mappers if asked - var coln = new $$.Collection(cy, eles); - if( p.updateMappers ){ coln.updateMappers(); } - - coln[ p.triggerFnName ]( p.event ); - - return self; // chaining - }; - }, - - // remove data field - removeData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: false, - immutableKeys: {} // key => true if immutable - }; - params = $$.util.extend({}, defaults, params); - - return function( names ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .removeData("foo bar") - if( $$.is.string(names) ){ // then get the list of keys, and delete them - var keys = names.split(/\s+/); - var l = keys.length; - - for( var i = 0; i < l; i++ ){ // delete each non-empty key - var key = keys[i]; - if( $$.is.emptyString(key) ){ continue; } - - var valid = !p.immutableKeys[ key ]; // not valid if immutable - if( valid ){ - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - delete all[ i_a ]._private[ p.field ][ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - - // .removeData() - } else if( names === undefined ){ // then delete all keys - - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - var _privateFields = all[ i_a ]._private[ p.field ]; - - for( var key in _privateFields ){ - var validKeyToDelete = !p.immutableKeys[ key ]; - - if( validKeyToDelete ){ - delete _privateFields[ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - } - - return self; // maintain chaining - }; // function - }, // removeData - - // event function reusable stuff - event: { - regex: /(\w+)(\.\w+)?/, // regex for matching event strings (e.g. "click.namespace") - optionalTypeRegex: /(\w+)?(\.\w+)?/, - falseCallback: function(){ return false; } - }, - - // event binding - on: function( params ){ - var defaults = { - unbindSelfOnTrigger: false, - unbindAllBindersOnTrigger: false - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, data, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( $$.is.plainObject(selector) ){ // selector is actually data - callback = data; - data = selector; - selector = undefined; - } else if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - data = undefined; - selector = undefined; - } - - if( $$.is.fn(data) || data === false ){ // data is actually callback - callback = data; - data = undefined; - } - - // if there isn't a callback, we can't really do anything - // (can't speak for mapped events arg version) - if( !($$.is.fn(callback) || callback === false) && eventsIsString ){ - return self; // maintain chaining - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - if( !$$.is.fn(callback) ){ continue; } - - evts = evts.split(/\s+/); - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - - if( match ){ - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - var listener = { - callback: callback, // callback to run - data: data, // extra data in eventObj.data - delegated: selector ? true : false, // whether the evt is delegated - selector: selector, // the selector to match for delegated events - type: type, // the event type (e.g. "click") - namespace: namespace, // the event namespace (e.g. ".foo") - unbindSelfOnTrigger: p.unbindSelfOnTrigger, - unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger, - binders: all // who bound together - }; - - for( var j = 0; j < all.length; j++ ){ - all[j]._private.listeners.push( listener ); - } - } - } // for events array - } // for events map - - return self; // maintain chaining - }; // function - }, // on - - off: function( params ){ - var defaults = { - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( arguments.length === 0 ){ // then unbind all - - for( var i = 0; i < all.length; i++ ){ - all[i]._private.listeners = []; - } - - return self; // maintain chaining - } - - if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - selector = undefined; - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - evts = evts.split(/\s+/); - for( var h = 0; h < evts.length; h++ ){ - var evt = evts[h]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.optionalTypeRegex ); // [type][.namespace] - if( match ){ - var type = match[1] ? match[1] : undefined; - var namespace = match[2] ? match[2] : undefined; - - for( var i = 0; i < all.length; i++ ){ // - var listeners = all[i]._private.listeners; - - for( var j = 0; j < listeners.length; j++ ){ - var listener = listeners[j]; - var nsMatches = !namespace || namespace === listener.namespace; - var typeMatches = !type || listener.type === type; - var cbMatches = !callback || callback === listener.callback; - var listenerMatches = nsMatches && typeMatches && cbMatches; - - // delete listener if it matches - if( listenerMatches ){ - listeners.splice(j, 1); - j--; - } - } // for listeners - } // for all - } // if match - } // for events array - - } // for events map - - return self; // maintain chaining - }; // function - }, // off - - trigger: function( params ){ - var defaults = {}; - params = $$.util.extend({}, defaults, params); - - return function(events, extraParams, fnToTrigger){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var eventsIsObject = $$.is.plainObject(events); - var eventsIsEvent = $$.is.event(events); - var p = params; - var cy = this._private.cy || this; - - if( eventsIsString ){ // then make a plain event object for each event name - var evts = events.split(/\s+/); - events = []; - - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - events.push( { - type: type, - namespace: namespace - } ); - } - } else if( eventsIsObject ){ // put in length 1 array - var eventArgObj = events; - - events = [ eventArgObj ]; - } - - if( extraParams ){ - if( !$$.is.array(extraParams) ){ // make sure extra params are in an array if specified - extraParams = [ extraParams ]; - } - } else { // otherwise, we've got nothing - extraParams = []; - } - - for( var i = 0; i < events.length; i++ ){ // trigger each event in order - var evtObj = events[i]; - - for( var j = 0; j < all.length; j++ ){ // for each - var triggerer = all[j]; - var listeners = triggerer._private.listeners; - var triggererIsElement = $$.is.element(triggerer); - var bubbleUp = triggererIsElement; - - // create the event for this element from the event object - var evt; - - if( eventsIsEvent ){ // then just get the object - evt = evtObj; - - evt.cyTarget = evt.cyTarget || triggerer; - evt.cy = evt.cy || cy; - evt.namespace = evt.namespace || evtObj.namespace; - - } else { // then we have to make one - evt = new $$.Event( evtObj, { - cyTarget: triggerer, - cy: cy, - namespace: evtObj.namespace - } ); - } - - // Create a rendered position based on the passed position - if( evt.cyPosition ){ - var pos = evt.cyPosition; - var zoom = cy.zoom(); - var pan = cy.pan(); - - evt.cyRenderedPosition = { - x: pos.x * zoom + pan.x, - y: pos.y * zoom + pan.y - }; - } - - if( fnToTrigger ){ // then override the listeners list with just the one we specified - listeners = [{ - namespace: evt.namespace, - type: evt.type, - callback: fnToTrigger - }]; - } - - for( var k = 0; k < listeners.length; k++ ){ // check each listener - var lis = listeners[k]; - var nsMatches = !lis.namespace || lis.namespace === evt.namespace; - var typeMatches = lis.type === evt.type; - var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && $$.is.element(evt.cyTarget) && evt.cyTarget.is(lis.selector) ) : (true); // we're not going to validate the hierarchy; that's too expensive - var listenerMatches = nsMatches && typeMatches && targetMatches; - - if( listenerMatches ){ // then trigger it - var args = [ evt ]; - args = args.concat( extraParams ); // add extra params to args list - - if( lis.data ){ // add on data plugged into binding - evt.data = lis.data; - } else { // or clear it in case the event obj is reused - evt.data = undefined; - } - - if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener - listeners.splice(k, 1); - k--; - } - - if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders - var binders = lis.binders; - for( var l = 0; l < binders.length; l++ ){ - var binder = binders[l]; - if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it - - var binderListeners = binder._private.listeners; - for( var m = 0; m < binderListeners.length; m++ ){ - var binderListener = binderListeners[m]; - - if( binderListener === lis ){ // delete listener from list - binderListeners.splice(m, 1); - m--; - } - } - } - } - - // run the callback - var context = lis.delegated ? evt.cyTarget : triggerer; - var ret = lis.callback.apply( context, args ); - - if( ret === false || evt.isPropagationStopped() ){ - // then don't bubble - bubbleUp = false; - - if( ret === false ){ - // returning false is a shorthand for stopping propagation and preventing the def. action - evt.stopPropagation(); - evt.preventDefault(); - } - } - } // if listener matches - } // for each listener - - // bubble up event for elements - if( bubbleUp ){ - var parent = triggerer.parent(); - var hasParent = parent.length !== 0; - - if( hasParent ){ // then bubble up to parent - parent = parent[0]; - parent.trigger(evt); - } else { // otherwise, bubble up to the core - cy.trigger(evt); - } - } - - } // for each of all - } // for each event - - return self; // maintain chaining - }; // function - } // trigger - - }; // define - - -})( cytoscape ); - -;(function($$){ "use strict"; - - - $$.fn.selector = function(map, options){ - for( var name in map ){ - var fn = map[name]; - $$.Selector.prototype[ name ] = fn; - } - }; - - $$.Selector = function(onlyThisGroup, selector){ - - if( !(this instanceof $$.Selector) ){ - return new $$.Selector(onlyThisGroup, selector); - } - - if( selector === undefined && onlyThisGroup !== undefined ){ - selector = onlyThisGroup; - onlyThisGroup = undefined; - } - - var self = this; - - self._private = { - selectorText: null, - invalid: true - } - - // storage for parsed queries - // when you add something here, also add to Selector.toString() - var newQuery = function(){ - return { - classes: [], - colonSelectors: [], - data: [], - group: null, - ids: [], - meta: [], - - // fake selectors - collection: null, // a collection to match against - filter: null, // filter function - - // these are defined in the upward direction rather than down (e.g. child) - // because we need to go up in Selector.filter() - parent: null, // parent query obj - ancestor: null, // ancestor query obj - subject: null, // defines subject in compound query (subject query obj; points to self if subject) - - // use these only when subject has been defined - child: null, - descendant: null - }; - } - - if( !selector || ( $$.is.string(selector) && selector.match(/^\s*$/) ) ){ - - if( onlyThisGroup == null ){ - // ignore - self.length = 0; - } else { - self[0] = newQuery(); - self[0].group = onlyThisGroup; - self.length = 1; - } - - } else if( $$.is.element( selector ) ){ - var collection = new $$.Collection(self.cy(), [ selector ]); - - self[0] = newQuery(); - self[0].collection = collection; - self.length = 1; - - } else if( $$.is.collection( selector ) ){ - self[0] = newQuery(); - self[0].collection = selector; - self.length = 1; - - } else if( $$.is.fn( selector ) ) { - self[0] = newQuery(); - self[0].filter = selector; - self.length = 1; - - } else if( $$.is.string( selector ) ){ - - // these are the actual tokens in the query language - var metaChar = "[\\!\\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]"; // chars we need to escape in var names, etc - var variable = "(?:[\\w-]|(?:\\\\"+ metaChar +"))+"; // a variable name - var comparatorOp = "=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*="; // binary comparison op (used in data selectors) - var boolOp = "\\?|\\!|\\^"; // boolean (unary) operators (used in data selectors) - var string = '"(?:\\\\"|[^"])+"' + "|" + "'(?:\\\\'|[^'])+'"; // string literals (used in data selectors) -- doublequotes | singlequotes - var number = $$.util.regex.number; // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123 - var value = string + "|" + number; // a value literal, either a string or number - var meta = "degree|indegree|outdegree"; // allowed metadata fields (i.e. allowed functions to use from $$.Collection) - var separator = "\\s*,\\s*"; // queries are separated by commas; e.g. edge[foo = "bar"], node.someClass - var className = variable; // a class name (follows variable conventions) - var descendant = "\\s+"; - var child = "\\s+>\\s+"; - var subject = "\\$"; - var id = variable; // an element id (follows variable conventions) - - // when a token like a variable has escaped meta characters, we need to clean the backslashes out - // so that values get compared properly in Selector.filter() - var cleanMetaChars = function(str){ - return str.replace(new RegExp("\\\\(" + metaChar + ")", "g"), function(match, $1, offset, original){ - return $1; - }); - }; - - // add @ variants to comparatorOp - var ops = comparatorOp.split("|"); - for( var i = 0; i < ops.length; i++ ){ - var op = ops[i]; - comparatorOp += "|@" + op; - } - - // the current subject in the query - var currentSubject = null; - - // NOTE: add new expression syntax here to have it recognised by the parser; - // a query contains all adjacent (i.e. no separator in between) expressions; - // the current query is stored in self[i] --- you can use the reference to `this` in the populate function; - // you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward - var exprs = { - group: { - query: true, - regex: "(node|edge|\\*)", - populate: function( group ){ - this.group = group == "*" ? group : group + "s"; - } - }, - - state: { - query: true, - regex: "(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:parent|:child|:active|:inactive|:touch)", - populate: function( state ){ - this.colonSelectors.push( state ); - } - }, - - id: { - query: true, - regex: "\\#("+ id +")", - populate: function( id ){ - this.ids.push( cleanMetaChars(id) ); - } - }, - - className: { - query: true, - regex: "\\.("+ className +")", - populate: function( className ){ - this.classes.push( cleanMetaChars(className) ); - } - }, - - dataExists: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*\\]", - populate: function( variable ){ - this.data.push({ - field: cleanMetaChars(variable) - }); - } - }, - - dataCompare: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*("+ comparatorOp +")\\s*("+ value +")\\s*\\]", - populate: function( variable, comparatorOp, value ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: comparatorOp, - value: value - }); - } - }, - - dataBool: { - query: true, - regex: "\\[\\s*("+ boolOp +")\\s*("+ variable +")\\s*\\]", - populate: function( boolOp, variable ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: boolOp - }); - } - }, - - metaCompare: { - query: true, - regex: "\\[\\[\\s*("+ meta +")\\s*("+ comparatorOp +")\\s*("+ number +")\\s*\\]\\]", - populate: function( meta, comparatorOp, number ){ - this.meta.push({ - field: cleanMetaChars(meta), - operator: comparatorOp, - value: number - }); - } - }, - - nextQuery: { - separator: true, - regex: separator, - populate: function(){ - // go on to next query - self[++i] = newQuery(); - currentSubject = null; - } - }, - - child: { - separator: true, - regex: child, - populate: function(){ - // this query is the parent of the following query - var childQuery = newQuery(); - childQuery.parent = this; - childQuery.subject = currentSubject; - - // we're now populating the child query with expressions that follow - self[i] = childQuery; - } - }, - - descendant: { - separator: true, - regex: descendant, - populate: function(){ - // this query is the ancestor of the following query - var descendantQuery = newQuery(); - descendantQuery.ancestor = this; - descendantQuery.subject = currentSubject; - - // we're now populating the descendant query with expressions that follow - self[i] = descendantQuery; - } - }, - - subject: { - modifier: true, - regex: subject, - populate: function(){ - if( currentSubject != null && this.subject != this ){ - $$.util.error("Redefinition of subject in selector `" + selector + "`"); - return false; - } - - currentSubject = this; - this.subject = this; - }, - - } - }; - - var j = 0; - for( var name in exprs ){ - exprs[j] = exprs[name]; - exprs[j].name = name; - - j++; - } - exprs.length = j; - - self._private.selectorText = selector; - var remaining = selector; - var i = 0; - - // of all the expressions, find the first match in the remaining text - var consumeExpr = function( expectation ){ - var expr; - var match; - var name; - - for( var j = 0; j < exprs.length; j++ ){ - var e = exprs[j]; - var n = e.name; - - // ignore this expression if it doesn't meet the expectation function - if( $$.is.fn( expectation ) && !expectation(n, e) ){ continue } - - var m = remaining.match(new RegExp( "^" + e.regex )); - - if( m != null ){ - match = m; - expr = e; - name = n; - - var consumed = m[0]; - remaining = remaining.substring( consumed.length ); - - break; // we've consumed one expr, so we can return now - } - } - - return { - expr: expr, - match: match, - name: name - }; - }; - - // consume all leading whitespace - var consumeWhitespace = function(){ - var match = remaining.match(/^\s+/); - - if( match ){ - var consumed = match[0]; - remaining = remaining.substring( consumed.length ); - } - }; - - self[0] = newQuery(); // get started - - consumeWhitespace(); // get rid of leading whitespace - for(;;){ - var check = consumeExpr(); - - if( check.expr == null ){ - $$.util.error("The selector `"+ selector +"`is invalid"); - return; - } else { - var args = []; - for(var j = 1; j < check.match.length; j++){ - args.push( check.match[j] ); - } - - // let the token populate the selector object (i.e. in self[i]) - var ret = check.expr.populate.apply( self[i], args ); - - if( ret === false ){ return } // exit if population failed - } - - // we're done when there's nothing left to parse - if( remaining.match(/^\s*$/) ){ - break; - } - } - - self.length = i + 1; - - // adjust references for subject - for(j = 0; j < self.length; j++){ - var query = self[j]; - - if( query.subject != null ){ - // go up the tree until we reach the subject - for(;;){ - if( query.subject == query ){ break } // done if subject is self - - if( query.parent != null ){ // swap parent/child reference - var parent = query.parent; - var child = query; - - child.parent = null; - parent.child = child; - - query = parent; // go up the tree - } else if( query.ancestor != null ){ // swap ancestor/descendant - var ancestor = query.ancestor; - var descendant = query; - - descendant.ancestor = null; - ancestor.descendant = descendant; - - query = ancestor; // go up the tree - } else { - $$.util.error("When adjusting references for the selector `"+ query +"`, neither parent nor ancestor was found"); - break; - } - } // for - - self[j] = query.subject; // subject should be the root query - } // if - } // for - - // make sure for each query that the subject group matches the implicit group if any - if( onlyThisGroup != null ){ - for(var j = 0; j < self.length; j++){ - if( self[j].group != null && self[j].group != onlyThisGroup ){ - $$.util.error("Group `"+ self[j].group +"` conflicts with implicit group `"+ onlyThisGroup +"` in selector `"+ selector +"`"); - return; - } - - self[j].group = onlyThisGroup; // set to implicit group - } - } - - } else { - $$.util.error("A selector must be created from a string; found " + selector); - return; - } - - self._private.invalid = false; - - }; - - $$.selfn = $$.Selector.prototype; - - $$.selfn.size = function(){ - return this.length; - }; - - $$.selfn.eq = function(i){ - return this[i]; - }; - - // get elements from the core and then filter them - $$.selfn.find = function(){ - // TODO impl if we decide to use a DB for storing elements - }; - - // filter an existing collection - $$.selfn.filter = function(collection, addLiveFunction){ - var self = this; - var cy = collection.cy(); - - // don't bother trying if it's invalid - if( self._private.invalid ){ - return new $$.Collection( cy ); - } - - var queryMatches = function(query, element){ - // check group - if( query.group != null && query.group != "*" && query.group != element._private.group ){ - return false; - } - - // check colon selectors - var allColonSelectorsMatch = true; - for(var k = 0; k < query.colonSelectors.length; k++){ - var sel = query.colonSelectors[k]; - var renderer = cy.renderer(); // TODO remove reference after refactoring - - switch(sel){ - case ":selected": - allColonSelectorsMatch = element.selected(); - break; - case ":unselected": - allColonSelectorsMatch = !element.selected(); - break; - case ":selectable": - allColonSelectorsMatch = element.selectable(); - break; - case ":unselectable": - allColonSelectorsMatch = !element.selectable(); - break; - case ":locked": - allColonSelectorsMatch = element.locked(); - break; - case ":unlocked": - allColonSelectorsMatch = !element.locked(); - break; - case ":visible": - allColonSelectorsMatch = element.visible(); - break; - case ":hidden": - allColonSelectorsMatch = !element.visible(); - break; - case ":transparent": - allColonSelectorsMatch = !element.transparent(); - break; - case ":grabbed": - allColonSelectorsMatch = element.grabbed(); - break; - case ":free": - allColonSelectorsMatch = !element.grabbed(); - break; - case ":removed": - allColonSelectorsMatch = element.removed(); - break; - case ":inside": - allColonSelectorsMatch = !element.removed(); - break; - case ":grabbable": - allColonSelectorsMatch = element.grabbable(); - break; - case ":ungrabbable": - allColonSelectorsMatch = !element.grabbable(); - break; - case ":animated": - allColonSelectorsMatch = element.animated(); - break; - case ":unanimated": - allColonSelectorsMatch = !element.animated(); - break; - case ":parent": - allColonSelectorsMatch = element.children().nonempty(); - break; - case ":child": - allColonSelectorsMatch = element.parent().nonempty(); - break; - case ":active": - allColonSelectorsMatch = element.active(); - break; - case ":inactive": - allColonSelectorsMatch = !element.active(); - break; - case ":touch": - allColonSelectorsMatch = window && document && (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); - break; - } - - if( !allColonSelectorsMatch ) break; - } - if( !allColonSelectorsMatch ) return false; - - // check id - var allIdsMatch = true; - for(var k = 0; k < query.ids.length; k++){ - var id = query.ids[k]; - var actualId = element._private.data.id; - - allIdsMatch = allIdsMatch && (id == actualId); - - if( !allIdsMatch ) break; - } - if( !allIdsMatch ) return false; - - // check classes - var allClassesMatch = true; - for(var k = 0; k < query.classes.length; k++){ - var cls = query.classes[k]; - - allClassesMatch = allClassesMatch && element.hasClass(cls); - - if( !allClassesMatch ) break; - } - if( !allClassesMatch ) return false; - - // generic checking for data/metadata - var operandsMatch = function(params){ - var allDataMatches = true; - for(var k = 0; k < query[params.name].length; k++){ - var data = query[params.name][k]; - var operator = data.operator; - var value = data.value; - var field = data.field; - var matches; - - if( operator != null && value != null ){ - - var fieldStr = "" + params.fieldValue(field); - var valStr = "" + eval(value); - - var caseInsensitive = false; - if( operator.charAt(0) == "@" ){ - fieldStr = fieldStr.toLowerCase(); - valStr = valStr.toLowerCase(); - - operator = operator.substring(1); - caseInsensitive = true; - } - - if( operator == "=" ){ - operator = "=="; - } - - switch(operator){ - case "*=": - matches = fieldStr.search(valStr) >= 0; - break; - case "$=": - matches = new RegExp(valStr + "$").exec(fieldStr) != null; - break; - case "^=": - matches = new RegExp("^" + valStr).exec(fieldStr) != null; - break; - default: - // if we're doing a case insensitive comparison, then we're using a STRING comparison - // even if we're comparing numbers - if( caseInsensitive ){ - // eval with lower case strings - var expr = "fieldStr " + operator + " valStr"; - matches = eval(expr); - } else { - // just eval as normal - var expr = params.fieldRef(field) + " " + operator + " " + value; - matches = eval(expr); - } - - } - } else if( operator != null ){ - switch(operator){ - case "?": - matches = params.fieldTruthy(field); - break; - case "!": - matches = !params.fieldTruthy(field); - break; - case "^": - matches = params.fieldUndefined(field); - break; - } - } else { - matches = !params.fieldUndefined(field); - } - - if( !matches ){ - allDataMatches = false; - break; - } - } // for - - return allDataMatches; - }; // operandsMatch - - // check data matches - var allDataMatches = operandsMatch({ - name: "data", - fieldValue: function(field){ - return element._private.data[field]; - }, - fieldRef: function(field){ - return "element._private.data." + field; - }, - fieldUndefined: function(field){ - return element._private.data[field] === undefined; - }, - fieldTruthy: function(field){ - if( element._private.data[field] ){ - return true; - } - return false; - } - }); - - if( !allDataMatches ){ - return false; - } - - // check metadata matches - var allMetaMatches = operandsMatch({ - name: "meta", - fieldValue: function(field){ - return element[field](); - }, - fieldRef: function(field){ - return "element." + field + "()"; - }, - fieldUndefined: function(field){ - return element[field]() == undefined; - }, - fieldTruthy: function(field){ - if( element[field]() ){ - return true; - } - return false; - } - }); - - if( !allMetaMatches ){ - return false; - } - - // check collection - if( query.collection != null ){ - var matchesAny = query.collection._private.ids[ element.id() ] != null; - - if( !matchesAny ){ - return false; - } - } - - // check filter function - if( query.filter != null && element.collection().filter( query.filter ).size() == 0 ){ - return false; - } - - - // check parent/child relations - var confirmRelations = function( query, elements ){ - if( query != null ){ - var matches = false; - elements = elements(); // make elements functional so we save cycles if query == null - - // query must match for at least one element (may be recursive) - for(var i = 0; i < elements.size(); i++){ - if( queryMatches( query, elements.eq(i) ) ){ - matches = true; - break; - } - } - - return matches; - } else { - return true; - } - }; - - if (! confirmRelations(query.parent, function(){ - return element.parent() - }) ){ return false } - - if (! confirmRelations(query.ancestor, function(){ - return element.parents() - }) ){ return false } - - if (! confirmRelations(query.child, function(){ - return element.children() - }) ){ return false } - - if (! confirmRelations(query.descendant, function(){ - return element.descendants() - }) ){ return false } - - // we've reached the end, so we've matched everything for this query - return true; - }; // queryMatches - - var selectorFunction = function(i, element){ - for(var j = 0; j < self.length; j++){ - var query = self[j]; - - if( queryMatches(query, element) ){ - return true; - } - } - - return false; - }; - - if( self._private.selectorText == null ){ - selectorFunction = function(){ return true; }; - } - - var filteredCollection = collection.filter( selectorFunction ); - - return filteredCollection; - }; // filter - - // ith query to string - $$.selfn.toString = $$.selfn.selector = function(){ - - var str = ""; - - var clean = function(obj){ - if( $$.is.string(obj) ){ - return obj; - } - return ""; - }; - - var queryToString = function(query){ - var str = ""; - - var group = clean(query.group); - str += group.substring(0, group.length - 1); - - for(var j = 0; j < query.data.length; j++){ - var data = query.data[j]; - str += "[" + data.field + clean(data.operator) + clean(data.value) + "]" - } - - for(var j = 0; j < query.meta.length; j++){ - var meta = query.meta[j]; - str += "{" + meta.field + clean(meta.operator) + clean(meta.value) + "}" - } - - for(var j = 0; j < query.colonSelectors.length; j++){ - var sel = query.colonSelectors[i]; - str += sel; - } - - for(var j = 0; j < query.ids.length; j++){ - var sel = "#" + query.ids[i]; - str += sel; - } - - for(var j = 0; j < query.classes.length; j++){ - var sel = "." + query.classes[i]; - str += sel; - } - - if( query.parent != null ){ - str = queryToString( query.parent ) + " > " + str; - } - - if( query.ancestor != null ){ - str = queryToString( query.ancestor ) + " " + str; - } - - if( query.child != null ){ - str += " > " + queryToString( query.child ); - } - - if( query.descendant != null ){ - str += " " + queryToString( query.descendant ); - } - - return str; - }; - - for(var i = 0; i < this.length; i++){ - var query = this[i]; - - str += queryToString( query ); - - if( this.length > 1 && i < this.length - 1 ){ - str += ", "; - } - } - - return str; - }; - -})( cytoscape ); - -;(function($$, window){ "use strict"; - - var isTouch = $$.is.touch(); - - $$.Style = function( cy ){ - - if( !(this instanceof $$.Style) ){ - return new $$.Style(cy); - } - - if( !$$.is.core(cy) ){ - $$.util.error("A style must have a core reference"); - return; - } - - this._private = { - cy: cy, - coreStyle: {} - }; - - this.length = 0; - - this.addDefaultStylesheet(); - }; - - // nice-to-have aliases - $$.style = $$.Style; - $$.styfn = $$.Style.prototype; - - // define functions in the Style prototype - $$.fn.style = function( fnMap, options ){ - for( var fnName in fnMap ){ - var fn = fnMap[ fnName ]; - $$.Style.prototype = fn; - } - }; - - // a dummy stylesheet object that doesn't need a reference to the core - $$.stylesheet = $$.Stylesheet = function(){ - if( !(this instanceof $$.Stylesheet) ){ - return new $$.Stylesheet(); - } - - this.length = 0; - }; - - // just store the selector to be parsed later - $$.Stylesheet.prototype.selector = function( selector ){ - var i = this.length++; - - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // just store the property to be parsed later - $$.Stylesheet.prototype.css = function( name, value ){ - var i = this.length - 1; - - if( $$.is.string(name) ){ - this[i].properties.push({ - name: name, - value: value - }); - } else if( $$.is.plainObject(name) ){ - var map = name; - - for( var j = 0; j < $$.style.properties.length; j++ ){ - var prop = $$.style.properties[j]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ // also try camel case name - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - var name = prop.name; - var value = mapVal; - - this[i].properties.push({ - name: name, - value: value - }); - } - } - } - - return this; // chaining - }; - - $$.style.applyFromString = function( style, string ){ - var remaining = "" + string; - var selAndBlockStr; - var blockRem; - var propAndValStr; - - // remove comments from the style string - remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, ""); - - function removeSelAndBlockFromRemaining(){ - // remove the parsed selector and block from the remaining text to parse - if( remaining.length > selAndBlockStr.length ){ - remaining = remaining.substr( selAndBlockStr.length ); - } else { - remaining = ""; - } - } - - function removePropAndValFromRem(){ - // remove the parsed property and value from the remaining block text to parse - if( blockRem.length > propAndValStr.length ){ - blockRem = blockRem.substr( propAndValStr.length ); - } else { - blockRem = ""; - } - } - - while(true){ - var nothingLeftToParse = remaining.match(/^\s*$/); - if( nothingLeftToParse ){ break; } - - var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); - - if( !selAndBlock ){ - $$.util.error("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: " + remaining); - break; - } - - selAndBlockStr = selAndBlock[0]; - - // parse the selector - var selectorStr = selAndBlock[1]; - var selector = new $$.Selector( selectorStr ); - if( selector._private.invalid ){ - $$.util.error("Skipping parsing of block: Invalid selector found in string stylesheet: " + selectorStr); - - // skip this selector and block - removeSelAndBlockFromRemaining(); - continue; - } - - // parse the block of properties and values - var blockStr = selAndBlock[2]; - var invalidBlock = false; - blockRem = blockStr; - var props = []; - - while(true){ - var nothingLeftToParse = blockRem.match(/^\s*$/); - if( nothingLeftToParse ){ break; } - - var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/); - - if( !propAndVal ){ - $$.util.error("Skipping parsing of block: Invalid formatting of style property and value definitions found in:" + blockStr); - invalidBlock = true; - break; - } - - propAndValStr = propAndVal[0]; - var propStr = propAndVal[1]; - var valStr = propAndVal[2]; - - var prop = $$.style.properties[ propStr ]; - if( !prop ){ - $$.util.error("Skipping property: Invalid property name in: " + propAndValStr); - - // skip this property in the block - removePropAndValFromRem(); - continue; - } - - var parsedProp = style.parse( propStr, valStr ); - - if( !parsedProp ){ - $$.util.error("Skipping property: Invalid property definition in: " + propAndValStr); - - // skip this property in the block - removePropAndValFromRem(); - continue; - } - - props.push({ - name: propStr, - val: valStr - }); - removePropAndValFromRem(); - } - - if( invalidBlock ){ - removeSelAndBlockFromRemaining(); - break; - } - - // put the parsed block in the style - style.selector( selectorStr ); - for( var i = 0; i < props.length; i++ ){ - var prop = props[i]; - style.css( prop.name, prop.val ); - } - - removeSelAndBlockFromRemaining(); - } - - return style; - }; - - $$.style.fromString = function( cy, string ){ - var style = new $$.Style(cy); - - $$.style.applyFromString( style, string ); - - return style; - }; - - $$.styfn.fromString = function( string ){ - var style = this; - - style.resetToDefault(); - - $$.style.applyFromString( style, string ); - - return style; - }; - - $$.style.applyFromJson = function( style, json ){ - for( var i = 0; i < json.length; i++ ){ - var context = json[i]; - var selector = context.selector; - var props = context.css; - - style.selector(selector); // apply selector - - for( var name in props ){ - var value = props[name]; - - style.css( name, value ); // apply property - } - } - - return style; - }; - - // static function - $$.style.fromJson = function( cy, json ){ - var style = new $$.Style(cy); - - $$.style.applyFromJson( style, json ); - - return style; - }; - - $$.styfn.fromJson = function( json ){ - var style = this; - - style.resetToDefault(); - - $$.style.applyFromJson( style, json ); - - return style; - }; - - // get json from style api - $$.styfn.json = function(){ - var json = []; - - for( var i = 0; i < this.length; i++ ){ - var cxt = this[i]; - var selector = cxt.selector; - var props = cxt.properties; - var css = {}; - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - css[ prop.name ] = prop.strValue; - } - - json.push({ - selector: !selector ? "core" : selector.toString(), - css: css - }); - } - - return json; - }; - - // generate a real style object from the dummy stylesheet - $$.Stylesheet.prototype.generateStyle = function( cy ){ - var style = new $$.Style(cy); - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - - return style; - }; - - $$.Stylesheet.prototype.assignToStyle = function( style, addDefaultStylesheet ){ - style.clear(); - - if( addDefaultStylesheet || addDefaultStylesheet === undefined ){ - style.addDefaultStylesheet(); - } - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - }; - - (function(){ - var number = $$.util.regex.number; - var rgba = $$.util.regex.rgbaNoBackRefs; - var hsla = $$.util.regex.hslaNoBackRefs; - var hex3 = $$.util.regex.hex3; - var hex6 = $$.util.regex.hex6; - var data = function( prefix ){ return "^" + prefix + "\\s*\\(\\s*([\\w\\.]+)\\s*\\)$" }; - var mapData = function( prefix ){ return "^" + prefix + "\\s*\\(([\\w\\.]+)\\s*\\,\\s*(" + number + ")\\s*\\,\\s*(" + number + ")\\s*,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\s*\\,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\)$" }; - - // each visual style property has a type and needs to be validated according to it - $$.style.types = { - percent: { number: true, min: 0, max: 100, units: "%" }, - zeroOneNumber: { number: true, min: 0, max: 1, unitless: true }, - nonNegativeInt: { number: true, min: 0, integer: true, unitless: true }, - size: { number: true, min: 0, enums: ["auto"] }, - bgSize: { number: true, min: 0, allowPercent: true }, - color: { color: true }, - lineStyle: { enums: ["solid", "dotted", "dashed"] }, - curveStyle: { enums: ["bundled", "bezier"] }, - fontFamily: { regex: "^([\\w- ]+(?:\\s*,\\s*[\\w- ]+)*)$" }, - fontVariant: { enums: ["small-caps", "normal"] }, - fontStyle: { enums: ["italic", "normal", "oblique"] }, - fontWeight: { enums: ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "800", "900", 100, 200, 300, 400, 500, 600, 700, 800, 900] }, - textDecoration: { enums: ["none", "underline", "overline", "line-through"] }, - textTransform: { enums: ["none", "capitalize", "uppercase", "lowercase"] }, - nodeShape: { enums: ["rectangle", "roundrectangle", "ellipse", "triangle", - "square", "pentagon", "hexagon", "heptagon", "octagon", "star"] }, - arrowShape: { enums: ["tee", "triangle", "square", "circle", "diamond", "none"] }, - display: { enums: ["element", "none"] }, - visibility: { enums: ["hidden", "visible"] }, - valign: { enums: ["top", "center", "bottom"] }, - halign: { enums: ["left", "center", "right"] }, - positionx: { enums: ["left", "center", "right"], number: true, allowPercent: true }, - positiony: { enums: ["top", "center", "bottom"], number: true, allowPercent: true }, - bgRepeat: { enums: ["repeat", "repeat-x", "repeat-y", "no-repeat"] }, - cursor: { enums: ["auto", "crosshair", "default", "e-resize", "n-resize", "ne-resize", "nw-resize", "pointer", "progress", "s-resize", "sw-resize", "text", "w-resize", "wait", "grab", "grabbing"] }, - text: { string: true }, - data: { mapping: true, regex: data("data") }, - layoutData: { mapping: true, regex: data("layoutData") }, - mapData: { mapping: true, regex: mapData("mapData") }, - mapLayoutData: { mapping: true, regex: mapData("mapLayoutData") }, - url: { regex: "^url\\s*\\(\\s*([^\\s]+)\\s*\\s*\\)|none|(.+)$" } - }; - - // define visual style properties - var t = $$.style.types; - $$.style.properties = [ - // these are for elements - { name: "cursor", type: t.cursor }, - { name: "text-valign", type: t.valign }, - { name: "text-halign", type: t.halign }, - { name: "color", type: t.color }, - { name: "content", type: t.text }, - { name: "text-outline-color", type: t.color }, - { name: "text-outline-width", type: t.size }, - { name: "text-outline-opacity", type: t.zeroOneNumber }, - { name: "text-opacity", type: t.zeroOneNumber }, - { name: "text-decoration", type: t.textDecoration }, - { name: "text-transform", type: t.textTransform }, - { name: "font-family", type: t.fontFamily }, - { name: "font-style", type: t.fontStyle }, - { name: "font-variant", type: t.fontVariant }, - { name: "font-weight", type: t.fontWeight }, - { name: "font-size", type: t.size }, - { name: "min-zoomed-font-size", type: t.size }, - { name: "display", type: t.display }, - { name: "visibility", type: t.visibility }, - { name: "opacity", type: t.zeroOneNumber }, - { name: "z-index", type: t.nonNegativeInt }, - { name: "overlay-padding", type: t.size }, - { name: "overlay-color", type: t.color }, - { name: "overlay-opacity", type: t.zeroOneNumber }, - - // these are just for nodes - { name: "background-color", type: t.color }, - { name: "background-opacity", type: t.zeroOneNumber }, - { name: "background-image", type: t.url }, - { name: "background-position-x", type: t.positionx }, - { name: "background-position-y", type: t.positiony }, - { name: "background-repeat", type: t.bgRepeat }, - { name: "background-size-x", type: t.bgSize }, - { name: "background-size-y", type: t.bgSize }, - { name: "pie-1-background-color", type: t.color }, - { name: "pie-2-background-color", type: t.color }, - { name: "pie-3-background-color", type: t.color }, - { name: "pie-4-background-color", type: t.color }, - { name: "pie-5-background-color", type: t.color }, - { name: "pie-6-background-color", type: t.color }, - { name: "pie-7-background-color", type: t.color }, - { name: "pie-8-background-color", type: t.color }, - { name: "pie-9-background-color", type: t.color }, - { name: "pie-10-background-color", type: t.color }, - { name: "pie-11-background-color", type: t.color }, - { name: "pie-12-background-color", type: t.color }, - { name: "pie-13-background-color", type: t.color }, - { name: "pie-14-background-color", type: t.color }, - { name: "pie-15-background-color", type: t.color }, - { name: "pie-16-background-color", type: t.color }, - { name: "pie-1-background-size", type: t.percent }, - { name: "pie-2-background-size", type: t.percent }, - { name: "pie-3-background-size", type: t.percent }, - { name: "pie-4-background-size", type: t.percent }, - { name: "pie-5-background-size", type: t.percent }, - { name: "pie-6-background-size", type: t.percent }, - { name: "pie-7-background-size", type: t.percent }, - { name: "pie-8-background-size", type: t.percent }, - { name: "pie-9-background-size", type: t.percent }, - { name: "pie-10-background-size", type: t.percent }, - { name: "pie-11-background-size", type: t.percent }, - { name: "pie-12-background-size", type: t.percent }, - { name: "pie-13-background-size", type: t.percent }, - { name: "pie-14-background-size", type: t.percent }, - { name: "pie-15-background-size", type: t.percent }, - { name: "pie-16-background-size", type: t.percent }, - { name: "border-color", type: t.color }, - { name: "border-opacity", type: t.zeroOneNumber }, - { name: "border-width", type: t.size }, - { name: "border-style", type: t.lineStyle }, - { name: "height", type: t.size }, - { name: "width", type: t.size }, - { name: "padding-left", type: t.size }, - { name: "padding-right", type: t.size }, - { name: "padding-top", type: t.size }, - { name: "padding-bottom", type: t.size }, - { name: "shape", type: t.nodeShape }, - - // these are just for edges - { name: "source-arrow-shape", type: t.arrowShape }, - { name: "target-arrow-shape", type: t.arrowShape }, - { name: "source-arrow-color", type: t.color }, - { name: "target-arrow-color", type: t.color }, - { name: "line-style", type: t.lineStyle }, - { name: "line-color", type: t.color }, - { name: "control-point-step-size", type: t.size }, - { name: "curve-style", type: t.curveStyle }, - - // these are just for the core - { name: "selection-box-color", type: t.color }, - { name: "selection-box-opacity", type: t.zeroOneNumber }, - { name: "selection-box-border-color", type: t.color }, - { name: "selection-box-border-width", type: t.size }, - { name: "panning-cursor", type: t.cursor }, - { name: "active-bg-color", type: t.color }, - { name: "active-bg-opacity", type: t.zeroOneNumber }, - { name: "active-bg-size", type: t.size } - ]; - - // allow access of properties by name ( e.g. $$.style.properties.height ) - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var prop = props[i]; - - props[ prop.name ] = prop; // allow lookup by name - } - - // because the pie properties are numbered, give access to a constant N (for renderer use) - $$.style.pieBackgroundN = 16; - })(); - - // adds the default stylesheet to the current style - $$.styfn.addDefaultStylesheet = function(){ - // to be nice, we build font related style properties from the core container - // so that cytoscape matches the style of its container by default - // - // unfortunately, this doesn't seem work consistently and can grab the default stylesheet values - // instead of the developer's values so let's just make it explicit for the dev for now - // - // delaying the read of these val's is not an opt'n: that would delay init'l load time - var fontFamily = "Helvetica" || this.containerPropertyAsString("font-family") || "sans-serif"; - var fontStyle = "normal" || this.containerPropertyAsString("font-style") || "normal"; - var fontVariant = "normal" || this.containerPropertyAsString("font-variant") || "normal"; - var fontWeight = "normal" || this.containerPropertyAsString("font-weight") || "normal"; - var color = "#000" || this.containerPropertyAsString("color") || "#000"; - var textTransform = "none" || this.containerPropertyAsString("text-transform") || "none"; - var textDecoration = "none" || this.containerPropertyAsString("text-decoration") || "none"; - var fontSize = 16 || this.containerPropertyAsString("font-size") || 16; - - // fill the style with the default stylesheet - this - .selector("node, edge") // common properties - .css({ - "cursor": "default", - "text-valign": "top", - "text-halign": "center", - "color": color, - "text-outline-color": "#000", - "text-outline-width": 0, - "text-outline-opacity": 1, - "text-opacity": 1, - "text-decoration": "none", - "text-transform": textTransform, - "font-family": fontFamily, - "font-style": fontStyle, - "font-variant": fontVariant, - "font-weight": fontWeight, - "font-size": fontSize, - "min-zoomed-font-size": 0, - "visibility": "visible", - "display": "element", - "opacity": 1, - "z-index": 0, - "content": "", - "overlay-opacity": 0, - "overlay-color": "#000", - "overlay-padding": 10, - - // node props - "background-color": "#888", - "background-opacity": 1, - "background-image": "none", - "border-color": "#000", - "border-opacity": 1, - "border-width": 0, - "border-style": "solid", - "height": 30, - "width": 30, - "padding-top": 0, - "padding-bottom": 0, - "padding-left": 0, - "padding-right": 0, - "shape": "ellipse", - "pie-1-background-color": "black", - "pie-1-background-size": "0%", - "pie-2-background-color": "black", - "pie-2-background-size": "0%", - "pie-3-background-color": "black", - "pie-3-background-size": "0%", - "pie-4-background-color": "black", - "pie-4-background-size": "0%", - "pie-5-background-color": "black", - "pie-5-background-size": "0%", - "pie-6-background-color": "black", - "pie-6-background-size": "0%", - "pie-7-background-color": "black", - "pie-7-background-size": "0%", - "pie-8-background-color": "black", - "pie-8-background-size": "0%", - "pie-9-background-color": "black", - "pie-9-background-size": "0%", - "pie-10-background-color": "black", - "pie-10-background-size": "0%", - "pie-11-background-color": "black", - "pie-11-background-size": "0%", - "pie-12-background-color": "black", - "pie-12-background-size": "0%", - "pie-13-background-color": "black", - "pie-13-background-size": "0%", - "pie-14-background-color": "black", - "pie-14-background-size": "0%", - "pie-15-background-color": "black", - "pie-15-background-size": "0%", - "pie-16-background-color": "black", - "pie-16-background-size": "0%", - - // edge props - "source-arrow-shape": "none", - "target-arrow-shape": "none", - "source-arrow-color": "#bbb", - "target-arrow-color": "#bbb", - "line-style": "solid", - "line-color": "#bbb", - "control-point-step-size": 40, - "curve-style": "bezier" - }) - .selector("$node > node") // compound (parent) node properties - .css({ - "width": "auto", - "height": "auto", - "shape": "rectangle", - "background-opacity": 0.5, - "padding-top": 10, - "padding-right": 10, - "padding-left": 10, - "padding-bottom": 10 - }) - .selector("edge") // just edge properties - .css({ - "width": 1, - }) - .selector(":active") - .css({ - "overlay-color": "black", - "overlay-padding": 10, - "overlay-opacity": 0.25 - }) - .selector("core") // just core properties - .css({ - "selection-box-color": "#ddd", - "selection-box-opacity": 0.65, - "selection-box-border-color": "#aaa", - "selection-box-border-width": 1, - "panning-cursor": "grabbing", - "active-bg-color": "black", - "active-bg-opacity": 0.15, - "active-bg-size": isTouch ? 40 : 15 - }) - ; - }; - - // remove all contexts - $$.styfn.clear = function(){ - this._private.newStyle = true; - - for( var i = 0; i < this.length; i++ ){ - delete this[i]; - } - this.length = 0; - - return this; // chaining - }; - - $$.styfn.resetToDefault = function(){ - this.clear(); - this.addDefaultStylesheet(); - - return this; - }; - - // builds a style object for the "core" selector - $$.styfn.core = function(){ - return this._private.coreStyle; - }; - - // parse a property; return null on invalid; return parsed property otherwise - // fields : - // - name : the name of the property - // - value : the parsed, native-typed value of the property - // - strValue : a string value that represents the property value in valid css - // - bypass : true iff the property is a bypass property - $$.styfn.parse = function( name, value, propIsBypass ){ - - name = $$.util.camel2dash( name ); // make sure the property name is in dash form (e.g. "property-name" not "propertyName") - var property = $$.style.properties[ name ]; - var passedValue = value; - - if( !property ){ return null; } // return null on property of unknown name - if( value === undefined || value === null ){ return null; } // can't assign null - - var valueIsString = $$.is.string(value); - if( valueIsString ){ // trim the value to make parsing easier - value = $$.util.trim( value ); - } - - var type = property.type; - if( !type ){ return null; } // no type, no luck - - // check if bypass is null or empty string (i.e. indication to delete bypass property) - if( propIsBypass && (value === "" || value === null) ){ - return { - name: name, - value: value, - bypass: true, - deleteBypass: true - }; - } - - // check if value is mapped - var data, mapData, layoutData, mapLayoutData; - if( !valueIsString ){ - // then don't bother to do the expensive regex checks - - } else if( - ( data = new RegExp( $$.style.types.data.regex ).exec( value ) ) || - ( layoutData = new RegExp( $$.style.types.layoutData.regex ).exec( value ) ) - ){ - var isLayout = layoutData !== undefined; - data = data || layoutData; - - return { - name: name, - value: data, - strValue: value, - mapped: isLayout ? $$.style.types.layoutData : $$.style.types.data, - field: data[1], - bypass: propIsBypass - }; - - } else if( - ( mapData = new RegExp( $$.style.types.mapData.regex ).exec( value ) ) || - ( mapLayoutData = new RegExp( $$.style.types.mapLayoutData.regex ).exec( value ) ) - ){ - var isLayout = mapLayoutData !== undefined; - mapData = mapData || mapLayoutData; - - // we can map only if the type is a colour or a number - if( !(type.color || type.number) ){ return false; } - - var valueMin = this.parse( name, mapData[4]); // parse to validate - if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped - - var valueMax = this.parse( name, mapData[5]); // parse to validate - if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped - - // check if valueMin and valueMax are the same - if( valueMin.value === valueMax.value ){ - return false; // can't make much of a mapper without a range - - } else if( type.color ){ - var c1 = valueMin.value; - var c2 = valueMax.value; - - var same = c1[0] === c2[0] // red - && c1[1] === c2[1] // green - && c1[2] === c2[2] // blue - && ( // optional alpha - c1[3] === c2[3] // same alpha outright - || ( - (c1[3] == null || c1[3] === 1) // full opacity for colour 1? - && - (c2[3] == null || c2[3] === 1) // full opacity for colour 2? - ) - ) - ; - - if( same ){ return false; } // can't make a mapper without a range - } - - return { - name: name, - value: mapData, - strValue: value, - mapped: isLayout ? $$.style.types.mapLayoutData : $$.style.types.mapData, - field: mapData[1], - fieldMin: parseFloat( mapData[2] ), // min & max are numeric - fieldMax: parseFloat( mapData[3] ), - valueMin: valueMin.value, - valueMax: valueMax.value, - bypass: propIsBypass - }; - } - - // check the type and return the appropriate object - if( type.number ){ - var units; - var implicitUnit = "px"; // not set => px - - if( type.units ){ // use specified units if set - units = type.units; - } - - if( !type.unitless ){ - if( valueIsString ){ - var unitsRegex = "px|em" + (type.allowPercent ? "|\\%" : ""); - if( units ){ unitsRegex = units; } // only allow explicit units if so set - var match = value.match( "^(" + $$.util.regex.number + ")(" + unitsRegex + ")?" + "$" ); - - if( match ){ - value = match[1]; - units = match[2] || implicitUnit; - } - - } else if( !units ) { - units = implicitUnit; // implicitly px if unspecified - } - } - - value = parseFloat( value ); - - // if not a number and enums not allowed, then the value is invalid - if( isNaN(value) && type.enums === undefined ){ - return null; - } - - // check if this number type also accepts special keywords in place of numbers - // (i.e. `left`, `auto`, etc) - if( isNaN(value) && type.enums !== undefined ){ - value = passedValue; - - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - return null; // failed on enum after failing on number - } - - // check if value must be an integer - if( type.integer && !$$.is.integer(value) ){ - return null; - } - - // check value is within range - if( (type.min !== undefined && value < type.min) - || (type.max !== undefined && value > type.max) - ){ - return null; - } - - var ret = { - name: name, - value: value, - strValue: "" + value + (units ? units : ""), - units: units, - bypass: propIsBypass, - pxValue: type.unitless || units === "%" ? - undefined - : - ( units === "px" || !units ? (value) : (this.getEmSizeInPixels() * value) ) - }; - - return ret; - - } else if( type.color ){ - var tuple = $$.util.color2tuple( value ); - - return { - name: name, - value: tuple, - strValue: value, - bypass: propIsBypass - }; - - } else if( type.enums ){ - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - } else if( type.regex ){ - var regex = new RegExp( type.regex ); // make a regex from the type - var m = regex.exec( value ); - - if( m ){ // regex matches - return { - name: name, - value: m, - strValue: value, - bypass: propIsBypass - }; - } else { // regex doesn't match - return null; // didn't match the regex so the value is bogus - } - - } else if( type.string ){ - // just return - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - - } else { - return null; // not a type we can handle - } - - }; - - // gets what an em size corresponds to in pixels relative to a dom element - $$.styfn.getEmSizeInPixels = function(){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement && window.getComputedStyle ){ - var pxAsStr = window.getComputedStyle(domElement).getPropertyValue("font-size"); - var px = parseFloat( pxAsStr ); - return px; - } else { - return 1; // in case we're running outside of the browser - } - }; - - // gets css property from the core container - $$.styfn.containerCss = function( propName ){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement && window.getComputedStyle ){ - return window.getComputedStyle(domElement).getPropertyValue( propName ); - } - }; - - $$.styfn.containerProperty = function( propName ){ - var propStr = this.containerCss( propName ); - var prop = this.parse( propName, propStr ); - return prop; - }; - - $$.styfn.containerPropertyAsString = function( propName ){ - var prop = this.containerProperty( propName ); - - if( prop ){ - return prop.strValue; - } - }; - - // create a new context from the specified selector string and switch to that context - $$.styfn.selector = function( selectorStr ){ - // "core" is a special case and does not need a selector - var selector = selectorStr === "core" ? null : new $$.Selector( selectorStr ); - - var i = this.length++; // new context means new index - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // add one or many css rules to the current context - $$.styfn.css = function(){ - var args = arguments; - - switch( args.length ){ - case 1: - var map = args[0]; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - this.cssRule( prop.name, mapVal ); - } - } - - break; - - case 2: - this.cssRule( args[0], args[1] ); - break; - - default: - break; // do nothing if args are invalid - } - - return this; // chaining - }; - - // add a single css rule to the current context - $$.styfn.cssRule = function( name, value ){ - // name-value pair - var property = this.parse( name, value ); - - // add property to current context if valid - if( property ){ - var i = this.length - 1; - this[i].properties.push( property ); - - // add to core style if necessary - var currentSelectorIsCore = !this[i].selector; - if( currentSelectorIsCore ){ - this._private.coreStyle[ property.name ] = property; - } - } - - return this; // chaining - }; - - // apply a property to the style (for internal use) - // returns whether application was successful - // - // now, this function flattens the property, and here's how: - // - // for parsedProp:{ bypass: true, deleteBypass: true } - // no property is generated, instead the bypass property in the - // element's style is replaced by what's pointed to by the `bypassed` - // field in the bypass property (i.e. restoring the property the - // bypass was overriding) - // - // for parsedProp:{ mapped: truthy } - // the generated flattenedProp:{ mapping: prop } - // - // for parsedProp:{ bypass: true } - // the generated flattenedProp:{ bypassed: parsedProp } - $$.styfn.applyParsedProperty = function( ele, parsedProp, context ){ - parsedProp = $$.util.clone( parsedProp ); // copy b/c the same parsedProp may be applied to many elements, BUT - // the instances put in each element should be unique to avoid overwriting other the lists of other elements - - var prop = parsedProp; - var style = ele._private.style; - var fieldVal, flatProp; - var type = $$.style.properties[ prop.name ].type; - var propIsBypass = prop.bypass; - var origProp = style[ prop.name ]; - var origPropIsBypass = origProp && origProp.bypass; - - // can't apply auto to width or height unless it's a parent node - if( (parsedProp.name === "height" || parsedProp.name === "width") && parsedProp.value === "auto" && ele.isNode() && !ele.isParent() ){ - return false; - } - - // check if we need to delete the current bypass - if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete - var currentProp = style[ prop.name ]; - - // can only delete if the current prop is a bypass and it points to the property it was overriding - if( !currentProp ){ - return true; // property is already not defined - } else if( currentProp.bypass && currentProp.bypassed ){ // then replace the bypass property with the original - - // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary) - style[ prop.name ] = currentProp.bypassed; - return true; - - } else { - return false; // we're unsuccessful deleting the bypass - } - } - - // put the property in the style objects - switch( prop.mapped ){ // flatten the property if mapped - case $$.style.types.mapData: - case $$.style.types.mapLayoutData: - - var isLayout = prop.mapped === $$.style.types.mapLayoutData; - - // flatten the field (e.g. data.foo.bar) - var fields = prop.field.split("."); - var fieldVal = isLayout ? ele._private.layoutData : ele._private.data; - for( var i = 0; i < fields.length && fieldVal; i++ ){ - var field = fields[i]; - fieldVal = fieldVal[ field ]; - } - - if( !$$.is.number(fieldVal) ){ return false; } // it had better be a number - - var percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin); - - if( type.color ){ - var r1 = prop.valueMin[0]; - var r2 = prop.valueMax[0]; - var g1 = prop.valueMin[1]; - var g2 = prop.valueMax[1]; - var b1 = prop.valueMin[2]; - var b2 = prop.valueMax[2]; - var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3]; - var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3]; - - var clr = [ - Math.round( r1 + (r2 - r1)*percent ), - Math.round( g1 + (g2 - g1)*percent ), - Math.round( b1 + (b2 - b1)*percent ), - Math.round( a1 + (a2 - a1)*percent ) - ]; - - flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing - bypass: prop.bypass, // we're a bypass if the mapping property is a bypass - name: prop.name, - value: clr, - strValue: [ "rgba(", clr[0], ", ", clr[1], ", ", clr[2], ", ", clr[3] , ")" ].join("") // fake it til you make it - }; - - } else if( type.number ){ - var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent; - flatProp = this.parse( prop.name, calcValue, prop.bypass ); - - } else { - return false; // can only map to colours and numbers - } - - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - - break; - - // direct mapping - case $$.style.types.data: - case $$.style.types.layoutData: - - var isLayout = prop.mapped === $$.style.types.layoutData; - - // flatten the field (e.g. data.foo.bar) - var fields = prop.field.split("."); - var fieldVal = isLayout ? ele._private.layoutData : ele._private.data; - for( var i = 0; i < fields.length && fieldVal; i++ ){ - var field = fields[i]; - fieldVal = fieldVal[ field ]; - } - - flatProp = this.parse( prop.name, fieldVal, prop.bypass ); - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - break; - - case undefined: - break; // just set the property - - default: - return false; // not a valid mapping - } - - // if the property is a bypass property, then link the resultant property to the original one - if( propIsBypass ){ - if( origPropIsBypass ){ // then this bypass overrides the existing one - prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass - } else { // then link the orig prop to the new bypass - prop.bypassed = origProp; - } - - style[ prop.name ] = prop; // and set - - } else { // prop is not bypass - var prevProp; - - if( origPropIsBypass ){ // then keep the orig prop (since it's a bypass) and link to the new prop - prevProp = origProp.bypassed; - - origProp.bypassed = prop; - } else { // then just replace the old prop with the new one - prevProp = style[ prop.name ]; - - style[ prop.name ] = prop; - } - - if( prevProp && prevProp.mapping && prop.mapping && prevProp.context === context ){ - prevProp = prevProp.prev; - } - - if( prevProp && prevProp !== prop ){ - prop.prev = prevProp; - } - } - - prop.context = context; - - return true; - }; - - $$.styfn.rollBackContext = function( ele, context ){ - for( var j = 0; j < context.properties.length; j++ ){ // for each prop - var prop = context.properties[j]; - var eleProp = ele._private.style[ prop.name ]; - - // because bypasses do not store prevs, look at the bypassed property - if( eleProp.bypassed ){ - eleProp = eleProp.bypassed; - } - - var first = true; - var lastEleProp; - var l = 0; - while( eleProp.prev ){ - var prev = eleProp.prev; - - if( eleProp.context === context ){ - - if( first ){ - ele._private.style[ prop.name ] = prev; - } else if( lastEleProp ){ - lastEleProp.prev = prev; - } - - } - - lastEleProp = eleProp; - eleProp = prev; - first = false; - l++; - - // in case we have a problematic prev list - // if( l >= 100 ){ - // debugger; - // } - } - } - }; - - - // (potentially expensive calculation) - // apply the style to the element based on - // - its bypass - // - what selectors match it - $$.styfn.apply = function( eles ){ - var self = this; - - for( var ie = 0; ie < eles.length; ie++ ){ - var ele = eles[ie]; - - if( self._private.newStyle ){ - ele._private.styleCxts = []; - ele._private.style = {}; - } - - // console.log('APPLYING STYLESHEET\n--\n'); - - // apply the styles - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var contextSelectorMatches = context.selector && context.selector.filter( ele ).length > 0; // NB: context.selector may be null for "core" - var props = context.properties; - - // console.log(i + ' : looking at selector: ' + context.selector); - - if( contextSelectorMatches ){ // then apply its properties - - // apply the properties in the context - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - var newCxt = !ele._private.styleCxts[i]; - var currentEleProp = ele._private.style[prop.name]; - var propIsFirstInEle = currentEleProp && currentEleProp.context === context; - var needToUpdateCxtMapping = prop.mapped && propIsFirstInEle; - - //if(prop.mapped) debugger; - - if( newCxt || needToUpdateCxtMapping ){ - // console.log(i + ' + MATCH: applying property: ' + prop.name); - this.applyParsedProperty( ele, prop, context ); - } - } - - // keep a note that this context matches - ele._private.styleCxts[i] = context; - } else { - - // roll back style cxts that don't match now - if( ele._private.styleCxts[i] ){ - // console.log(i + ' x MISS: rolling back context'); - this.rollBackContext( ele, context ); - } - - delete ele._private.styleCxts[i]; - } - } // for context - - } // for elements - - self._private.newStyle = false; - }; - - // updates the visual style for all elements (useful for manual style modification after init) - $$.styfn.update = function(){ - var cy = this._private.cy; - var eles = cy.elements(); - - eles.updateStyle(); - }; - - // gets the rendered style for an element - $$.styfn.getRenderedStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - var cy = this._private.cy; - var zoom = cy.zoom(); - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - var val = styleProp.unitless ? styleProp.strValue : (styleProp.pxValue * zoom) + "px"; - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - - return rstyle; - } - }; - - // gets the raw style for an element - $$.styfn.getRawStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - rstyle[ prop.name ] = styleProp.strValue; - rstyle[ $$.util.dash2camel(prop.name) ] = styleProp.strValue; - } - } - - return rstyle; - } - }; - - // gets the value style for an element (useful for things like animations) - $$.styfn.getValueStyle = function( ele ){ - var rstyle, style; - - if( $$.is.element(ele) ){ - rstyle = {}; - style = ele._private.style; - } else { - rstyle = {}; - style = ele; // just passed the style itself - } - - if( style ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ] || style[ $$.util.dash2camel(prop.name) ]; - - if( styleProp !== undefined && !$$.is.plainObject( styleProp ) ){ // then make a prop of it - styleProp = this.parse(prop.name, styleProp); - } - - if( styleProp ){ - var val = styleProp.value === undefined ? styleProp : styleProp.value; - - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - } - - return rstyle; - }; - - // just update the functional properties (i.e. mappings) in the elements' - // styles (less expensive than recalculation) - $$.styfn.updateMappers = function( eles ){ - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - var style = ele._private.style; - - for( var j = 0; j < $$.style.properties.length; j++ ){ // for each prop - var prop = $$.style.properties[j]; - var propInStyle = style[ prop.name ]; - - if( propInStyle && propInStyle.mapping ){ - var mapping = propInStyle.mapping; - this.applyParsedProperty( ele, mapping ); // reapply the mapping property - } - } - } - }; - - // bypasses are applied to an existing style on an element, and just tacked on temporarily - // returns true iff application was successful for at least 1 specified property - $$.styfn.applyBypass = function( eles, name, value ){ - var props = []; - - // put all the properties (can specify one or many) in an array after parsing them - if( name === "*" || name === "**" ){ // apply to all property names - - if( value !== undefined ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - - } else if( $$.is.string(name) ){ // then parse the single property - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } else if( $$.is.plainObject(name) ){ // then parse each property - var specifiedProps = name; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = specifiedProps[ name ]; - - if( value === undefined ){ // try camel case name too - value = specifiedProps[ $$.util.dash2camel(name) ]; - } - - if( value !== undefined ){ - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - } else { // can't do anything without well defined properties - return false; - } - - // we've failed if there are no valid properties - if( props.length === 0 ){ return false; } - - // now, apply the bypass properties on the elements - var ret = false; // return true if at least one succesful bypass applied - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - - ret = this.applyParsedProperty( ele, prop ) || ret; - } - } - - return ret; - }; - - $$.styfn.removeAllBypasses = function( eles ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = ""; // empty => remove bypass - - var parsedProp = this.parse(name, value, true); - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - this.applyParsedProperty(ele, parsedProp); - } - } - }; - - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$, window){ "use strict"; - - var isTouch = $$.is.touch(); - - var defaults = { - hideEdgesOnViewport: false - }; - - var origDefaults = $$.util.copy( defaults ); - - $$.defaults = function( opts ){ - defaults = $$.util.extend({}, origDefaults, opts); - }; - - $$.fn.core = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - $$.Core.prototype[ name ] = fn; - } - }; - - $$.Core = function( opts ){ - if( !(this instanceof $$.Core) ){ - return new $$.Core(opts); - } - var cy = this; - - opts = $$.util.extend({}, defaults, opts); - - var container = opts.container; - var reg = $$.getRegistrationForInstance(cy, container); - if( reg && reg.cy ){ - reg.domElement.innerHTML = ''; - reg.cy.notify({ type: 'destroy' }); // destroy the renderer - - $$.removeRegistrationForInstance(reg.cy, reg.domElement); - } - - reg = $$.registerInstance( cy, container ); - var readies = reg.readies; - - var options = opts; - options.layout = $$.util.extend( { name: window && container ? "grid" : "null" }, options.layout ); - options.renderer = $$.util.extend( { name: window && container ? "canvas" : "null" }, options.renderer ); - - // TODO determine whether we need a check like this even though we allow running headless now - // - // if( !$$.is.domElement(options.container) ){ - // $$.util.error("Cytoscape.js must be called on an element"); - // return; - // } - - var _p = this._private = { - ready: false, // whether ready has been triggered - initrender: false, // has initrender has been triggered - instanceId: reg.id, // the registered instance id - options: options, // cached options - elements: [], // array of elements - id2index: {}, // element id => index in elements array - listeners: [], // list of listeners - aniEles: [], // array of elements being animated - scratch: {}, // scratch object for core - layout: null, - renderer: null, - notificationsEnabled: true, // whether notifications are sent to the renderer - minZoom: 1e-50, - maxZoom: 1e50, - zoomingEnabled: options.zoomingEnabled === undefined ? true : options.zoomingEnabled, - userZoomingEnabled: options.userZoomingEnabled === undefined ? true : options.userZoomingEnabled, - panningEnabled: options.panningEnabled === undefined ? true : options.panningEnabled, - userPanningEnabled: options.userPanningEnabled === undefined ? true : options.userPanningEnabled, - boxSelectionEnabled: options.boxSelectionEnabled === undefined ? true : options.boxSelectionEnabled, - zoom: $$.is.number(options.zoom) ? options.zoom : 1, - pan: { - x: $$.is.plainObject(options.pan) && $$.is.number(options.pan.x) ? options.pan.x : 0, - y: $$.is.plainObject(options.pan) && $$.is.number(options.pan.y) ? options.pan.y : 0, - }, - hasCompoundNodes: false - }; - - // set selection type - var selType = options.selectionType; - if( selType === undefined || (selType !== "additive" && selType !== "single") ){ - // then set default - - if( isTouch ){ - _p.selectionType = "additive"; - } else { - _p.selectionType = "single"; - } - } else { - _p.selectionType = selType; - } - - // init zoom bounds - if( $$.is.number(options.minZoom) && $$.is.number(options.maxZoom) && options.minZoom < options.maxZoom ){ - _p.minZoom = options.minZoom; - _p.maxZoom = options.maxZoom; - } else if( $$.is.number(options.minZoom) && options.maxZoom === undefined ){ - _p.minZoom = options.minZoom; - } else if( $$.is.number(options.maxZoom) && options.minZoom === undefined ){ - _p.maxZoom = options.maxZoom; - } - - // init style - - if( $$.is.stylesheet(options.style) ){ - _p.style = options.style.generateStyle(this); - } else if( $$.is.array(options.style) ) { - _p.style = $$.style.fromJson(this, options.style); - } else if( $$.is.string(options.style) ){ - _p.style = $$.style.fromString(this, options.style); - } else { - _p.style = new $$.Style( cy ); - } - - // create the renderer - cy.initRenderer( $$.util.extend({ - hideEdgesOnViewport: options.hideEdgesOnViewport - }, options.renderer) ); - - // trigger the passed function for the `initrender` event - if( options.initrender ){ - cy.on('initrender', options.initrender); - cy.on('initrender', function(){ - cy._private.initrender = true; - }); - } - - // initial load - cy.load(options.elements, function(){ // onready - cy.startAnimationLoop(); - cy._private.ready = true; - - // if a ready callback is specified as an option, the bind it - if( $$.is.fn( options.ready ) ){ - cy.bind("ready", options.ready); - } - - // bind all the ready handlers registered before creating this instance - for( var i = 0; i < readies.length; i++ ){ - var fn = readies[i]; - cy.bind("ready", fn); - } - reg.readies = []; // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc - - cy.trigger("ready"); - }, options.done); - }; - - $$.corefn = $$.Core.prototype; // short alias - - - $$.fn.core({ - ready: function(){ - return this._private.ready; - }, - - initrender: function(){ - return this._private.initrender; - }, - - registered: function(){ - if( this._private && this._private.instanceId != null ){ - return true; - } else { - return false; - } - }, - - registeredId: function(){ - return this._private.instanceId; - }, - - getElementById: function( id ){ - var index = this._private.id2index[ id ]; - if( index !== undefined ){ - return this._private.elements[ index ]; - } - - // worst case, return an empty collection - return new $$.Collection( this ); - }, - - selectionType: function(){ - return this._private.selectionType; - }, - - hasCompoundNodes: function(){ - return this._private.hasCompoundNodes; - }, - - addToPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var alreadyInPool = index !== undefined; - - if( !alreadyInPool ){ - index = elements.length; - elements.push( ele ) - id2index[ id ] = index; - ele._private.index = index; - } - } - - return this; // chaining - }, - - removeFromPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var inPool = index !== undefined; - - if( inPool ){ - delete this._private.id2index[ id ]; - elements.splice(index, 1); - - // adjust the index of all elements past this index - for( var j = index; j < elements.length; j++ ){ - var jid = elements[j]._private.data.id; - id2index[ jid ]--; - } - } - } - }, - - container: function(){ - return this._private.options.container; - }, - - options: function(){ - return $$.util.copy( this._private.options ); - }, - - json: function(params){ - var json = {}; - var cy = this; - - json.elements = {}; - cy.elements().each(function(i, ele){ - var group = ele.group(); - - if( !json.elements[group] ){ - json.elements[group] = []; - } - - json.elements[group].push( ele.json() ); - }); - - json.style = cy.style().json(); - json.scratch = cy.scratch(); - json.zoomingEnabled = cy._private.zoomingEnabled; - json.userZoomingEnabled = cy._private.userZoomingEnabled; - json.zoom = cy._private.zoom; - json.minZoom = cy._private.minZoom; - json.maxZoom = cy._private.maxZoom; - json.panningEnabled = cy._private.panningEnabled; - json.userPanningEnabled = cy._private.userPanningEnabled; - json.pan = cy._private.pan; - json.boxSelectionEnabled = cy._private.boxSelectionEnabled; - json.layout = cy._private.options.layout; - json.renderer = cy._private.options.renderer; - json.hideEdgesOnViewport = cy._private.options.hideEdgesOnViewport; - - return json; - } - - }); - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -(function($$, window){ "use strict"; - - function ready(f) { - var fn = ( document && (document.readyState === 'interactive' || document.readyState === 'complete') ) ? f : ready; - - setTimeout(fn, 9, f); - } - - $$.fn.core({ - add: function(opts){ - - var elements; - var cy = this; - - // add the elements - if( $$.is.elementOrCollection(opts) ){ - var eles = opts; - - if( eles._private.cy === cy ){ // same instance => just restore - elements = eles.restore(); - - } else { // otherwise, copy from json - var jsons = []; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - jsons.push( ele.json() ); - } - - elements = new $$.Collection( cy, jsons ); - } - } - - // specify an array of options - else if( $$.is.array(opts) ){ - var jsons = opts; - - elements = new $$.Collection(cy, jsons); - } - - // specify via opts.nodes and opts.edges - else if( $$.is.plainObject(opts) && ($$.is.array(opts.nodes) || $$.is.array(opts.edges)) ){ - var elesByGroup = opts; - var jsons = []; - - var grs = ["nodes", "edges"]; - for( var i = 0, il = grs.length; i < il; i++ ){ - var group = grs[i]; - var elesArray = elesByGroup[group]; - - if( $$.is.array(elesArray) ){ - - for( var j = 0, jl = elesArray.length; j < jl; j++ ){ - var json = elesArray[j]; - - var mjson = $$.util.extend({}, json, { group: group }); - jsons.push( mjson ); - } - } - } - - elements = new $$.Collection(cy, jsons); - } - - // specify options for one element - else { - var json = opts; - elements = (new $$.Element( cy, json )).collection(); - } - - return elements; - }, - - remove: function(collection){ - if( $$.is.elementOrCollection(collection) ){ - collection = collection; - } else if( $$.is.string(collection) ){ - var selector = collection; - collection = this.$( selector ); - } - - return collection.remove(); - }, - - load: function(elements, onload, ondone){ - var cy = this; - - // remove old elements - var oldEles = cy.elements(); - if( oldEles.length > 0 ){ - oldEles.remove(); - } - - cy.notifications(false); - - if( elements != null ){ - if( $$.is.plainObject(elements) || $$.is.array(elements) ){ - cy.add( elements ); - } - } - - function callback(){ - cy.one("layoutready", function(e){ - cy.notifications(true); - cy.trigger(e); // we missed this event by turning notifications off, so pass it on - - cy.notify({ - type: "load", - collection: cy.elements() - }); - - cy.one("load", onload); - cy.trigger("load"); - }).one("layoutstop", function(){ - cy.one("done", ondone); - cy.trigger("done"); - }); - - cy.layout( cy._private.options.layout ); - - } - - if( window ){ - ready( callback ); - } else { - callback(); - } - - return this; - } - }); - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - addToAnimationPool: function( eles ){ - var cy = this; - var aniEles = cy._private.aniEles; - var aniElesHas = []; - - for( var i = 0; i < aniEles.length; i++ ){ - var id = aniEles[i]._private.data.id; - aniElesHas[ id ] = true; - } - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - - if( !aniElesHas[id] ){ - aniEles.push( ele ); - } - } - }, - - startAnimationLoop: function(){ - var cy = this; - var stepDelay = 1000/60; - var useTimeout = false; - var useRequestAnimationFrame = true; - - // initialise the list - cy._private.aniEles = []; - - // TODO change this when standardised - var requestAnimationFrame = typeof window === 'undefined' ? function(){} : ( window.requestAnimationFrame || window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ); - - if( requestAnimationFrame == null || !useRequestAnimationFrame ){ - requestAnimationFrame = function(fn){ - window.setTimeout(function(){ - fn(+new Date); - }, stepDelay); - }; - } - - var containerDom = cy.container(); - - function globalAnimationStep(){ - function exec(){ - requestAnimationFrame(function(now){ - handleElements(now); - globalAnimationStep(); - }, containerDom); - } - - if( useTimeout ){ - setTimeout(function(){ - exec(); - }, stepDelay); - } else { - exec(); - } - } - - globalAnimationStep(); // first call - - function handleElements(now){ - now = +new Date; - - var eles = cy._private.aniEles; - for( var e = 0; e < eles.length; e++ ){ - var ele = eles[e]; - - // we might have errors if we edit animation.queue and animation.current - // for ele (i.e. by stopping) - // try{ - - var current = ele._private.animation.current; - var queue = ele._private.animation.queue; - - // if nothing currently animating, get something from the queue - if( current.length === 0 ){ - var q = queue; - var next = q.length > 0 ? q.shift() : null; - - if( next != null ){ - next.callTime = +new Date; // was queued, so update call time - current.push( next ); - } - } - - // step and remove if done - var completes = []; - for(var i = 0; i < current.length; i++){ - var ani = current[i]; - step( ele, ani, now ); - - if( current[i].done ){ - completes.push( ani ); - - // remove current[i] - current.splice(i, 1); - i--; - } - } - - // call complete callbacks - for( var i = 0; i < completes.length; i++ ){ - var ani = completes[i]; - var complete = ani.params.complete; - - if( $$.is.fn(complete) ){ - complete.apply( ele, [ now ] ); - } - } - - // } catch(e){ - // // do nothing - // } - - } // each element - - - // notify renderer - if( eles.length > 0 ){ - cy.notify({ - type: "draw", - collection: eles - }); - } - - // remove elements from list of currently animating if its queues are empty - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var queue = ele._private.animation.queue; - var current = ele._private.animation.current; - var keepEle = current.length > 0 || queue.length > 0; - - if( !keepEle ){ // then remove from the array - eles.splice(i, 1); - i--; - } - } - - } // handleElements - - function step( self, animation, now ){ - var style = cy._private.style; - var properties = animation.properties; - var params = animation.params; - var startTime = animation.callTime; - var percent; - - if( animation.duration === 0 ){ - percent = 1; - } else { - percent = Math.min(1, (now - startTime)/animation.duration); - } - - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( properties.delay == null ){ // then update the position - var startPos = animation.startPosition; - var endPos = properties.position; - var pos = self._private.position; - if( endPos ){ - if( valid( startPos.x, endPos.x ) ){ - pos.x = ease( startPos.x, endPos.x, percent ); - } - - if( valid( startPos.y, endPos.y ) ){ - pos.y = ease( startPos.y, endPos.y, percent ); - } - } - - if( properties.css ){ - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var name = props[i].name; - var end = properties.css[ name ]; - - if( end !== undefined ){ - var start = animation.startStyle[ name ]; - var easedVal = ease( start, end, percent ); - - style.applyBypass( self, name, easedVal ); - } - } // for props - } // if - } - - if( $$.is.fn(params.step) ){ - params.step.apply( self, [ now ] ); - } - - if( percent >= 1 ){ - animation.done = true; - } - - return percent; - } - - function valid(start, end){ - if( start == null || end == null ){ - return false; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return true; - } else if( (start) && (end) ){ - return true; - } - - return false; - } - - function ease(start, end, percent){ - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return start + (end - start) * percent; - - } else if( $$.is.number(start[0]) && $$.is.number(end[0]) ){ // then assume a colour - var c1 = start; - var c2 = end; - - var ch = function(ch1, ch2){ - var diff = ch2 - ch1; - var min = ch1; - return Math.round( percent * diff + min ); - }; - - var r = ch( c1[0], c2[0] ); - var g = ch( c1[1], c2[1] ); - var b = ch( c1[2], c2[2] ); - - return 'rgb(' + r + ', ' + g + ', ' + b + ')'; - } - - return undefined; - } - - } - - }); - -})( cytoscape ); - - - - - -;(function($$){ "use strict"; - - $$.fn.core({ - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - }); - - // aliases for those folks who like old stuff: - $$.corefn.bind = $$.corefn.on; - $$.corefn.unbind = $$.corefn.off; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - png: function( options ){ - var cy = this; - var renderer = this._private.renderer; - options = options || {}; - - return renderer.png( options ); - } - - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - layout: function( params ){ - var cy = this; - - if( this._private.layoutRunning ){ // don't run another layout if one's already going - return this; - } - - // if no params, use the previous ones - if( params == null ){ - params = this._private.options.layout; - } - - this.initLayout( params ); - - cy.trigger("layoutstart"); - - this._private.layoutRunning = true; - this.one('layoutstop', function(){ - cy._private.layoutRunning = false; - }); - - this._private.layout.run(); - - return this; - - }, - - initLayout: function( options ){ - if( options == null ){ - $$.util.error("Layout options must be specified to run a layout"); - return; - } - - if( options.name == null ){ - $$.util.error("A `name` must be specified to run a layout"); - return; - } - - var name = options.name; - var layoutProto = $$.extension("layout", name); - - if( layoutProto == null ){ - $$.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?", name); - return; - } - - this._private.layout = new layoutProto( $$.util.extend({}, options, { - renderer: this._private.renderer, - cy: this - }) ); - this._private.options.layout = options; // save options - } - - }); - -})( cytoscape ); - -(function($$){ "use strict"; - - $$.fn.core({ - notify: function( params ){ - if( !this._private.notificationsEnabled ){ return; } // exit on disabled - - var renderer = this.renderer(); - var cy = this; - - // normalise params.collection - if( $$.is.element(params.collection) ){ // make collection from element - var element = params.collection; - params.collection = new $$.Collection(cy, [ element ]); - - } else if( $$.is.array(params.collection) ){ // make collection from elements array - var elements = params.collection; - params.collection = new $$.Collection(cy, elements); - } - - renderer.notify(params); - }, - - notifications: function( bool ){ - var p = this._private; - - if( bool === undefined ){ - return p.notificationsEnabled; - } else { - p.notificationsEnabled = bool ? true : false; - } - }, - - noNotifications: function( callback ){ - this.notifications(false); - callback(); - this.notifications(true); - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - renderTo: function( context, zoom, pan ){ - var r = this._private.renderer; - - r.renderTo( context, zoom, pan ); - return this; - }, - - renderer: function(){ - return this._private.renderer; - }, - - forceRender: function(){ - this.notify({ - type: "draw" - }); - - return this; - }, - - initRenderer: function( options ){ - var cy = this; - - var rendererProto = $$.extension("renderer", options.name); - if( rendererProto == null ){ - $$.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?", options.name); - return; - } - - this._private.renderer = new rendererProto( - $$.util.extend({}, options, { - cy: cy, - style: cy._private.style - }) - ); - - - }, - - recalculateRenderedStyle: function(){ - var renderer = this.renderer(); - - if( renderer.recalculateRenderedStyle ){ - renderer.recalculateRenderedStyle(); - } - } - - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - // get a collection - // - empty collection on no args - // - collection of elements in the graph on selector arg - // - guarantee a returned collection when elements or collection specified - collection: function( eles ){ - - if( $$.is.string(eles) ){ - return this.$( eles ); - } else if( $$.is.elementOrCollection(eles) ){ - return eles.collection(); - } - - return new $$.Collection( this ); - }, - - nodes: function( selector ){ - var nodes = this.$("node"); - - if( selector ){ - return nodes.filter( selector ); - } - - return nodes; - }, - - edges: function( selector ){ - var edges = this.$("edge"); - - if( selector ){ - return edges.filter( selector ); - } - - return edges; - }, - - // search the graph like jQuery - $: function( selector ){ - var eles = new $$.Collection( this, this._private.elements ); - - if( selector ){ - return eles.filter( selector ); - } - - return eles; - } - - }); - - // aliases - $$.corefn.elements = $$.corefn.filter = $$.corefn.$; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - style: function(val){ - return this._private.style; - } - }); - -})( cytoscape ); - - -;(function($$){ "use strict"; - - $$.fn.core({ - - panningEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.panningEnabled = bool ? true : false; - } else { - return this._private.panningEnabled; - } - - return this; // chaining - }, - - userPanningEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.userPanningEnabled = bool ? true : false; - } else { - return this._private.userPanningEnabled; - } - - return this; // chaining - }, - - zoomingEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.zoomingEnabled = bool ? true : false; - } else { - return this._private.zoomingEnabled; - } - - return this; // chaining - }, - - userZoomingEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.userZoomingEnabled = bool ? true : false; - } else { - return this._private.userZoomingEnabled; - } - - return this; // chaining - }, - - boxSelectionEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.boxSelectionEnabled = bool ? true : false; - } else { - return this._private.boxSelectionEnabled; - } - - return this; // chaining - }, - - pan: function(){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - switch( args.length ){ - case 0: // .pan() - return pan; - - case 1: - - if( !this._private.panningEnabled ){ - return this; - - } else if( $$.is.string( args[0] ) ){ // .pan("x") - dim = args[0]; - return pan[ dim ]; - - } else if( $$.is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x = x; - } - - if( $$.is.number(y) ){ - pan.y = y; - } - - this.trigger("pan"); - } - break; - - case 2: // .pan("x", 100) - if( !this._private.panningEnabled ){ - return this; - } - - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] = val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - panBy: function(params){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - if( !this._private.panningEnabled ){ - return this; - } - - switch( args.length ){ - case 1: - - if( $$.is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x += x; - } - - if( $$.is.number(y) ){ - pan.y += y; - } - - this.trigger("pan"); - } - break; - - case 2: // .panBy("x", 100) - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] += val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - fit: function( elements, padding ){ - if( $$.is.number(elements) && padding === undefined ){ // elements is optional - padding = elements; - elements = undefined; - } - - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var sel = elements; - elements = this.$( sel ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = this.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom; - padding = $$.is.number(padding) ? padding : 0; - - if( !isNaN(w) && !isNaN(h) && elements.length > 0 ){ - zoom = this._private.zoom = Math.min( (w - 2*padding)/bb.w, (h - 2*padding)/bb.h ); - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - this._private.pan = { // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }; - - this.trigger("pan zoom"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - } - - return this; // chaining - }, - - minZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.minZoom; - } else if( $$.is.number(zoom) ){ - this._private.minZoom = zoom; - } - - return this; - }, - - maxZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.maxZoom; - } else if( $$.is.number(zoom) ){ - this._private.maxZoom = zoom; - } - - return this; - }, - - zoom: function( params ){ - var pos; // in rendered px - var zoom; - - if( params === undefined ){ // then get the zoom - return this._private.zoom; - - } else if( $$.is.number(params) ){ // then set the zoom - zoom = params; - - } else if( $$.is.plainObject(params) ){ // then zoom about a point - zoom = params.level; - - if( params.position ){ - var p = params.position; - var pan = this._private.pan; - var z = this._private.zoom; - - pos = { // convert to rendered px - x: p.x * z + pan.x, - y: p.y * z + pan.y - }; - } else if( params.renderedPosition ){ - pos = params.renderedPosition; - } - - if( pos && !this._private.panningEnabled ){ - return this; // panning disabled - } - } - - if( !this._private.zoomingEnabled ){ - return this; // zooming disabled - } - - if( !$$.is.number(zoom) || ( pos && (!$$.is.number(pos.x) || !$$.is.number(pos.y)) ) ){ - return this; // can't zoom with invalid params - } - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - if( pos ){ // set zoom about position - var pan1 = this._private.pan; - var zoom1 = this._private.zoom; - var zoom2 = zoom; - - var pan2 = { - x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x, - y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y - }; - - this._private.zoom = zoom; - this._private.pan = pan2; - - var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y; - this.trigger("zoom" + (posChanged ? " pan" : "") ); - - } else { // just set the zoom - this._private.zoom = zoom; - this.trigger("zoom"); - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( selector ){ - var eles = this.$( selector ); - - return eles.boundingBox(); - }, - - renderedBoundingBox: function( selector ){ - var eles = this.$( selector ); - - return eles.renderedBoundingBox(); - }, - - center: function(elements){ - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var selector = elements; - elements = cy.elements( selector ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = cy.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom = this._private.zoom; - - this.pan({ // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }); - - this.trigger("pan"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - reset: function(){ - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - this.pan({ x: 0, y: 0 }); - - if( this._private.maxZoom > 1 && this._private.minZoom < 1 ){ - this.zoom(1); - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Use this interface to define functions for collections/elements. - // This interface is good, because it forces you to think in terms - // of the collections case (more than 1 element), so we don't need - // notification blocking nonsense everywhere. - // - // Other collection-*.js files depend on this being defined first. - // It's a trade off: It simplifies the code for Collection and - // Element integration so much that it's worth it to create the - // JS dependency. - // - // Having this integration guarantees that we can call any - // collection function on an element and vice versa. - - // e.g. $$.fn.collection({ someFunc: function(){ /* ... */ } }) - $$.fn.collection = $$.fn.eles = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - - $$.Collection.prototype[ name ] = fn; - } - }; - - // factory for generating edge ids when no id is specified for a new element - var idFactory = { - prefix: { - nodes: "n", - edges: "e" - }, - id: { - nodes: 0, - edges: 0 - }, - generate: function(cy, element, tryThisId){ - var json = $$.is.element( element ) ? element._private : element; - var group = json.group; - var id = tryThisId != null ? tryThisId : this.prefix[group] + this.id[group]; - - if( cy.getElementById(id).empty() ){ - this.id[group]++; // we've used the current id, so move it up - } else { // otherwise keep trying successive unused ids - while( !cy.getElementById(id).empty() ){ - id = this.prefix[group] + ( ++this.id[group] ); - } - } - - return id; - } - }; - - // Element - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a node or an edge - $$.Element = function(cy, params, restore){ - if( !(this instanceof $$.Element) ){ - return new $$.Element(cy, params, restore); - } - - var self = this; - restore = (restore === undefined || restore ? true : false); - - if( cy === undefined || params === undefined || !$$.is.core(cy) ){ - $$.util.error("An element must have a core reference and parameters set"); - return; - } - - // validate group - if( params.group !== "nodes" && params.group !== "edges" ){ - $$.util.error("An element must be of type `nodes` or `edges`; you specified `" + params.group + "`"); - return; - } - - // make the element array-like, just like a collection - this.length = 1; - this[0] = this; - - // NOTE: when something is added here, add also to ele.json() - this._private = { - cy: cy, - single: true, // indicates this is an element - data: params.data || {}, // data object - layoutData: {}, // place for layouts to put calculated stats etc for mappers - position: params.position || {}, // fields x, y, etc (could be 3d or radial coords; renderer decides) - autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special "auto" value - autoHeight: undefined, - listeners: [], // array of bound listeners - group: params.group, // string; "nodes" or "edges" - style: {}, // properties as set by the style - rstyle: {}, // properties for style sent from the renderer to the core - styleCxts: [], // applied style contexts from the styler - removed: true, // whether it's inside the vis; true if removed (set true here since we call restore) - selected: params.selected ? true : false, // whether it's selected - selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable - locked: params.locked ? true : false, // whether the element is locked (cannot be moved) - grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately - grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed - active: false, // whether the element is active from user interaction - classes: {}, // map ( className => true ) - animation: { // object for currently-running animations - current: [], - queue: [] - }, - rscratch: {}, // object in which the renderer can store information - scratch: {}, // scratch objects - edges: [], // array of connected edges - children: [] // array of children - }; - - // renderedPosition overrides if specified - if( params.renderedPosition ){ - var rpos = params.renderedPosition; - var pan = cy.pan(); - var zoom = cy.zoom(); - - this._private.position = { - x: (rpos.x - pan.x)/zoom, - y: (rpos.y - pan.y)/zoom - }; - } - - if( $$.is.string(params.classes) ){ - var classes = params.classes.split(/\s+/); - for( var i = 0, l = classes.length; i < l; i++ ){ - var cls = classes[i]; - if( !cls || cls === "" ){ continue; } - - self._private.classes[cls] = true; - } - } - - if( params.css ){ - cy.style().applyBypass( this, params.css ); - } - - if( restore === undefined || restore ){ - this.restore(); - } - - }; - - - // Collection - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a set of nodes, edges, or both together - $$.Collection = function(cy, elements){ - if( !(this instanceof $$.Collection) ){ - return new $$.Collection(cy, elements); - } - - if( cy === undefined || !$$.is.core(cy) ){ - $$.util.error("A collection must have a reference to the core"); - return; - } - - var ids = {}; - var uniqueElements = []; - var createdElements = false; - - if( !elements ){ - elements = []; - } else if( elements.length > 0 && $$.is.plainObject( elements[0] ) && !$$.is.element( elements[0] ) ){ - createdElements = true; - - // make elements from json and restore all at once later - var eles = []; - var elesIds = {}; - - for( var i = 0, l = elements.length; i < l; i++ ){ - var json = elements[i]; - - if( json.data == null ){ - json.data = {}; - } - - var data = json.data; - - // make sure newly created elements have valid ids - if( data.id == null ){ - data.id = idFactory.generate( cy, json ); - } else if( cy.getElementById( data.id ).length != 0 || elesIds[ data.id ] ){ - continue; // can't create element if prior id already exists - } - - var ele = new $$.Element( cy, json, false ); - eles.push( ele ); - elesIds[ data.id ] = true; - } - - elements = eles; - } - - for( var i = 0, l = elements.length; i < l; i++ ){ - var element = elements[i]; - if( !element ){ continue; } - - var id = element._private.data.id; - - if( !ids[ id ] ){ - ids[ id ] = element; - uniqueElements.push( element ); - } - } - - for(var i = 0, l = uniqueElements.length; i < l; i++){ - this[i] = uniqueElements[i]; - } - this.length = uniqueElements.length; - - this._private = { - cy: cy, - ids: ids - }; - - // restore the elements if we created them from json - if( createdElements ){ - this.restore(); - } - }; - - - // Functions - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // keep the prototypes in sync (an element has the same functions as a collection) - // and use $$.elefn and $$.elesfn as shorthands to the prototypes - $$.elefn = $$.elesfn = $$.Element.prototype = $$.Collection.prototype; - - $$.elesfn.cy = function(){ - return this._private.cy; - }; - - $$.elesfn.element = function(){ - return this[0]; - }; - - $$.elesfn.collection = function(){ - if( $$.is.collection(this) ){ - return this; - } else { // an element - return new $$.Collection( this._private.cy, [this] ); - } - }; - - $$.elesfn.json = function(){ - var ele = this.element(); - if( ele == null ){ return undefined } - - var p = ele._private; - - var json = $$.util.copy({ - data: p.data, - position: p.position, - group: p.group, - bypass: p.bypass, - removed: p.removed, - selected: p.selected, - selectable: p.selectable, - locked: p.locked, - grabbed: p.grabbed, - grabbable: p.grabbable, - classes: "" - }); - - var classes = []; - for( var cls in p.classes ){ - classes.push(cls); - } - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - json.classes += cls + ( i < classes.length - 1 ? " " : "" ); - } - - return json; - }; - - $$.elesfn.jsons = function(){ - var jsons = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - var json = ele.json(); - - jsons.push( json ); - } - - return jsons; - }; - - $$.elesfn.restore = function( notifyRenderer ){ - var self = this; - var restored = []; - var cy = self.cy(); - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // create arrays of nodes and edges, since we need to - // restore the nodes first - var elements = []; - var nodes = [], edges = []; - var numNodes = 0; - var numEdges = 0; - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - // keep nodes first in the array and edges after - if( ele.isNode() ){ // put to front of array if node - nodes.push( ele ); - numNodes++; - } else { // put to end of array if edge - edges.push( ele ); - numEdges++; - } - } - - elements = nodes.concat( edges ); - - // now, restore each element - for( var i = 0, l = elements.length; i < l; i++ ){ - var ele = elements[i]; - - if( !ele.removed() ){ - // don't need to do anything - continue; - } - - var _private = ele._private; - var data = _private.data; - - // set id and validate - if( data.id === undefined ){ - data.id = idFactory.generate( cy, ele ); - } else if( $$.is.emptyString(data.id) || !$$.is.string(data.id) ){ - $$.util.error("Can not create element with invalid string ID `" + data.id + "`"); - - // can't create element if it has empty string as id or non-string id - continue; - } else if( cy.getElementById( data.id ).length != 0 ){ - $$.util.error("Can not create second element with ID `" + data.id + "`"); - - // can't create element if one already has that id - continue; - } - - var id = data.id; // id is finalised, now let's keep a ref - - if( ele.isEdge() ){ // extra checks for edges - - var edge = ele; - var fields = ["source", "target"]; - var fieldsLength = fields.length; - var badSourceOrTarget = false; - for(var j = 0; j < fieldsLength; j++){ - - var field = fields[j]; - var val = data[field]; - - if( val == null || val === "" ){ - // can't create if source or target is not defined properly - $$.util.error("Can not create edge `" + data.id + "` with unspecified " + field); - badSourceOrTarget = true; - } else if( cy.getElementById(val).empty() ){ - // can't create edge if one of its nodes doesn't exist - $$.util.error("Can not create edge `" + data.id + "` with nonexistant " + field + " `" + val + "`"); - badSourceOrTarget = true; - } - } - - if( badSourceOrTarget ){ continue; } // can't create this - - var src = cy.getElementById( data.source ); - var tgt = cy.getElementById( data.target ); - - src._private.edges.push( edge ); - tgt._private.edges.push( edge ); - - } // if is edge - - // create mock ids map for element so it can be used like collections - _private.ids = {}; - _private.ids[ data.id ] = ele; - - _private.removed = false; - cy.addToPool( ele ); - - restored.push( ele ); - } // for each element - - // do compound node sanity checks - for( var i = 0; i < numNodes; i++ ){ // each node - var node = elements[i]; - var data = node._private.data; - var id = data.id; - - var parentId = node._private.data.parent; - var specifiedParent = parentId != null; - - if( specifiedParent ){ - var parent = cy.getElementById( parentId ); - - if( parent.empty() ){ - // non-existant parent; just remove it - delete data.parent; - } else { - var selfAsParent = false; - var ancestor = parent; - while( !ancestor.empty() ){ - if( node.same(ancestor) ){ - // mark self as parent and remove from data - selfAsParent = true; - delete data.parent; // remove parent reference - - // exit or we loop forever - break; - } - - ancestor = ancestor.parent(); - } - - if( !selfAsParent ){ - // connect with children - parent[0]._private.children.push( node ); - - // let the core know we have a compound graph - cy._private.hasCompoundNodes = true; - } - } // else - } // if specified parent - } // for each node - - restored = new $$.Collection( cy, restored ); - if( restored.length > 0 ){ - - var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() ); - toUpdateStyle.updateStyle( notifyRenderer ); - - if( notifyRenderer ){ - restored.rtrigger("add"); - } else { - restored.trigger("add"); - } - } - - return self; // chainability - }; - - $$.elesfn.removed = function(){ - var ele = this[0]; - return ele && ele._private.removed; - }; - - $$.elesfn.inside = function(){ - var ele = this[0]; - return ele && !ele._private.removed; - }; - - $$.elesfn.remove = function( notifyRenderer ){ - var self = this; - var removed = []; - var elesToRemove = []; - var elesToRemoveIds = {}; - var cy = self._private.cy; - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // add connected edges - function addConnectedEdges(node){ - var edges = node._private.edges; - for( var i = 0; i < edges.length; i++ ){ - add( edges[i] ); - } - } - - - // add descendant nodes - function addChildren(node){ - var children = node._private.children; - - for( var i = 0; i < children.length; i++ ){ - add( children[i] ); - } - } - - function add( ele ){ - var alreadyAdded = elesToRemoveIds[ ele.id() ]; - if( alreadyAdded ){ - return; - } else { - elesToRemoveIds[ ele.id() ] = true; - } - - if( ele.isNode() ){ - elesToRemove.push( ele ); // nodes are removed last - - addConnectedEdges( ele ); - addChildren( ele ); - } else { - elesToRemove.unshift( ele ); // edges are removed first - } - } - - // make the list of elements to remove - // (may be removing more than specified due to connected edges etc) - - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - add( ele ); - } - - function removeEdgeRef(node, edge){ - var connectedEdges = node._private.edges; - for( var j = 0; j < connectedEdges.length; j++ ){ - var connectedEdge = connectedEdges[j]; - - if( edge === connectedEdge ){ - connectedEdges.splice( j, 1 ); - break; - } - } - } - - function removeChildRef(parent, ele){ - ele = ele[0]; - parent = parent[0]; - var children = parent._private.children; - - for( var j = 0; j < children.length; j++ ){ - if( children[j][0] === ele[0] ){ - children.splice(j, 1); - break; - } - } - } - - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - - // mark as removed - ele._private.removed = true; - - // remove from core pool - cy.removeFromPool( ele ); - - // add to list of removed elements - removed.push( ele ); - - if( ele.isEdge() ){ // remove references to this edge in its connected nodes - var src = ele.source()[0]; - var tgt = ele.target()[0]; - - removeEdgeRef( src, ele ); - removeEdgeRef( tgt, ele ); - - } else { // remove reference to parent - var parent = ele.parent(); - - if( parent.length !== 0 ){ - removeChildRef(parent, ele); - } - } - } - - // check to see if we have a compound graph or not - var elesStillInside = cy._private.elements; - cy._private.hasCompoundNodes = false; - for( var i = 0; i < elesStillInside.length; i++ ){ - var ele = elesStillInside[i]; - - if( ele.isParent() ){ - cy._private.hasCompoundNodes = true; - break; - } - } - - var removedElements = new $$.Collection( this.cy(), removed ); - if( removedElements.size() > 0 ){ - // must manually notify since trigger won't do this automatically once removed - - if( notifyRenderer ){ - this.cy().notify({ - type: "remove", - collection: removedElements - }); - } - - removedElements.trigger("remove"); - } - - // check for empty remaining parent nodes - var checkedParentId = {}; - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - var isNode = ele._private.group === "nodes"; - var parentId = ele._private.data.parent; - - if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){ - checkedParentId[ parentId ] = true; - var parent = cy.getElementById( parentId ); - - if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){ - parent.updateStyle(); - } - } - } - - return this; - }; - -})( cytoscape ); - - -;(function( $$ ){ "use strict"; - - $$.fn.eles({ - animated: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.animation.current.length > 0; - } - }, - - clearQueue: function(){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - ele._private.animation.queue = []; - } - - return this; - }, - - delay: function( time, complete ){ - this.animate({ - delay: time - }, { - duration: time, - complete: complete - }); - - return this; - }, - - animate: function( properties, params ){ - var callTime = +new Date; - var cy = this._private.cy; - var style = cy.style(); - var q; - - if( params === undefined ){ - params = {}; - } - - if( params.duration === undefined ){ - params.duration = 400; - } - - switch( params.duration ){ - case "slow": - params.duration = 600; - break; - case "fast": - params.duration = 200; - break; - } - - if( properties == null || (properties.position == null && properties.renderedPosition == null && properties.css == null && properties.delay == null) ){ - return this; // nothing to animate - } - - if( properties.css ){ - properties.css = style.getValueStyle( properties.css ); - } - - if( properties.renderedPosition ){ - var rpos = properties.renderedPosition; - var pan = cy.pan(); - var zoom = cy.zoom(); - - properties.position = { - x: ( rpos.x - pan.x ) /zoom, - y: ( rpos.y - pan.y ) /zoom - }; - } - - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - - var pos = self._private.position; - var startPosition = { - x: pos.x, - y: pos.y - }; - var startStyle = style.getValueStyle( self ); - - if( self.animated() && (params.queue === undefined || params.queue) ){ - q = self._private.animation.queue; - } else { - q = self._private.animation.current; - } - - q.push({ - properties: properties, - duration: params.duration, - params: params, - callTime: callTime, - startPosition: startPosition, - startStyle: startStyle - }); - } - - cy.addToAnimationPool( this ); - - return this; // chaining - }, // animate - - stop: function(clearQueue, jumpToEnd){ - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - var anis = self._private.animation.current; - - for( var j = 0; j < anis.length; j++ ){ - var animation = anis[j]; - if( jumpToEnd ){ - // next iteration of the animation loop, the animation - // will go straight to the end and be removed - animation.duration = 0; - } - } - - // clear the queue of future animations - if( clearQueue ){ - self._private.animation.queue = []; - } - } - - // we have to notify (the animation loop doesn't do it for us on `stop`) - this.cy().notify({ - collection: this, - type: "draw" - }); - - return this; - } - }); - -})( cytoscape ); - -;(function( $$ ){ "use strict"; - - $$.fn.eles({ - addClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - if( $$.is.emptyString(cls) ){ continue; } - - for( var j = 0; j < self.length; j++ ){ - var ele = self[j]; - var hasClass = ele._private.classes[cls]; - ele._private.classes[cls] = true; - - if( !hasClass ){ // if didn't already have, add to list of changed - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - hasClass: function(className){ - var ele = this[0]; - return ( ele != null && ele._private.classes[className] ) ? true : false; - }, - - toggleClass: function(classesStr, toggle){ - var classes = classesStr.split(/\s+/); - var self = this; - var changed = []; // eles who had classes changed - - for( var i = 0, il = self.length; i < il; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - - if( $$.is.emptyString(cls) ){ continue; } - - var hasClass = ele._private.classes[cls]; - var shouldAdd = toggle || (toggle === undefined && !hasClass); - - if( shouldAdd ){ - ele._private.classes[cls] = true; - - if( !hasClass ){ changed.push(ele); } - } else { // then remove - ele._private.classes[cls] = false; - - if( hasClass ){ changed.push(ele); } - } - - } // for j classes - } // for i eles - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - removeClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < self.length; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - if( !cls || cls === "" ){ continue; } - - var hasClass = ele._private.classes[cls]; - delete ele._private.classes[cls]; - - if( hasClass ){ // then we changed its set of classes - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(self._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - allAre: function(selector){ - return this.filter(selector).length === this.length; - }, - - is: function(selector){ - return this.filter(selector).length > 0; - }, - - same: function( collection ){ - collection = this.cy().collection( collection ); - - // cheap extra check - if( this.length !== collection.length ){ - return false; - } - - return this.intersect( collection ).length === this.length; - }, - - anySame: function(collection){ - collection = this.cy().collection( collection ); - - return this.intersect( collection ).length > 0; - }, - - allAreNeighbors: function(collection){ - collection = this.cy().collection( collection ); - - return this.neighborhood().intersect( collection ).length === collection.length; - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var borderWidthMultiplier = 2 * 0.5; - var borderWidthAdjustment = 0; - - $$.fn.eles({ - - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - - rscratch: $$.define.data({ - field: "rscratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeRscratch: $$.define.removeData({ - field: "rscratch", - triggerEvent: false - }), - - id: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.id; - } - }, - - position: $$.define.data({ - field: "position", - bindingEvent: "position", - allowBinding: true, - allowSetting: true, - settingEvent: "position", - settingTriggersEvent: true, - triggerFnName: "rtrigger", - allowGetting: true, - validKeys: ["x", "y"], - onSet: function( eles ){ - var updatedEles = eles.updateCompoundBounds(); - updatedEles.rtrigger("position"); - }, - canSet: function( ele ){ - return !ele.locked(); - } - }), - - // position but no notification to renderer - silentPosition: $$.define.data({ - field: "position", - bindingEvent: "position", - allowBinding: false, - allowSetting: true, - settingEvent: "position", - settingTriggersEvent: false, - triggerFnName: "trigger", - allowGetting: true, - validKeys: ["x", "y"], - onSet: function( eles ){ - eles.updateCompoundBounds(); - }, - canSet: function( ele ){ - return !ele.locked(); - } - }), - - positions: function( pos ){ - if( $$.is.plainObject(pos) ){ - this.position(pos); - - } else if( $$.is.fn(pos) ){ - var fn = pos; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - var pos = fn.apply(ele, [i, ele]); - - if( pos && !ele.locked() ){ - var elePos = ele._private.position; - elePos.x = pos.x; - elePos.y = pos.y; - } - } - - var updatedEles = this.updateCompoundBounds(); - - this.add( updatedEles ).rtrigger("position"); - } - - return this; // chaining - }, - - updateCompoundBounds: function(){ - var cy = this.cy(); - - if( !cy.hasCompoundNodes() ){ return cy.collection(); } // save cycles for non compound graphs - - var updated = []; - - function update( parent ){ - var children = parent.children(); - var style = parent._private.style; - var bb = children.boundingBox({ includeLabels: false, includeEdges: false }); - var padding = { - top: style["padding-top"].pxValue, - bottom: style["padding-bottom"].pxValue, - left: style["padding-left"].pxValue, - right: style["padding-right"].pxValue - }; - var pos = parent._private.position; - var didUpdate = false; - - if( style["width"].value === "auto" ){ - parent._private.autoWidth = bb.w + padding.left + padding.right; - pos.x = (bb.x1 + bb.x2 - padding.left + padding.right)/2; - didUpdate = true; - } - - if( style["height"].value === "auto" ){ - parent._private.autoHeight = bb.h + padding.top + padding.bottom; - pos.y = (bb.y1 + bb.y2 - padding.top + padding.bottom)/2; - didUpdate = true; - } - - if( didUpdate ){ - updated.push( parent ); - } - } - - // go up, level by level - var eles = this.parent(); - while( eles.nonempty() ){ - - // update each parent node in this level - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - update( ele ); - } - - // next level - eles = eles.parent(); - } - - // return changed - return new $$.Collection( cy, updated ); - }, - - // get/set the rendered (i.e. on screen) positon of the element - renderedPosition: function( dim, val ){ - var ele = this[0]; - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - var rpos = $$.is.plainObject( dim ) ? dim : undefined; - var setting = rpos !== undefined || ( val !== undefined && $$.is.string(dim) ); - - if( ele && ele.isNode() ){ // must have an element and must be a node to return position - if( setting ){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( val !== undefined ){ // set one dimension - ele._private.position[dim] = ( val - pan[dim] )/zoom; - } else if( rpos !== undefined ){ // set whole position - ele._private.position = { - x: ( rpos.x - pan.x ) /zoom, - y: ( rpos.y - pan.y ) /zoom - }; - } - } - - this.rtrigger("position"); - } else { // getting - var pos = ele._private.position; - rpos = { - x: pos.x * zoom + pan.x, - y: pos.y * zoom + pan.y - }; - - if( dim === undefined ){ // then return the whole rendered position - return rpos; - } else { // then return the specified dimension - return rpos[ dim ]; - } - } - } else if( !setting ){ - return undefined; // for empty collection case - } - - return this; // chaining - }, - - // convenience function to get a numerical value for the width of the node/edge - width: function(){ - var ele = this[0]; - - if( ele ){ - var w = ele._private.style.width; - return w.strValue === "auto" ? ele._private.autoWidth : w.pxValue; - } - }, - - outerWidth: function(){ - var ele = this[0]; - - if( ele ){ - var style = ele._private.style; - var width = style.width.strValue === "auto" ? ele._private.autoWidth : style.width.pxValue;; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return width + border; - } - }, - - renderedWidth: function(){ - var ele = this[0]; - - if( ele ){ - var width = ele.width(); - return width * this.cy().zoom(); - } - }, - - renderedOuterWidth: function(){ - var ele = this[0]; - - if( ele ){ - var owidth = ele.outerWidth(); - return owidth * this.cy().zoom(); - } - }, - - // convenience function to get a numerical value for the height of the node - height: function(){ - var ele = this[0]; - - if( ele && ele.isNode() ){ - var h = ele._private.style.height; - return h.strValue === "auto" ? ele._private.autoHeight : h.pxValue; - } - }, - - outerHeight: function(){ - var ele = this[0]; - - if( ele ){ - var style = ele._private.style; - var height = style.height.strValue === "auto" ? ele._private.autoHeight : style.height.pxValue; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return height + border; - } - }, - - renderedHeight: function(){ - var ele = this[0]; - - if( ele ){ - var height = ele.height(); - return height * this.cy().zoom(); - } - }, - - renderedOuterHeight: function(){ - var ele = this[0]; - - if( ele ){ - var oheight = ele.outerHeight(); - return oheight * this.cy().zoom(); - } - }, - - renderedBoundingBox: function( options ){ - var bb = this.boundingBox( options ); - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - - var x1 = bb.x1 * zoom + pan.x; - var x2 = bb.x2 * zoom + pan.x; - var y1 = bb.y1 * zoom + pan.y; - var y2 = bb.y2 * zoom + pan.y; - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2, - w: x2 - x1, - h: y2 - y1 - }; - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( options ){ - var eles = this; - - options = $$.util.extend({ - includeNodes: true, - includeEdges: true, - includeLabels: true - }, options); - - // recalculate projections etc - this.cy().recalculateRenderedStyle(); - - var x1 = Infinity; - var x2 = -Infinity; - var y1 = Infinity; - var y2 = -Infinity; - - // find bounds of elements - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var ex1, ex2, ey1, ey2, x, y; - var includedEle = false; - - if( ele.css("display") === "none" ){ continue; } // then ele doesn't take up space - - if( ele.isNode() && options.includeNodes ){ - includedEle = true; - - var pos = ele._private.position; - x = pos.x; - y = pos.y; - var w = ele.outerWidth(); - var halfW = w/2; - var h = ele.outerHeight(); - var halfH = h/2; - - // handle node dimensions - ///////////////////////// - - ex1 = x - halfW; - ex2 = x + halfW; - ey1 = y - halfH; - ey2 = y + halfH; - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - } else if( ele.isEdge() && options.includeEdges ){ - includedEle = true; - - var n1pos = ele.source()[0]._private.position; - var n2pos = ele.target()[0]._private.position; - - // handle edge dimensions (rough box estimate) - ////////////////////////////////////////////// - - var rstyle = ele._private.rstyle || {}; - - ex1 = n1pos.x; - ex2 = n2pos.x; - ey1 = n1pos.y; - ey2 = n2pos.y; - - if( ex1 > ex2 ){ - var temp = ex1; - ex1 = ex2; - ex2 = temp; - } - - if( ey1 > ey2 ){ - var temp = ey1; - ey1 = ey2; - ey2 = temp; - } - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - // handle points along edge (sanity check) - ////////////////////////////////////////// - - var bpts = rstyle.bezierPts || []; - var w = ele._private.style['width'].pxValue; - for( var j = 0; j < bpts.length; j++ ){ - var bpt = bpts[j]; - - x1 = bpt.x - w < x1 ? bpt.x - w : x1; - x2 = bpt.x + w > x2 ? bpt.x + w : x2; - y1 = bpt.y - w < y1 ? bpt.y - w : y1; - y2 = bpt.y + w > y2 ? bpt.y + w : y2; - } - - } - - // handle label dimensions - ////////////////////////// - - var style = ele._private.style; - var rstyle = ele._private.rstyle; - var label = style['content'].strValue; - var fontSize = style['font-size']; - var halign = style['text-halign']; - var valign = style['text-valign']; - var labelWidth = rstyle.labelWidth; - var labelHeight = rstyle.labelHeight || fontSize.pxValue; - var labelX = rstyle.labelX; - var labelY = rstyle.labelY; - - if( includedEle && options.includeLabels && label && fontSize && labelHeight != undefined && labelWidth != undefined && labelX != undefined && labelY != undefined && halign && valign ){ - var lh = labelHeight; - var lw = labelWidth; - var lx1, lx2, ly1, ly2; - - if( ele.isEdge() ){ - lx1 = labelX - lw/2; - lx2 = labelX + lw/2; - ly1 = labelY - lh/2; - ly2 = labelY + lh/2; - } else { - switch( halign.value ){ - case "left": - lx1 = labelX - lw; - lx2 = labelX; - break; - - case "center": - lx1 = labelX - lw/2; - lx2 = labelX + lw/2; - break; - - case "right": - lx1 = labelX; - lx2 = labelX + lw; - break; - } - - switch( valign.value ){ - case "top": - ly1 = labelY - lh; - ly2 = labelY; - break; - - case "center": - ly1 = labelY - lh/2; - ly2 = labelY + lh/2; - break; - - case "bottom": - ly1 = labelY; - ly2 = labelY + lh; - break; - } - } - - x1 = lx1 < x1 ? lx1 : x1; - x2 = lx2 > x2 ? lx2 : x2; - y1 = ly1 < y1 ? ly1 : y1; - y2 = ly2 > y2 ? ly2 : y2; - } - } // for - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2, - w: x2 - x1, - h: y2 - y1 - }; - } - }); - - -})( cytoscape ); - -;(function( $$ ){ "use strict"; - - // Regular degree functions (works on single element) - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeFunction(callback){ - return function(){ - var self = this; - - if( self.length === 0 ){ return; } - - if( self.isNode() && !self.removed() ){ - var degree = 0; - var node = self[0]; - var connectedEdges = node._private.edges; - - for( var i = 0; i < connectedEdges.length; i++ ){ - var edge = connectedEdges[i]; - degree += callback( node, edge ); - } - - return degree; - } else { - return; - } - }; - } - - $$.fn.eles({ - degree: defineDegreeFunction(function(node, edge){ - if( edge.source().same( edge.target() ) ){ - return 2; - } else { - return 1; - } - }), - - indegree: defineDegreeFunction(function(node, edge){ - if( edge.target().same(node) ){ - return 1; - } else { - return 0; - } - }), - - outdegree: defineDegreeFunction(function(node, edge){ - if( edge.source().same(node) ){ - return 1; - } else { - return 0; - } - }) - }); - - - // Collection degree stats - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeBoundsFunction(degreeFn, callback){ - return function(){ - var ret = undefined; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - var degree = ele[degreeFn](); - if( degree !== undefined && (ret === undefined || callback(degree, ret)) ){ - ret = degree; - } - } - - return ret; - }; - } - - $$.fn.eles({ - minDegree: defineDegreeBoundsFunction("degree", function(degree, min){ - return degree < min; - }), - - maxDegree: defineDegreeBoundsFunction("degree", function(degree, max){ - return degree > max; - }), - - minIndegree: defineDegreeBoundsFunction("indegree", function(degree, min){ - return degree < min; - }), - - maxIndegree: defineDegreeBoundsFunction("indegree", function(degree, max){ - return degree > max; - }), - - minOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, min){ - return degree < min; - }), - - maxOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, max){ - return degree > max; - }) - }); - - $$.fn.eles({ - totalDegree: function(){ - var total = 0; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - total += nodes[i].degree(); - } - - return total; - } - }); - -})( cytoscape ); - - - -;(function($$){ "use strict"; - - // Functions for binding & triggering events - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - - rtrigger: function(event, extraParams){ // for internal use only - if( this.length === 0 ){ return; } // empty collections don't need to notify anything - - // notify renderer unless removed - this.cy().notify({ - type: event, - collection: this.filter(function(){ - return !this.removed(); - }) - }); - - this.trigger(event, extraParams); - return this; - } - }); - - // aliases for those folks who like old stuff: - $$.elesfn.bind = $$.elesfn.on; - $$.elesfn.unbind = $$.elesfn.off; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - isNode: function(){ - return this.group() === "nodes"; - }, - - isEdge: function(){ - return this.group() === "edges"; - }, - - isLoop: function(){ - return this.isEdge() && this.source().id() === this.target().id(); - }, - - group: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.group; - } - } - }); - - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Functions for iterating over collections - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - each: function(fn){ - if( $$.is.fn(fn) ){ - for(var i = 0; i < this.length; i++){ - var ele = this[i]; - var ret = fn.apply( ele, [ i, ele ] ); - - if( ret === false ){ break; } // exit each early on return false - } - } - return this; - }, - - toArray: function(){ - var array = []; - - for(var i = 0; i < this.length; i++){ - array.push( this[i] ); - } - - return array; - }, - - slice: function(start, end){ - var array = []; - var thisSize = this.length; - - if( end == null ){ - end = thisSize; - } - - if( start == null ){ - start = 0; - } - - if( start < 0 ){ - start = thisSize + start; - } - - if( end < 0 ){ - end = thisSize + end; - } - - for(var i = start; i >= 0 && i < end && i < thisSize; i++){ - array.push( this[i] ); - } - - return new $$.Collection(this.cy(), array); - }, - - size: function(){ - return this.length; - }, - - eq: function(i){ - return this[i]; - }, - - empty: function(){ - return this.length === 0; - }, - - nonempty: function(){ - return !this.empty(); - }, - - sort: function( sortFn ){ - if( !$$.is.fn( sortFn ) ){ - return this; - } - - var cy = this.cy(); - var coln = new $$.Collection( cy ); - - var sorted = this.toArray().sort( sortFn ); - - return new $$.Collection(cy, sorted); - }, - - sortByZIndex: function(){ - return this.sort( $$.Collection.zIndexSort ); - } - }); - - - $$.Collection.zIndexSort = function(a, b) { - var elementDepth = function(ele) { - if (ele._private.group == "nodes") - { - return ele.parents().size(); - } - else if (ele._private.group == "edges") - { - return Math.max(ele.source()[0].parents().size(), - ele.target()[0].parents().size()); - } - else - { - return 0; - } - }; - - var result = a._private.style["z-index"].value - b._private.style["z-index"].value; - - var depthA = 0; - var depthB = 0; - - // no need to calculate element depth if there is no compound node - if ( a.cy().hasCompoundNodes() ) - { - depthA = elementDepth(a); - depthB = elementDepth(b); - } - - // if both elements has same depth, - // then edges should be drawn first - if (depthA - depthB === 0) - { - // "a" is a node, it should be drawn later - if (a._private.group === "nodes" - && b._private.group === "edges") - { - return 1; - } - - // "a" is an edge, it should be drawn first - else if (a._private.group === "edges" - && b._private.group === "nodes") - { - return -1; - } - - // both nodes or both edges - else - { - if( result === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top) - return a._private.index - b._private.index; - } else { - return result; - } - } - } - - // elements on different level - else - { - // deeper element should be drawn later - return depthA - depthB; - } - - // return zero if z-index values are not the same - return 0; - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var borderWidthMultiplier = 2 * 0.5; - var borderWidthAdjustment = 0; - - $$.fn.eles({ - - // fully updates (recalculates) the style for the elements - updateStyle: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - style.apply( this ); - - var updatedCompounds = this.updateCompoundBounds(); - - if( notifyRenderer ){ - this.add( updatedCompounds ).rtrigger("style"); // let renderer know we changed style - } else { - this.add( updatedCompounds ).trigger("style"); // just fire the event - } - return this; // chaining - }, - - // just update the mappers in the elements' styles; cheaper than eles.updateStyle() - updateMappers: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - style.updateMappers( this ); - - var updatedCompounds = this.updateCompoundBounds(); - - if( notifyRenderer ){ - this.add( updatedCompounds ).rtrigger("style"); // let renderer know we changed style - } else { - this.add( updatedCompounds ).trigger("style"); // just fire the event - } - return this; // chaining - }, - - // get the specified css property as a rendered value (i.e. on-screen value) - // or get the whole rendered style if no property specified (NB doesn't allow setting) - renderedCss: function( property ){ - var ele = this[0]; - - if( ele ){ - var renstyle = ele.cy().style().getRenderedStyle( ele ); - - if( property === undefined ){ - return renstyle; - } else { - return renstyle[ property ]; - } - } - }, - - // read the calculated css style of the element or override the style (via a bypass) - css: function( name, value ){ - var style = this.cy().style(); - - if( $$.is.plainObject(name) ){ // then extend the bypass - var props = name; - style.applyBypass( this, props ); - this.rtrigger("style"); // let the renderer know we've updated style - - } else if( $$.is.string(name) ){ - - if( value === undefined ){ // then get the property from the style - var ele = this[0]; - - if( ele ){ - return ele._private.style[ name ].strValue; - } else { // empty collection => can't get any value - return; - } - - } else { // then set the bypass with the property value - style.applyBypass( this, name, value ); - this.rtrigger("style"); // let the renderer know we've updated style - } - - } else if( name === undefined ){ - var ele = this[0]; - - if( ele ){ - return style.getRawStyle( ele ); - } else { // empty collection => can't get any value - return; - } - } - - return this; // chaining - }, - - removeCss: function(){ - var style = this.cy().style(); - var eles = this; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - style.removeAllBypasses( ele ); - } - - this.rtrigger('style'); - }, - - show: function(){ - this.css("display", "element"); - return this; // chaining - }, - - hide: function(){ - this.css("display", "none"); - return this; // chaining - }, - - visible: function(){ - var ele = this[0]; - - if( ele ){ - if( - ele.css("visibility") !== "visible" - || ele.css("display") !== "element" - // || parseFloat( ele.css("opacity") ) === 0 - ){ - return false; - } - - if( ele.isNode() ){ - var parents = ele.parents(); - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var pVis = parent.css("visibility"); - var pDis = parent.css("display"); - var pOpac = parseFloat( parent.css("opacity") ); - - if( pVis !== "visible" || pDis !== "element" ){ - return false; - } - } - - return true; - } else if( ele.isEdge() ){ - var src = ele.source(); - var tgt = ele.target(); - - return src.visible() && tgt.visible(); - } - - } - }, - - hidden: function(){ - var ele = this[0]; - - if( ele ){ - return !ele.visible(); - } - }, - - effectiveOpacity: function(){ - var ele = this[0]; - - if( ele ){ - var parentOpacity = ele._private.style.opacity.value; - var parents = ele.parents(); - - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var opacity = parent._private.style.opacity.value; - - parentOpacity = opacity * parentOpacity; - } - - return parentOpacity; - } - }, - - transparent: function(){ - var ele = this[0]; - - if( ele ){ - return ele.effectiveOpacity() === 0; - } - }, - - isFullAutoParent: function(){ - var ele = this[0]; - - if( ele ){ - var autoW = ele._private.style["width"].value === "auto"; - var autoH = ele._private.style["height"].value === "auto"; - - return ele.isParent() && autoW && autoH; - } - } - - }); - - - $$.elesfn.style = $$.elesfn.css; - $$.elesfn.renderedStyle = $$.elesfn.renderedCss; - $$.elesfn.removeStyle = $$.elesfn.removeCss; - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Collection functions that toggle a boolean value - //////////////////////////////////////////////////////////////////////////////////////////////////// - - - function defineSwitchFunction(params){ - return function(){ - var args = arguments; - - // e.g. cy.nodes().select( data, handler ) - if( args.length === 2 ){ - var data = args[0]; - var handler = args[1]; - this.bind( params.event, data, handler ); - } - - // e.g. cy.nodes().select( handler ) - else if( args.length === 1 ){ - var handler = args[0]; - this.bind( params.event, handler ); - } - - // e.g. cy.nodes().select() - else if( args.length === 0 ){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( !params.ableField || ele._private[params.ableField] ){ - ele._private[params.field] = params.value; - } - } - this.updateStyle(); // change of state => possible change of style - this.trigger(params.event); - } - - return this; - }; - } - - function defineSwitchSet( params ){ - $$.elesfn[ params.field ] = function(){ - var ele = this[0]; - if( ele ){ - return ele._private[ params.field ]; - } - }; - - $$.elesfn[ params.on ] = defineSwitchFunction({ - event: params.on, - field: params.field, - ableField: params.ableField, - value: true - }); - - $$.elesfn[ params.off ] = defineSwitchFunction({ - event: params.off, - field: params.field, - ableField: params.ableField, - value: false - }); - } - - defineSwitchSet({ - field: "locked", - on: "lock", - off: "unlock" - }); - - defineSwitchSet({ - field: "grabbable", - on: "grabify", - off: "ungrabify" - }); - - defineSwitchSet({ - field: "selected", - ableField: "selectable", - on: "select", - off: "unselect" - }); - - defineSwitchSet({ - field: "selectable", - on: "selectify", - off: "unselectify" - }); - - $$.elesfn.grabbed = function(){ - var ele = this[0]; - if( ele ){ - return ele._private.grabbed; - } - }; - - defineSwitchSet({ - field: "active", - on: "activate", - off: "unactivate" - }); - - $$.elesfn.inactive = function(){ - var ele = this[0]; - if( ele ){ - return !ele._private.active; - } - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - nodes: function(selector){ - return this.filter(function(i, element){ - return element.isNode(); - }).filter(selector); - }, - - edges: function(selector){ - return this.filter(function(i, element){ - return element.isEdge(); - }).filter(selector); - }, - - filter: function(filter){ - var cy = this._private.cy; - - if( $$.is.fn(filter) ){ - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( filter.apply(ele, [i, ele]) ){ - elements.push(ele); - } - } - - return new $$.Collection(cy, elements); - - } else if( $$.is.string(filter) || $$.is.elementOrCollection(filter) ){ - return new $$.Selector(filter).filter(this); - - } else if( filter === undefined ){ - return this; - } - - return new $$.Collection( cy ); // if not handled by above, give 'em an empty collection - }, - - not: function(toRemove){ - var cy = this._private.cy; - - if( !toRemove ){ - return this; - } else { - - if( $$.is.string( toRemove ) ){ - toRemove = this.filter( toRemove ); - } - - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var element = this[i]; - - var remove = toRemove._private.ids[ element.id() ]; - if( !remove ){ - elements.push( element ); - } - } - - return new $$.Collection( cy, elements ); - } - - }, - - intersect: function( other ){ - var self = this; - var cy = this._private.cy; - - // if a selector is specified, then filter by it - if( $$.is.string(other) ){ - var selector = other; - return this.filter( selector ); - } - - var elements = []; - var col1 = this; - var col2 = other; - var col1Smaller = this.length < other.length; - var ids1 = col1Smaller ? col1._private.ids : col2._private.ids; - var ids2 = col1Smaller ? col2._private.ids : col1._private.ids; - - for( var id in ids1 ){ - var ele = ids2[ id ]; - - if( ele ){ - elements.push( ele ); - } - } - - return new $$.Collection( cy, elements ); - }, - - add: function(toAdd){ - var self = this; - var cy = this._private.cy; - - if( !toAdd ){ - return this; - } - - if( $$.is.string(toAdd) ){ - var selector = toAdd; - toAdd = cy.elements(selector); - } - - var elements = []; - var ids = {}; - - function add(element){ - if( !element ){ - return; - } - - if( !ids[ element.id() ] ){ - elements.push( element ); - ids[ element.id() ] = true; - } - } - - // add own - for( var i = 0; i < self.length; i++ ){ - var element = self[i]; - add(element); - } - - // add toAdd - for( var i = 0; i < toAdd.length; i++ ){ - var element = toAdd[i]; - add(element); - } - - return new $$.Collection(cy, elements); - } - }); - - $$.fn.eles({ - // do a breadth first search from the nodes in the collection - // from pseudocode on wikipedia - breadthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var Q = []; - var marked = {}; - var id2depth = {}; - var connectedFrom = {}; - var connectedEles = []; - - // enqueue v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - Q.unshift( v[i] ); - - // and mark v - marked[ v[i].id() ] = true; - - id2depth[ v[i].id() ] = 0; - - connectedEles.push( v[i] ); - } - } - - i = 0; - while( Q.length !== 0 ){ // while Q not empty - var t = Q.shift(); - var depth = 0; - - var fromNodeId = connectedFrom[ t.id() ]; - while( fromNodeId ){ - depth++; - fromNodeId = connectedFrom[ fromNodeId ]; - } - - id2depth[ t.id() ] = depth; - var ret = fn.call(t, i, depth); - i++; - - // on return true, return the result - if( ret === true ){ - return new $$.Collection( cy, [ t ] ); - } - - // on return false, stop iteration - else if( ret === false ){ - break; - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - - for( var j = 0; j < adjacentEdges.length; j++ ){ - var e = adjacentEdges[j]; - var u = e.connectedNodes('[id != "' + t.id() + '"]'); - - if( u.length !== 0 ){ - u = u[0]; - - if( !marked[ u.id() ] ){ - marked[ u.id() ] = true; // mark u - Q.unshift( u ); // enqueue u onto Q - - connectedFrom[ u.id() ] = t.id(); - - connectedEles.push( u ); - connectedEles.push( e ); - } - } - } - } - - return new $$.Collection( cy, connectedEles ); // return none - }, - - // do a depth first search on the nodes in the collection - // from pseudocode on wikipedia (iterative impl) - depthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var S = []; - var discovered = []; - var forwardEdge = {}; - var backEdge = {}; - var crossEdge = {}; - var treeEdge = {}; - var explored = {}; - - function labelled(e){ - var id = e.id(); - return forwardEdge[id] || backEdge[id] || crossEdge[id] || treeEdge[id]; - } - - // push v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - S.push( v[i] ); - - // and mark discovered - discovered[ v[i].id() ] = true; - } - } - - while( S.length !== 0 ){ - var t = S[ S.length - 1 ]; - var ret = fn.call(t); - var breaked = false; - - if( ret === true ){ - return new $$.Collection( cy, [t] ); - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - for( var i = 0; i < adjacentEdges.length; i++ ){ - var e = adjacentEdges[i]; - - if( labelled(e) ){ - continue; - } - - var w = e.connectedNodes('[id != "' + t.id() + '"]'); - if( w.length !== 0 ){ - w = w[0]; - var wid = w.id(); - - if( !discovered[wid] && !explored[wid] ){ - treeEdge[wid] = true; - discovered[wid] = true; - S.push(w); - breaked = true; - break; - } else if( discovered[wid] ){ - backEdge[wid] = true; - } else { - crossEdge[wid] = true; - } - } - } - - if( !breaked ){ - explored[ t.id() ] = true; - S.pop(); - } - } - }, - - // get the root nodes in the DAG - roots: function( selector ){ - var eles = this; - var roots = []; - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - if( !ele.isNode() ){ - continue; - } - - var hasEdgesPointingIn = ele.connectedEdges('[target = "' + ele.id() + '"][source != "' + ele.id() + '"]').length > 0; - - if( !hasEdgesPointingIn ){ - roots.push( ele ); - } - } - - return new $$.Collection( this._private.cy, roots ).filter( selector ); - }, - - // kruskal's algorithm (finds min spanning tree, assuming undirected graph) - // implemented from pseudocode from wikipedia - kruskal: function( weightFn ){ - weightFn = weightFn || function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - function findSet(ele){ - for( var i = 0; i < forest.length; i++ ){ - var eles = forest[i]; - - if( eles.anySame(ele) ){ - return { - eles: eles, - index: i - }; - } - } - } - - var A = new $$.Collection(this._private.cy, []); - var forest = []; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - forest.push( nodes[i].collection() ); - } - - var edges = this.edges(); - var S = edges.toArray().sort(function(a, b){ - var weightA = weightFn.call(a); - var weightB = weightFn.call(b); - - return weightA - weightB; - }); - - for(var i = 0; i < S.length; i++){ - var edge = S[i]; - var u = edge.source()[0]; - var v = edge.target()[0]; - var setU = findSet(u); - var setV = findSet(v); - - if( setU.eles !== setV.eles ){ - A = A.add( edge ); - - forest[ setU.index ] = setU.eles.add( setV.eles ); - forest.splice( setV.index, 1 ); - } - } - - return nodes.add( A ); - - }, - - dijkstra: function( target, weightFn, directed ){ - var cy = this._private.cy; - directed = !$$.is.fn(weightFn) ? weightFn : directed; - directed = directed === undefined || directed; - weightFn = $$.is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - if( this.length === 0 || !target || !$$.is.elementOrCollection(target) || target.length === 0 ){ - return new $$.Collection(cy, []); - } - - var source = this[0]; - target = target[0]; - var dist = {}; - var prev = {}; - - var nodes = cy.nodes(); - for( var i = 0; i < nodes.length; i++ ){ - dist[ nodes[i].id() ] = Infinity; - } - - dist[ source.id() ] = 0; - var Q = nodes; - - var smallestDist = function(Q){ - var smallest = Infinity; - var index; - for(var i in dist){ - if( dist[i] < smallest && Q.$('#' + i).length !== 0 ){ - smallest = dist[i]; - index = i; - } - } - - return index; - }; - - var distBetween = function(u, v){ - var edges = u.edgesWith(v); - var smallestDistance = Infinity; - var smallestEdge; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var weight = weightFn.call(edge); - - if( weight < smallestDistance ){ - smallestDistance = weight; - smallestEdge = edge; - } - } - - return { - edge: smallestEdge, - dist: smallestDistance - }; - }; - - while( Q.length !== 0 ){ - var uid = smallestDist(Q); - var u = Q.filter('#' + uid); - - if( u.length === 0 ){ - continue; - } - - //debugger; - - Q = Q.not( u ); - - if( u.same(target) ){ - break; - } - - if( dist[uid] === Math.Infinite ){ - break; - } - - var neighbors = u.neighborhood().nodes(); - for( var i = 0; i < neighbors.length; i++ ){ - var v = neighbors[i]; - var vid = v.id() - - var duv = distBetween(u, v); - var alt = dist[uid] + duv.dist; - if( alt < dist[vid] ){ - dist[vid] = alt; - prev[vid] = { - node: v, - edge: duv.edge - }; - // TODO decrease-key v in Q - } - } - } - } - }); - - // nice, short mathemathical alias - $$.elesfn.bfs = $$.elesfn.breadthFirstSearch; - $$.elesfn.dfs = $$.elesfn.depthFirstSearch; - - - - // Neighbourhood functions - ////////////////////////// - - $$.fn.eles({ - neighborhood: function(selector){ - var elements = []; - var cy = this._private.cy; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ // for all nodes - var node = nodes[i]; - var connectedEdges = node.connectedEdges(); - - // for each connected edge, add the edge and the other node - for( var j = 0; j < connectedEdges.length; j++ ){ - var edge = connectedEdges[j]; - var otherNode = edge.connectedNodes().not(node); - - // need check in case of loop - if( otherNode.length > 0 ){ - elements.push( otherNode[0] ); // add node 1 hop away - } - - // add connected edge - elements.push( edge[0] ); - } - - } - - return ( new $$.Collection( cy, elements ) ).filter( selector ); - }, - - closedNeighborhood: function(selector){ - return this.neighborhood().add(this).filter(selector); - }, - - openNeighborhood: function(selector){ - return this.neighborhood(selector); - } - }); - - - // Edge functions - ///////////////// - - $$.fn.eles({ - source: defineSourceFunction({ - attr: "source" - }), - - target: defineSourceFunction({ - attr: "target" - }) - }); - - function defineSourceFunction( params ){ - return function( selector ){ - var sources = []; - var edges = this.edges(); - var cy = this._private.cy; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var id = edge._private.data[params.attr]; - var src = cy.getElementById( id ); - - if( src.length > 0 ){ - sources.push( src ); - } - } - - return new $$.Collection( cy, sources ).filter( selector ); - } - } - - $$.fn.eles({ - edgesWith: defineEdgesWithFunction(), - - edgesTo: defineEdgesWithFunction({ - thisIs: "source" - }) - }); - - function defineEdgesWithFunction( params ){ - - return function(otherNodes){ - var elements = []; - var cy = this._private.cy; - var p = params || {}; - - // get elements if a selector is specified - if( $$.is.string(otherNodes) ){ - otherNodes = cy.$( otherNodes ); - } - - var edges = otherNodes.connectedEdges(); - var thisIds = this._private.ids; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var foundId; - var edgeData = edge._private.data; - - if( p.thisIs ){ - var idToFind = edgeData[ p.thisIs ]; - foundId = thisIds[ idToFind ]; - } else { - foundId = thisIds[ edgeData.source ] || thisIds[ edgeData.target ]; - } - - if( foundId ){ - elements.push( edge ); - } - } - - return new $$.Collection( cy, elements ); - }; - } - - $$.fn.eles({ - connectedEdges: function( selector ){ - var retEles = []; - var cy = this._private.cy; - - var eles = this; - for( var i = 0; i < eles.length; i++ ){ - var node = eles[i]; - if( !node.isNode() ){ continue; } - - var edges = node._private.edges; - - for( var j = 0; j < edges.length; j++ ){ - var edge = edges[j]; - retEles.push( edge ); - } - } - - return new $$.Collection( cy, retEles ).filter( selector ); - }, - - connectedNodes: function( selector ){ - var retEles = []; - var cy = this._private.cy; - - var eles = this; - for( var i = 0; i < eles.length; i++ ){ - var edge = eles[i]; - if( !edge.isEdge() ){ continue; } - - retEles.push( edge.source()[0] ); - retEles.push( edge.target()[0] ); - } - - return new $$.Collection( cy, retEles ).filter( selector ); - }, - - parallelEdges: defineParallelEdgesFunction(), - - codirectedEdges: defineParallelEdgesFunction({ - codirected: true - }) - }); - - function defineParallelEdgesFunction(params){ - var defaults = { - codirected: false - }; - params = $$.util.extend({}, defaults, params); - - return function( selector ){ - var cy = this._private.cy; - var elements = []; - var edges = this.edges(); - var p = params; - - // look at all the edges in the collection - for( var i = 0; i < edges.length; i++ ){ - var edge1 = edges[i]; - var src1 = edge1.source()[0]; - var srcid1 = src1.id(); - var tgt1 = edge1.target()[0]; - var tgtid1 = tgt1.id(); - var srcEdges1 = src1._private.edges; - - // look at edges connected to the src node of this edge - for( var j = 0; j < srcEdges1.length; j++ ){ - var edge2 = srcEdges1[j]; - var edge2data = edge2._private.data; - var tgtid2 = edge2data.target; - var srcid2 = edge2data.source; - - var codirected = tgtid2 === tgtid1 && srcid2 === srcid1; - var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2; - - if( (p.codirected && codirected) - || (!p.codirected && (codirected || oppdirected)) ){ - elements.push( edge2 ); - } - } - } - - return new $$.Collection( cy, elements ).filter( selector ); - }; - - } - - - // Compound functions - ///////////////////// - - $$.fn.eles({ - parent: function( selector ){ - var parents = []; - var cy = this._private.cy; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - var parent = cy.getElementById( ele._private.data.parent ); - - if( parent.size() > 0 ){ - parents.push( parent ); - } - } - - return new $$.Collection( cy, parents ).filter( selector ); - }, - - parents: function( selector ){ - var parents = []; - - var eles = this.parent(); - while( eles.nonempty() ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - parents.push( ele ); - } - - eles = eles.parent(); - } - - return new $$.Collection( this.cy(), parents ).filter( selector ); - }, - - children: function( selector ){ - var children = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - children = children.concat( ele._private.children ); - } - - return new $$.Collection( this.cy(), children ).filter( selector ); - }, - - siblings: function( selector ){ - return this.parent().children().not( this ).filter( selector ); - }, - - isParent: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.children.length !== 0; - } - }, - - isChild: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.parent !== undefined && ele.parent().length !== 0; - } - }, - - descendants: function( selector ){ - var elements = []; - - function add( eles ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - elements.push( ele ); - - if( ele.children().nonempty() ){ - add( ele.children() ); - } - } - } - - add( this.children() ); - - return new $$.Collection( this.cy(), elements ).filter( selector ); - } - }); - - // aliases - $$.fn.eles.ancestors = $$.fn.eles.parents; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - function NullRenderer(options){ - } - - NullRenderer.prototype.notify = function(params){ - }; - - $$("renderer", "null", NullRenderer); - -})( cytoscape ); - -/* - The canvas renderer was written by Yue Dong. - - Modifications tracked on Github. -*/ - -(function($$) { "use strict"; - - function CanvasRenderer(options) { - - CanvasRenderer.CANVAS_LAYERS = 5; - CanvasRenderer.SELECT_BOX = 0; - CanvasRenderer.DRAG = 2; - CanvasRenderer.NODE = 4; - CanvasRenderer.BUFFER_COUNT = 2; - - this.options = options; - - this.data = { - - select: [undefined, undefined, undefined, undefined, 0], // Coordinates for selection box, plus enabled flag - renderer: this, cy: options.cy, container: options.cy.container(), - - canvases: new Array(CanvasRenderer.CANVAS_LAYERS), - canvasNeedsRedraw: new Array(CanvasRenderer.CANVAS_LAYERS), - - bufferCanvases: new Array(CanvasRenderer.BUFFER_COUNT) - - }; - - //--Pointer-related data - this.hoverData = {down: null, last: null, - downTime: null, triggerMode: null, - dragging: false, - initialPan: [null, null], capture: false}; - - this.timeoutData = {panTimeout: null}; - - this.dragData = {possibleDragElements: []}; - - this.touchData = {start: null, capture: false, - // These 3 fields related to tap, taphold events - startPosition: [null, null, null, null, null, null], - singleTouchStartTime: null, - singleTouchMoved: true, - - - now: [null, null, null, null, null, null], - earlier: [null, null, null, null, null, null] }; - //-- - - //--Wheel-related data - this.zoomData = {freeToZoom: false, lastPointerX: null}; - //-- - - this.redraws = 0; - - this.bindings = []; - - this.data.canvasContainer = document.createElement("div"); - var containerStyle = this.data.canvasContainer.style; - containerStyle.position = "absolute"; - containerStyle.zIndex = "0"; - - this.data.container.appendChild( this.data.canvasContainer ); - - for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) { - this.data.canvases[i] = document.createElement("canvas"); - this.data.canvases[i].style.position = "absolute"; - this.data.canvases[i].setAttribute("data-id", "layer" + i); - this.data.canvases[i].style.zIndex = String(CanvasRenderer.CANVAS_LAYERS - i); - this.data.canvasContainer.appendChild(this.data.canvases[i]); - - this.data.canvasNeedsRedraw[i] = false; - } - - this.data.canvases[CanvasRenderer.NODE].setAttribute("data-id", "layer" + CanvasRenderer.NODE + '-node'); - this.data.canvases[CanvasRenderer.SELECT_BOX].setAttribute("data-id", "layer" + CanvasRenderer.SELECT_BOX + '-selectbox'); - this.data.canvases[CanvasRenderer.DRAG].setAttribute("data-id", "layer" + CanvasRenderer.DRAG + '-drag'); - - for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) { - this.data.bufferCanvases[i] = document.createElement("canvas"); - this.data.bufferCanvases[i].style.position = "absolute"; - this.data.bufferCanvases[i].setAttribute("data-id", "buffer" + i); - this.data.bufferCanvases[i].style.zIndex = String(-i - 1); - this.data.bufferCanvases[i].style.visibility = "hidden"; - this.data.canvasContainer.appendChild(this.data.bufferCanvases[i]); - } - - this.hideEdgesOnViewport = options.hideEdgesOnViewport; - - this.load(); - } - - CanvasRenderer.panOrBoxSelectDelay = 400; - CanvasRenderer.isTouch = $$.is.touch(); - - CanvasRenderer.prototype.notify = function(params) { - switch( params.type ){ - - case "destroy": - this.destroy(); - return; - - case "add": - case "remove": - case "load": - this.updateNodesCache(); - this.updateEdgesCache(); - break; - - case "viewport": - this.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - break; - - case "style": - this.updateCachedZSortedEles(); - break; - } - - - this.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - this.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - - this.redraw(); - }; - - CanvasRenderer.prototype.destroy = function(){ - this.destroyed = true; - - for( var i = 0; i < this.bindings.length; i++ ){ - var binding = this.bindings[i]; - var b = binding; - - b.target.removeEventListener(b.event, b.handler, b.useCapture); - } - }; - - - - // copy the math functions into the renderer prototype - // unfortunately these functions are used interspersed t/o the code - // and this makes sure things work just in case a ref was missed in refactoring - // TODO remove this eventually - for( var fnName in $$.math ){ - CanvasRenderer.prototype[ fnName ] = $$.math[ fnName ]; - } - - - var debug = function(){}; - $$("renderer", "canvas", CanvasRenderer); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - var rendFunc = CanvasRenderer.prototype; - var arrowShapes = CanvasRenderer.arrowShapes = {}; - - CanvasRenderer.arrowShapeHeight = 0.3; - - // Contract for arrow shapes: - // 0, 0 is arrow tip - // (0, 1) is direction towards node - // (1, 0) is right - // - // functional api: - // collide: check x, y in shape - // roughCollide: called before collide, no false negatives - // draw: draw - // spacing: dist(arrowTip, nodeBoundary) - // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip - - arrowShapes["arrow"] = { - _points: [ - -0.15, -0.3, - 0, 0, - 0.15, -0.3 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["arrow"]._points; - -// console.log("collide(): " + direction); - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["arrow"]._farthestPointSqDistance) == "undefined") { - arrowShapes["arrow"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["arrow"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["arrow"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["arrow"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["triangle"] = arrowShapes["arrow"]; - - arrowShapes["none"] = { - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - draw: function(context) { - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return 0; - } - } - - arrowShapes["circle"] = { - _baseRadius: 0.15, - - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - // Transform x, y to get non-rotated ellipse - - if (width != height) { - // This gives negative of the angle - var angle = Math.asin(direction[1] / - (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - var rotatedPoint = - [x * cos - y * sin, - y * cos + x * sin]; - - var aspectRatio = (height + padding) / (width + padding); - y /= aspectRatio; - centerY /= aspectRatio; - - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } else { - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return true; - }, - draw: function(context) { - context.arc(0, 0, arrowShapes["circle"]._baseRadius, 0, Math.PI * 2, false); - }, - spacing: function(edge) { - return rendFunc.getArrowWidth(edge._private.style["width"].pxValue) - * arrowShapes["circle"]._baseRadius; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["inhibitor"] = { - _points: [ - -0.25, 0, - -0.25, -0.1, - 0.25, -0.1, - 0.25, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["inhibitor"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["inhibitor"]._farthestPointSqDistance) == "undefined") { - arrowShapes["inhibitor"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["inhibitor"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["inhibitor"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["inhibitor"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 4; - }, - gap: function(edge) { - return 4; - } - } - - arrowShapes["square"] = { - _points: [ - -0.12, 0.00, - 0.12, 0.00, - 0.12, -0.24, - -0.12, -0.24 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["square"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["square"]._farthestPointSqDistance) == "undefined") { - arrowShapes["square"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["square"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["square"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["square"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["diamond"] = { - _points: [ - -0.14, -0.14, - 0, -0.28, - 0.14, -0.14, - 0, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["diamond"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["diamond"]._farthestPointSqDistance) == "undefined") { - arrowShapes["diamond"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["diamond"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["diamond"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { -// context.translate(0, 0.16); - context.lineTo(-0.14, -0.14); - context.lineTo(0, -0.28); - context.lineTo(0.14, -0.14); - context.lineTo(0, 0.0); - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["tee"] = arrowShapes["inhibitor"]; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.getCachedNodes = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - if (data.cache.cachedNodes == undefined) { - data.cache.cachedNodes = cy.nodes(); - } - - return data.cache.cachedNodes; - } - - CanvasRenderer.prototype.updateNodesCache = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - data.cache.cachedNodes = cy.nodes(); - } - - CanvasRenderer.prototype.getCachedEdges = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - if (data.cache.cachedEdges == undefined) { - data.cache.cachedEdges = cy.edges(); - } - - return data.cache.cachedEdges; - } - - CanvasRenderer.prototype.updateEdgesCache = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - data.cache.cachedEdges = cy.edges(); - } - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Project mouse - CanvasRenderer.prototype.projectIntoViewport = function(pageX, pageY) { - - var n = this.data.container; - - var offsets = this.findContainerPageCoords(); - var offsetLeft = offsets[0]; - var offsetTop = offsets[1]; - -// console.log("calce"); - - // By here, offsetLeft and offsetTop represent the "pageX/pageY" of the top-left corner of the div. So, do subtraction to find relative position. - var x = pageX - offsetLeft; - var y = pageY - offsetTop; - - x -= this.data.cy.pan().x; y -= this.data.cy.pan().y; x /= this.data.cy.zoom(); y /= this.data.cy.zoom(); - return [x, y]; - } - - CanvasRenderer.prototype.findContainerPageCoords = function() { - var offsetLeft = 0; - var offsetTop = 0; - var container = this.data.container; - var n = container; - - while (n != null) { - var style = window.getComputedStyle(n); - if (typeof(n.offsetLeft) === "number") { - var position = style.getPropertyValue("position").toLowerCase(); - var borderLeft = parseFloat( style.getPropertyValue("border-left-width") ); - var borderTop = parseFloat( style.getPropertyValue("border-top-width") ); - - offsetLeft += n.offsetLeft; - offsetTop += n.offsetTop; - - if( position !== "static" || n === container ){ - offsetLeft += borderLeft; - offsetTop += borderTop; - } - - if( position === "fixed" ){ - offsetLeft += window.scrollX; - offsetTop += window.scrollY; - - break; // don't want to check any more parents after position:fixed - } - - if (n == document.body || n == document.header) { - // offsetLeft -= n.scrollLeft; - // offsetTop -= n.scrollTop; - - break; - } - } - - if( n ){ n = n.offsetParent }; - } - - // By here, offsetLeft and offsetTop represent the "pageX/pageY" of the top-left corner of the div. - return [offsetLeft, offsetTop]; - } - - // Find nearest element - CanvasRenderer.prototype.findNearestElement = function(x, y, visibleElementsOnly) { - var data = this.data; var nodes = this.getCachedNodes(); var edges = this.getCachedEdges(); var near = []; - var isTouch = CanvasRenderer.isTouch; - - var zoom = this.data.cy.zoom(); - var edgeThreshold = (isTouch ? 256 : 32) / zoom; - var nodeThreshold = (isTouch ? 16 : 0) / zoom; - - // Check nodes - for (var i = 0; i < nodes.length; i++) { - if (CanvasRenderer.nodeShapes[this.getNodeShape(nodes[i])].checkPointRough(x, y, - nodes[i]._private.style["border-width"].pxValue / 2, - this.getNodeWidth(nodes[i]) + nodeThreshold, this.getNodeHeight(nodes[i]) + nodeThreshold, - nodes[i]._private.position.x, nodes[i]._private.position.y) - && - CanvasRenderer.nodeShapes[this.getNodeShape(nodes[i])].checkPoint(x, y, - nodes[i]._private.style["border-width"].pxValue / 2, - (this.getNodeWidth(nodes[i]) + nodeThreshold), (this.getNodeHeight(nodes[i]) + nodeThreshold), - nodes[i]._private.position.x, nodes[i]._private.position.y)) { - - if (visibleElementsOnly) { - if (nodes[i]._private.style["opacity"].value != 0 - && nodes[i]._private.style["visibility"].value == "visible" - && nodes[i]._private.style["display"].value == "element") { - - near.push(nodes[i]); - } - } else { - near.push(nodes[i]); - } - } - } - - // Check edges - var addCurrentEdge; - for (var i = 0; i < edges.length; i++) { - var edge = edges[i]; - var rs = edge._private.rscratch; - - addCurrentEdge = false; - - if (rs.edgeType == "self") { - if (($$.math.inBezierVicinity(x, y, - rs.startX, - rs.startY, - rs.cp2ax, - rs.cp2ay, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - Math.pow(edge._private.style["width"].pxValue/2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue/2, 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2ax, - rs.cp2ay, - rs.selfEdgeMidX, - rs.selfEdgeMidY))) - || - ($$.math.inBezierVicinity(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].pxValue/2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue/2, 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY)))) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "straight") { - if ($$.math.inLineVicinity(x, y, rs.startX, rs.startY, rs.endX, rs.endY, edges[i]._private.style["width"].pxValue * 2) - && - Math.pow(edges[i]._private.style["width"].pxValue / 2, 2) + edgeThreshold > - $$.math.sqDistanceToFiniteLine(x, y, - rs.startX, - rs.startY, - rs.endX, - rs.endY)) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "bezier") { - if ($$.math.inBezierVicinity(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].pxValue / 2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue / 2 , 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY))) - { addCurrentEdge = true; } - } - - if (!near.length || near[near.length - 1] != edges[i]) { - if ((CanvasRenderer.arrowShapes[edges[i]._private.style["source-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0) - && - CanvasRenderer.arrowShapes[edges[i]._private.style["source-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0)) - || - (CanvasRenderer.arrowShapes[edges[i]._private.style["target-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0) - && - CanvasRenderer.arrowShapes[edges[i]._private.style["target-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0))) - { addCurrentEdge = true; } - } - - if (addCurrentEdge) { - if (visibleElementsOnly) { - // For edges, make sure the edge is visible/has nonzero opacity, - // then also make sure both source and target nodes are visible/have - // nonzero opacity - var source = data.cy.getElementById(edges[i]._private.data.source) - var target = data.cy.getElementById(edges[i]._private.data.target) - - if (edges[i]._private.style["opacity"].value != 0 - && edges[i]._private.style["visibility"].value == "visible" - && edges[i]._private.style["display"].value == "element" - && source._private.style["opacity"].value != 0 - && source._private.style["visibility"].value == "visible" - && source._private.style["display"].value == "element" - && target._private.style["opacity"].value != 0 - && target._private.style["visibility"].value == "visible" - && target._private.style["display"].value == "element") { - - near.push(edges[i]); - } - } else { - near.push(edges[i]); - } - } - } - - near.sort( this.zOrderSort ); - - if (near.length > 0) { return near[ near.length - 1 ]; } else { return null; } - } - - // "Give me everything from this box" - CanvasRenderer.prototype.getAllInBox = function(x1, y1, x2, y2) { - var data = this.data; var nodes = this.getCachedNodes(); var edges = this.getCachedEdges(); var box = []; - - var x1c = Math.min(x1, x2); var x2c = Math.max(x1, x2); var y1c = Math.min(y1, y2); var y2c = Math.max(y1, y2); x1 = x1c; x2 = x2c; y1 = y1c; y2 = y2c; var heur; - - for (var i=0;i list of edges between them - var pairId; - for (var i = 0; i < edges.length; i++){ - var edge = edges[i]; - - // ignore edges who are not to be displayed - // they shouldn't take up space - if( edge._private.style.display.value === 'none' ){ - continue; - } - - var srcId = edge._private.data.source; - var tgtId = edge._private.data.target; - - pairId = srcId > tgtId ? - tgtId + '-' + srcId : - srcId + '-' + tgtId ; - - if (hashTable[pairId] == undefined) { - hashTable[pairId] = []; - } - - hashTable[pairId].push( edge ); - pairIds.push( pairId ); - } - - var src, tgt, srcPos, tgtPos, srcW, srcH, tgtW, tgtH, srcShape, tgtShape, srcBorder, tgtBorder; - var midpt; - var vectorNormInverse; - var badBezier; - - // for each pair (src, tgt), create the ctrl pts - // Nested for loop is OK; total number of iterations for both loops = edgeCount - for (var p = 0; p < pairIds.length; p++) { - pairId = pairIds[p]; - - src = cy.getElementById( hashTable[pairId][0]._private.data.source ); - tgt = cy.getElementById( hashTable[pairId][0]._private.data.target ); - - srcPos = src._private.position; - tgtPos = tgt._private.position; - - srcW = this.getNodeWidth(src); - srcH = this.getNodeHeight(src); - - tgtW = this.getNodeWidth(tgt); - tgtH = this.getNodeHeight(tgt); - - srcShape = CanvasRenderer.nodeShapes[ this.getNodeShape(src) ]; - tgtShape = CanvasRenderer.nodeShapes[ this.getNodeShape(tgt) ]; - - srcBorder = src._private.style["border-width"].pxValue; - tgtBorder = tgt._private.style["border-width"].pxValue; - - badBezier = false; - - - if (hashTable[pairId].length > 1) { - - // pt outside src shape to calc distance/displacement from src to tgt - var srcOutside = srcShape.intersectLine( - srcPos.x, - srcPos.y, - srcW, - srcH, - tgtPos.x, - tgtPos.y, - srcBorder / 2 - ); - - // pt outside tgt shape to calc distance/displacement from src to tgt - var tgtOutside = tgtShape.intersectLine( - tgtPos.x, - tgtPos.y, - tgtW, - tgtH, - srcPos.x, - srcPos.y, - tgtBorder / 2 - ); - - var midpt = { - x: ( srcOutside[0] + tgtOutside[0] )/2, - y: ( srcOutside[1] + tgtOutside[1] )/2 - }; - - var dy = ( tgtOutside[1] - srcOutside[1] ); - var dx = ( tgtOutside[0] - srcOutside[0] ); - var l = Math.sqrt( dx*dx + dy*dy ); - - var vector = { - x: dx, - y: dy - }; - - var vectorNorm = { - x: vector.x/l, - y: vector.y/l - }; - vectorNormInverse = { - x: -vectorNorm.y, - y: vectorNorm.x - }; - - // if src intersection is inside tgt or tgt intersection is inside src, then no ctrl pts to draw - if( - tgtShape.checkPoint( srcOutside[0], srcOutside[1], tgtBorder/2, tgtW, tgtH, tgtPos.x, tgtPos.y ) || - srcShape.checkPoint( tgtOutside[0], tgtOutside[1], srcBorder/2, srcW, srcH, srcPos.x, srcPos.y ) - ){ - vectorNormInverse = {}; - badBezier = true; - } - - } - - var edge; - var rs; - - for (var i = 0; i < hashTable[pairId].length; i++) { - edge = hashTable[pairId][i]; - rs = edge._private.rscratch; - - var edgeIndex1 = rs.lastEdgeIndex; - var edgeIndex2 = i; - - var numEdges1 = rs.lastNumEdges; - var numEdges2 = hashTable[pairId].length; - - var srcX1 = rs.lastSrcCtlPtX; - var srcX2 = srcPos.x; - var srcY1 = rs.lastSrcCtlPtY; - var srcY2 = srcPos.y; - var srcW1 = rs.lastSrcCtlPtW; - var srcW2 = src.outerWidth(); - var srcH1 = rs.lastSrcCtlPtH; - var srcH2 = src.outerHeight(); - - var tgtX1 = rs.lastTgtCtlPtX; - var tgtX2 = tgtPos.x; - var tgtY1 = rs.lastTgtCtlPtY; - var tgtY2 = tgtPos.y; - var tgtW1 = rs.lastTgtCtlPtW; - var tgtW2 = tgt.outerWidth(); - var tgtH1 = rs.lastTgtCtlPtH; - var tgtH2 = tgt.outerHeight(); - - if( badBezier ){ - rs.badBezier = true; - } else { - rs.badBezier = false; - } - - if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2 - && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2 - && edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2 ){ - // console.log('edge ctrl pt cache HIT') - continue; // then the control points haven't changed and we can skip calculating them - } else { - rs.lastSrcCtlPtX = srcX2; - rs.lastSrcCtlPtY = srcY2; - rs.lastSrcCtlPtW = srcW2; - rs.lastSrcCtlPtH = srcH2; - rs.lastTgtCtlPtX = tgtX2; - rs.lastTgtCtlPtY = tgtY2; - rs.lastTgtCtlPtW = tgtW2; - rs.lastTgtCtlPtH = tgtH2; - rs.lastEdgeIndex = edgeIndex2; - rs.lastNumEdges = numEdges2; - // console.log('edge ctrl pt cache MISS') - } - - var stepSize = edge._private.style["control-point-step-size"].value; - - // Self-edge - if ( src.id() == tgt.id() ) { - - rs.edgeType = "self"; - - // New -- fix for large nodes - rs.cp2ax = srcPos.x; - rs.cp2ay = srcPos.y - (1 + Math.pow(srcH, 1.12) / 100) * stepSize * (i / 3 + 1); - - rs.cp2cx = src._private.position.x - (1 + Math.pow(srcW, 1.12) / 100) * stepSize * (i / 3 + 1); - rs.cp2cy = srcPos.y; - - rs.selfEdgeMidX = (rs.cp2ax + rs.cp2cx) / 2.0; - rs.selfEdgeMidY = (rs.cp2ay + rs.cp2cy) / 2.0; - - // Straight edge - } else if (hashTable[pairId].length % 2 == 1 - && i == Math.floor(hashTable[pairId].length / 2)) { - - rs.edgeType = "straight"; - - // Bezier edge - } else { - var distanceFromMidpoint = (0.5 - hashTable[pairId].length / 2 + i) * stepSize; - - rs.edgeType = "bezier"; - - rs.cp2x = midpt.x + vectorNormInverse.x * distanceFromMidpoint; - rs.cp2y = midpt.y + vectorNormInverse.y * distanceFromMidpoint; - - // console.log(edge, midPointX, displacementX, distanceFromMidpoint); - } - - // find endpts for edge - this.findEndpoints( edge ); - - var badStart = !$$.is.number( rs.startX ) || !$$.is.number( rs.startY ); - var badAStart = !$$.is.number( rs.arrowStartX ) || !$$.is.number( rs.arrowStartY ); - var badEnd = !$$.is.number( rs.endX ) || !$$.is.number( rs.endY ); - var badAEnd = !$$.is.number( rs.arrowEndX ) || !$$.is.number( rs.arrowEndY ); - - var minCpADistFactor = 3; - var arrowW = this.getArrowWidth( edge._private.style['width'].pxValue ) * CanvasRenderer.arrowShapeHeight; - var minCpADist = minCpADistFactor * arrowW; - var startACpDist = $$.math.distance( { x: rs.cp2x, y: rs.cp2y }, { x: rs.startX, y: rs.startY } ); - var closeStartACp = startACpDist < minCpADist; - var endACpDist = $$.math.distance( { x: rs.cp2x, y: rs.cp2y }, { x: rs.endX, y: rs.endY } ); - var closeEndACp = endACpDist < minCpADist; - - if( rs.edgeType === "bezier" ){ - var overlapping = false; - - if( badStart || badAStart || closeStartACp ){ - overlapping = true; - - // project control point along line from src centre to outside the src shape - // (otherwise intersection will yield nothing) - var cpD = { // delta - x: rs.cp2x - srcPos.x, - y: rs.cp2y - srcPos.y - }; - var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line - var cpM = { // normalised delta - x: cpD.x / cpL, - y: cpD.y / cpL - }; - var radius = Math.max(srcW, srcH); - var cpProj = { // *2 radius guarantees outside shape - x: rs.cp2x + cpM.x * 2 * radius, - y: rs.cp2y + cpM.y * 2 * radius - }; - - var srcCtrlPtIntn = srcShape.intersectLine( - srcPos.x, - srcPos.y, - srcW, - srcH, - cpProj.x, - cpProj.y, - srcBorder / 2 - ); - - if( closeStartACp ){ - rs.cp2x = rs.cp2x + cpM.x * (minCpADist - startACpDist); - rs.cp2y = rs.cp2y + cpM.y * (minCpADist - startACpDist) - } else { - rs.cp2x = srcCtrlPtIntn[0] + cpM.x * minCpADist; - rs.cp2y = srcCtrlPtIntn[1] + cpM.y * minCpADist; - } - } - - if( badEnd || badAEnd || closeEndACp ){ - overlapping = true; - - // project control point along line from tgt centre to outside the tgt shape - // (otherwise intersection will yield nothing) - var cpD = { // delta - x: rs.cp2x - tgtPos.x, - y: rs.cp2y - tgtPos.y - }; - var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line - var cpM = { // normalised delta - x: cpD.x / cpL, - y: cpD.y / cpL - }; - var radius = Math.max(srcW, srcH); - var cpProj = { // *2 radius guarantees outside shape - x: rs.cp2x + cpM.x * 2 * radius, - y: rs.cp2y + cpM.y * 2 * radius - }; - - var tgtCtrlPtIntn = tgtShape.intersectLine( - tgtPos.x, - tgtPos.y, - tgtW, - tgtH, - cpProj.x, - cpProj.y, - tgtBorder / 2 - ); - - if( closeEndACp ){ - rs.cp2x = rs.cp2x + cpM.x * (minCpADist - endACpDist); - rs.cp2y = rs.cp2y + cpM.y * (minCpADist - endACpDist); - } else { - rs.cp2x = tgtCtrlPtIntn[0] + cpM.x * minCpADist; - rs.cp2y = tgtCtrlPtIntn[1] + cpM.y * minCpADist; - } - - } - - if( overlapping ){ - // recalc endpts - this.findEndpoints( edge ); - } - } - - // project the edge into rstyle - this.projectBezier( edge ); - - } - } - - return hashTable; - } - - CanvasRenderer.prototype.findEndpoints = function(edge) { - var intersect; - - var source = edge.source()[0]; - var target = edge.target()[0]; - - var srcPos = source._private.position; - var tgtPos = target._private.position; - - var tgtArShape = edge._private.style["target-arrow-shape"].value; - var srcArShape = edge._private.style["source-arrow-shape"].value; - - var tgtBorderW = target._private.style["border-width"].pxValue; - var srcBorderW = source._private.style["border-width"].pxValue; - - var rs = edge._private.rscratch; - - if (edge._private.rscratch.edgeType == "self") { - - var cp = [rs.cp2cx, rs.cp2cy]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], - cp[1], - tgtBorderW / 2 - ); - - var arrowEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - var cp = [rs.cp2ax, rs.cp2ay]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - srcBorderW / 2 - ); - - var arrowStart = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[srcArShape].spacing(edge)); - var edgeStart = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[srcArShape].gap(edge)); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - } else if (rs.edgeType == "straight") { - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - source.position().x, - source.position().y, - tgtBorderW / 2); - - if (intersect.length == 0) { - rs.noArrowPlacement = true; - // return; - } else { - rs.noArrowPlacement = false; - } - - var arrowEnd = $$.math.shortenIntersection(intersect, - [source.position().x, source.position().y], - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, - [source.position().x, source.position().y], - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - target.position().x, - target.position().y, - srcBorderW / 2); - - if (intersect.length == 0) { - rs.noArrowPlacement = true; - // return; - } else { - rs.noArrowPlacement = false; - } - - /* - console.log("1: " - + CanvasRenderer.arrowShapes[srcArShape], - srcArShape); - */ - var arrowStart = $$.math.shortenIntersection(intersect, - [target.position().x, target.position().y], - CanvasRenderer.arrowShapes[srcArShape].spacing(edge)); - var edgeStart = $$.math.shortenIntersection(intersect, - [target.position().x, target.position().y], - CanvasRenderer.arrowShapes[srcArShape].gap(edge)); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - } else if (rs.edgeType == "bezier") { - // if( window.badArrow) debugger; - var cp = [rs.cp2x, rs.cp2y]; - - intersect = CanvasRenderer.nodeShapes[ - this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], //halfPointX, - cp[1], //halfPointY - tgtBorderW / 2 - ); - - /* - console.log("2: " - + CanvasRenderer.arrowShapes[srcArShape], - srcArShape); - */ - var arrowEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - intersect = CanvasRenderer.nodeShapes[ - this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - srcBorderW / 2 - ); - - var arrowStart = $$.math.shortenIntersection( - intersect, - cp, - CanvasRenderer.arrowShapes[srcArShape].spacing(edge) - ); - var edgeStart = $$.math.shortenIntersection( - intersect, - cp, - CanvasRenderer.arrowShapes[srcArShape].gap(edge) - ); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - // if( isNaN(rs.startX) || isNaN(rs.startY) ){ - // debugger; - // } - - } else if (rs.isArcEdge) { - return; - } - } - - // Find adjacent edges - CanvasRenderer.prototype.findEdges = function(nodeSet) { - - var edges = this.getCachedEdges(); - - var hashTable = {}; - var adjacentEdges = []; - - for (var i = 0; i < nodeSet.length; i++) { - hashTable[nodeSet[i]._private.data.id] = nodeSet[i]; - } - - for (var i = 0; i < edges.length; i++) { - if (hashTable[edges[i]._private.data.source] - || hashTable[edges[i]._private.data.target]) { - - adjacentEdges.push(edges[i]); - } - } - - return adjacentEdges; - } - - CanvasRenderer.prototype.getArrowWidth = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - CanvasRenderer.prototype.getArrowHeight = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - -// Draw edge - CanvasRenderer.prototype.drawEdge = function(context, edge, drawOverlayInstead) { - - if( !edge.visible() ){ - return; - } - - if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching - - var rs = edge._private.rscratch; - - // if bezier ctrl pts can not be calculated, then die - if( rs.badBezier ){ - return; - } - - var startNode, endNode; - - startNode = edge.source()[0]; - endNode = edge.target()[0]; - - if ( - edge._private.style["visibility"].value != "visible" - || edge._private.style["display"].value != "element" - || startNode._private.style["visibility"].value != "visible" - || startNode._private.style["display"].value != "element" - || endNode._private.style["visibility"].value != "visible" - || endNode._private.style["display"].value != "element" - ){ - return; - } - - var overlayPadding = edge._private.style["overlay-padding"].pxValue; - var overlayOpacity = edge._private.style["overlay-opacity"].value; - var overlayColor = edge._private.style["overlay-color"].value; - - // Edge color & opacity - if( drawOverlayInstead ){ - context.strokeStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - context.lineCap = "round"; - - if( edge._private.rscratch.edgeType == "self"){ - context.lineCap = "butt"; - } - - } else { - context.strokeStyle = "rgba(" - + edge._private.style["line-color"].value[0] + "," - + edge._private.style["line-color"].value[1] + "," - + edge._private.style["line-color"].value[2] + "," - + edge._private.style.opacity.value + ")"; - - - context.lineCap = "butt"; - } - - // Edge line width - if (edge._private.style["width"].pxValue <= 0) { - return; - } - - var edgeWidth = edge._private.style["width"].pxValue + (drawOverlayInstead ? 2 * overlayPadding : 0); - var lineStyle = drawOverlayInstead ? "solid" : edge._private.style["line-style"].value; - context.lineWidth = edgeWidth; - - this.findEndpoints(edge); - - if (edge._private.rscratch.edgeType == "self") { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, details.cp2ax, - details.cp2ay, details.selfEdgeMidX, details.selfEdgeMidY], - lineStyle, - edgeWidth); - - this.drawStyledEdge(edge, context, [details.selfEdgeMidX, details.selfEdgeMidY, - details.cp2cx, details.cp2cy, details.endX, details.endY], - lineStyle, - edgeWidth); - - // DEBUG: draw projected bezier pts - // context.fillStyle = 'red'; - // var bpts = edge._private.rstyle.bezierPts; - // for( var i = 0; i < bpts.length; i++ ){ - // var pt = bpts[i]; - - // context.fillRect(pt.x, pt.y, 2, 2); - // } - - } else if (edge._private.rscratch.edgeType == "straight") { - - var nodeDirectionX = endNode._private.position.x - startNode._private.position.x; - var nodeDirectionY = endNode._private.position.y - startNode._private.position.y; - - var edgeDirectionX = edge._private.rscratch.endX - edge._private.rscratch.startX; - var edgeDirectionY = edge._private.rscratch.endY - edge._private.rscratch.startY; - - if (nodeDirectionX * edgeDirectionX - + nodeDirectionY * edgeDirectionY < 0) { - - edge._private.rscratch.straightEdgeTooShort = true; - } else { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.endX, details.endY], - lineStyle, - edgeWidth); - - edge._private.rscratch.straightEdgeTooShort = false; - } - } else { - - var details = edge._private.rscratch; - - // context.fillStyle = 'rgba(255, 0, 0, 1)'; - // context.fillRect(details.startX, details.startY, 2, 2); - // context.fillRect(details.endX, details.endY, 2, 2); - - // context.fillStyle = edge._private.style['line-color'].strValue; - // context.fillRect(details.cp2x, details.cp2y, 2, 2); - - - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.cp2x, details.cp2y, details.endX, details.endY], - lineStyle, - edgeWidth); - - // DEBUG: draw projected bezier pts - // context.fillStyle = 'red'; - // var bpts = edge._private.rstyle.bezierPts; - // for( var i = 0; i < bpts.length; i++ ){ - // var pt = bpts[i]; - - // context.fillRect(pt.x, pt.y, 2, 2); - // } - - } - - if (edge._private.rscratch.noArrowPlacement !== true - && edge._private.rscratch.startX !== undefined) { - this.drawArrowheads(context, edge, drawOverlayInstead); - } - - } - - var _genPoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[4] - pt[0], 2) + Math.pow(pt[5] - pt[1], 2)); - approxLen += Math.sqrt(Math.pow((pt[4] + pt[0]) / 2 - pt[2], 2) + Math.pow((pt[5] + pt[1]) / 2 - pt[3], 2)); - - var pts = Math.ceil(approxLen / spacing); var inc = approxLen / spacing; - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = pt[0] * (1 - cur) * (1 - cur) + 2 * (pt[2]) * (1 - cur) * cur + pt[4] * (cur) * (cur); - pz[i * 2 + 1] = pt[1] * (1 - cur) * (1 - cur) + 2 * (pt[3]) * (1 - cur) * cur + pt[5] * (cur) * (cur); - } - - return pz; - } - - var _genStraightLinePoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[2] - pt[0], 2) + Math.pow(pt[3] - pt[1], 2)); - - var pts = Math.ceil(approxLen / spacing); - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - var lineOffset = [pt[2] - pt[0], pt[3] - pt[1]]; - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = lineOffset[0] * cur + pt[0]; - pz[i * 2 + 1] = lineOffset[1] * cur + pt[1]; - } - - return pz; - } - - var _genEvenOddpts = function(pt, evenspac, oddspac) { - - pt1 = _genpts(pt, evenspac); - pt2 = _genpts(pt, oddspac); - } - - - CanvasRenderer.prototype.drawStyledEdge = function( - edge, context, pts, type, width) { - - // 3 points given -> assume Bezier - // 2 -> assume straight - - var cy = this.data.cy; - var zoom = cy.zoom(); - - - // Adjusted edge width for dotted -// width = Math.max(width * 1.6, 3.4) * zoom; - - // console.log("w", width); - - if (type == "solid") { - - context.beginPath(); - context.moveTo(pts[0], pts[1]); - if (pts.length == 3 * 2) { - context.quadraticCurveTo(pts[2], pts[3], pts[4], pts[5]); - } else { - context.lineTo(pts[2], pts[3]); - } -// context.closePath(); - context.stroke(); - - } else if (type == "dotted") { - - var pt; - if (pts.length == 3 * 2) { - pt = _genPoints(pts, 16, true); - } else { - pt = _genStraightLinePoints(pts, 16, true); - } - - if (!pt) { return; } - - var dotRadius = Math.max(width * 1.6, 3.4) * zoom; - var bufW = dotRadius * 2, bufH = dotRadius * 2; - bufW = Math.max(bufW, 1); - bufH = Math.max(bufH, 1); - - var buffer = this.createBuffer(bufW, bufH); - - var context2 = buffer[1]; -// console.log(buffer); -// console.log(bufW, bufH); - - // Draw on buffer - context2.setTransform(1, 0, 0, 1, 0, 0); - context2.clearRect(0, 0, bufW, bufH); - - context2.fillStyle = context.strokeStyle; - context2.beginPath(); - context2.arc(bufW/2, bufH/2, dotRadius * 0.5, 0, Math.PI * 2, false); - context2.fill(); - - // Now use buffer - context.beginPath(); - //context.save(); - - for (var i=0; i 0) { - context.stroke(); - } - - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Draw edge text - CanvasRenderer.prototype.drawEdgeText = function(context, edge) { - - if( !edge.visible() ){ - return; - } - - if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching - - var computedSize = edge._private.style["font-size"].pxValue * edge.cy().zoom(); - var minSize = edge._private.style["min-zoomed-font-size"].pxValue; - - if( computedSize < minSize ){ - return; - } - - // Calculate text draw position - - context.textAlign = "center"; - context.textBaseline = "middle"; - - this.recalculateEdgeLabelProjection( edge ); - - var rs = edge._private.rscratch; - this.drawText(context, edge, rs.labelX, rs.labelY); - }; - - // Draw node text - CanvasRenderer.prototype.drawNodeText = function(context, node) { - - if ( !node.visible() ) { - return; - } - - var computedSize = node._private.style["font-size"].pxValue * node.cy().zoom(); - var minSize = node._private.style["min-zoomed-font-size"].pxValue; - - if( computedSize < minSize ){ - return; - } - - this.recalculateNodeLabelProjection( node ); - - var textHalign = node._private.style["text-halign"].strValue; - var textValign = node._private.style["text-valign"].strValue; - var rs = node._private.rscratch; - - switch( textHalign ){ - case "left": - context.textAlign = "right"; - break; - - case "right": - context.textAlign = "left"; - break; - - case "center": - default: - context.textAlign = "center"; - } - - switch( textValign ){ - case "top": - context.textBaseline = "bottom"; - break; - - case "bottom": - context.textBaseline = "top"; - break; - - case "center": - default: - context.textBaseline = "middle"; - } - - this.drawText(context, node, rs.labelX, rs.labelY); - }; - - // set up canvas context with font - // returns transformed text string - CanvasRenderer.prototype.setupTextStyle = function( context, element ){ - // Font style - var parentOpacity = element.effectiveOpacity(); - var style = element._private.style; - var labelStyle = style["font-style"].strValue; - var labelSize = style["font-size"].pxValue + "px"; - var labelFamily = style["font-family"].strValue; - var labelVariant = style["font-variant"].strValue; - var labelWeight = style["font-weight"].strValue; - - context.font = labelStyle + " " + labelWeight + " " - + labelSize + " " + labelFamily; - - var text = String(style["content"].value); - var textTransform = style["text-transform"].value; - - if (textTransform == "none") { - } else if (textTransform == "uppercase") { - text = text.toUpperCase(); - } else if (textTransform == "lowercase") { - text = text.toLowerCase(); - } - - // Calculate text draw position based on text alignment - - // so text outlines aren't jagged - context.lineJoin = 'round'; - - context.fillStyle = "rgba(" - + style["color"].value[0] + "," - + style["color"].value[1] + "," - + style["color"].value[2] + "," - + (style["text-opacity"].value - * style["opacity"].value * parentOpacity) + ")"; - - context.strokeStyle = "rgba(" - + style["text-outline-color"].value[0] + "," - + style["text-outline-color"].value[1] + "," - + style["text-outline-color"].value[2] + "," - + (style["text-opacity"].value - * style["opacity"].value * parentOpacity) + ")"; - - return text; - } - - // Draw text - CanvasRenderer.prototype.drawText = function(context, element, textX, textY) { - var style = element._private.style; - var parentOpacity = element.effectiveOpacity(); - if( parentOpacity === 0 ){ return; } - - var text = this.setupTextStyle( context, element ); - - if ( text != undefined && !isNaN(textX) && !isNaN(textY) ) { - var lineWidth = 2 * style["text-outline-width"].value; // *2 b/c the stroke is drawn centred on the middle - if (lineWidth > 0) { - context.lineWidth = lineWidth; - context.strokeText(text, textX, textY); - } - - context.fillText("" + text, textX, textY); - } - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Draw node - CanvasRenderer.prototype.drawNode = function(context, node, drawOverlayInstead) { - - var nodeWidth, nodeHeight; - - if ( !node.visible() ) { - return; - } - - var parentOpacity = node.effectiveOpacity(); - if( parentOpacity === 0 ){ return; } - - // context.fillStyle = "orange"; - // context.fillRect(node.position().x, node.position().y, 2, 2); - - nodeWidth = this.getNodeWidth(node); - nodeHeight = this.getNodeHeight(node); - - context.lineWidth = node._private.style["border-width"].pxValue; - - if( drawOverlayInstead === undefined || !drawOverlayInstead ){ - - // Node color & opacity - context.fillStyle = "rgba(" - + node._private.style["background-color"].value[0] + "," - + node._private.style["background-color"].value[1] + "," - + node._private.style["background-color"].value[2] + "," - + (node._private.style["background-opacity"].value - * node._private.style["opacity"].value * parentOpacity) + ")"; - - // Node border color & opacity - context.strokeStyle = "rgba(" - + node._private.style["border-color"].value[0] + "," - + node._private.style["border-color"].value[1] + "," - + node._private.style["border-color"].value[2] + "," - + (node._private.style["border-opacity"].value * node._private.style["opacity"].value * parentOpacity) + ")"; - - context.lineJoin = 'miter'; // so borders are square with the node shape - - //var image = this.getCachedImage("url"); - - var url = node._private.style["background-image"].value[2] || - node._private.style["background-image"].value[1]; - - if (url != undefined) { - - var r = this; - var image = this.getCachedImage(url, - - function() { - -// console.log(e); - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - - // Replace Image object with Canvas to solve zooming too far - // into image graphical errors (Jan 10 2013) - r.swapCachedImage(url); - - r.redraw(); - } - ); - - if (image.complete == false) { - - CanvasRenderer.nodeShapes[r.getNodeShape(node)].drawPath( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, nodeHeight); - //node._private.style["width"].value, - //node._private.style["height"].value); - - context.stroke(); - context.fillStyle = "#555555"; - context.fill(); - - } else { - //context.clip - this.drawInscribedImage(context, image, node); - } - - } else { - - // Draw node - CanvasRenderer.nodeShapes[this.getNodeShape(node)].draw( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, - nodeHeight); //node._private.data.weight / 5.0 - } - - this.drawPie(context, node); - - // Border width, draw border - if (node._private.style["border-width"].pxValue > 0) { - CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, - nodeHeight) - ; - - context.stroke(); - } - - // draw the overlay - } else { - - var overlayPadding = node._private.style["overlay-padding"].pxValue; - var overlayOpacity = node._private.style["overlay-opacity"].value; - var overlayColor = node._private.style["overlay-color"].value; - if( overlayOpacity > 0 ){ - context.fillStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - - CanvasRenderer.nodeShapes['roundrectangle'].draw( - context, - node._private.position.x, - node._private.position.y, - nodeWidth + overlayPadding * 2, - nodeHeight + overlayPadding * 2 - ); - } - } - - }; - - // does the node have at least one pie piece? - CanvasRenderer.prototype.hasPie = function(node){ - node = node[0]; // ensure ele ref - - for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N - var size = node._private.style['pie-' + i + '-background-size'].value; - - if( size > 0 ){ - return true; - } - } - - return false; - }; - - CanvasRenderer.prototype.drawPie = function(context, node){ - node = node[0]; // ensure ele ref - - if( !this.hasPie(node) ){ return; } // exit early if not needed - - var nodeW = this.getNodeWidth( node ); - var nodeH = this.getNodeHeight( node ); - var x = node._private.position.x; - var y = node._private.position.y; - var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node - var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1] - - context.save(); - - // clip to the node shape - CanvasRenderer.nodeShapes[ this.getNodeShape(node) ] - .drawPath( context, x, y, nodeW, nodeH ) - ; - context.clip(); - - for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N - var size = node._private.style['pie-' + i + '-background-size'].value; - var color = node._private.style['pie-' + i + '-background-color']; - var percent = size / 100; // map integer range [0, 100] to [0, 1] - var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise - var angleDelta = 2 * Math.PI * percent; - var angleEnd = angleStart + angleDelta; - - // slice start and end points - var sx1 = x + radius * Math.cos( angleStart ); - var sy1 = y + radius * Math.sin( angleStart ); - - // ignore if - // - zero size - // - we're already beyond the full circle - // - adding the current slice would go beyond the full circle - if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){ - continue; - } - - context.beginPath(); - context.moveTo(x, y); - context.arc( x, y, radius, angleStart, angleEnd ); - context.closePath(); - - context.fillStyle = 'rgb(' - + color.value[0] + ',' - + color.value[1] + ',' - + color.value[2] + ')' - ; - - context.fill(); - - lastPercent += percent; - } - - context.restore(); - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.getPixelRatio = function(){ - var canvas = this.data.canvases[0]; - var context = canvas.getContext("2d"); - - var backingStore = context.backingStorePixelRatio || - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || 1; - - //console.log(window.devicePixelRatio, backingStore); - - var isFirefox = typeof InstallTrigger !== 'undefined'; - - if( isFirefox ){ // because ff can't scale canvas properly - return 1; - } - - return (window.devicePixelRatio || 1) / backingStore; - } - - // Resize canvas - CanvasRenderer.prototype.matchCanvasSize = function(container) { - var data = this.data; var width = container.clientWidth; var height = container.clientHeight; - - var canvas, canvasWidth = width, canvasHeight = height; - var pixelRatio = this.getPixelRatio(); - - // apply pixel ratio - canvasWidth *= pixelRatio; - canvasHeight *= pixelRatio; - - var canvasContainer = data.canvasContainer; - canvasContainer.style.width = width + 'px'; - canvasContainer.style.height = height + 'px'; - - for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) { - - canvas = data.canvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - - canvas.style.width = width + 'px'; - canvas.style.height = height + 'px'; - } - } - - for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) { - - canvas = data.bufferCanvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - } - } - - } - - CanvasRenderer.prototype.renderTo = function( cxt, zoom, pan ){ - this.redraw({ - forcedContext: cxt, - forcedZoom: zoom, - forcedPan: pan, - drawAllLayers: true - }); - }; - - // Redraw frame - CanvasRenderer.prototype.redraw = function( options ) { - options = options || {}; - - var forcedContext = options.forcedContext; - var drawAllLayers = options.drawAllLayers; - var forcedZoom = options.forcedZoom; - var forcedPan = options.forcedPan; - var r = this; - var pixelRatio = this.getPixelRatio(); - var cy = r.data.cy; var data = r.data; - - clearTimeout( this.redrawTimeout ); - - if( this.averageRedrawTime === undefined ){ this.averageRedrawTime = 0; } - - var minRedrawLimit = 1000/60; // people can't see much better than 60fps - var maxRedrawLimit = 1000; // don't cap max b/c it's more important to be responsive than smooth - - var redrawLimit = this.averageRedrawTime; // estimate the ideal redraw limit based on how fast we can draw - redrawLimit = Math.max(minRedrawLimit, redrawLimit); - redrawLimit = Math.min(redrawLimit, maxRedrawLimit); - - //console.log('--\nideal: %i; effective: %i', this.averageRedrawTime, redrawLimit); - - if( this.lastDrawTime === undefined ){ this.lastDrawTime = 0; } - - var nowTime = +new Date; - var timeElapsed = nowTime - this.lastDrawTime; - var callAfterLimit = timeElapsed >= redrawLimit; - - if( !forcedContext ){ - if( !callAfterLimit ){ - clearTimeout( this.redrawTimeout ); - this.redrawTimeout = setTimeout(function(){ - r.redraw(); - }, redrawLimit); - return; - } - - this.lastDrawTime = nowTime; - } - - - var startTime = nowTime; - - var looperMax = 100; - //console.log('-- redraw --') - - // console.time('init'); for( var looper = 0; looper <= looperMax; looper++ ){ - - - // } console.timeEnd('init') - - function drawToContext(){ - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - - if( !forcedContext ){ - r.matchCanvasSize(data.container); - } - - var zoom = cy.zoom(); - var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom; - var pan = cy.pan(); - var effectivePan = { - x: pan.x, - y: pan.y - }; - - if( forcedPan ){ - effectivePan = forcedPan; - } - - // apply pixel ratio - effectiveZoom *= pixelRatio; - effectivePan.x *= pixelRatio; - effectivePan.y *= pixelRatio; - - var elements; - var elesInDragLayer; - var elesNotInDragLayer; - var element; - - function setContextTransform(context){ - context.setTransform(1, 0, 0, 1, 0, 0); - !forcedContext && context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - if( !drawAllLayers ){ - context.translate(effectivePan.x, effectivePan.y); - context.scale(effectiveZoom, effectiveZoom); - } - if( forcedPan ){ - context.translate(forcedPan.x, forcedPan.y); - } - if( forcedZoom ){ - context.scale(forcedZoom, forcedZoom); - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) { - //NB : VERY EXPENSIVE - //console.time('edgectlpts'); for( var looper = 0; looper <= looperMax; looper++ ){ - - if( r.hideEdgesOnViewport && (r.pinching || r.hoverData.dragging || r.data.wheel || r.swipePanning) ){ - } else { - r.findEdgeControlPoints(edges); - } - - //} console.timeEnd('edgectlpts') - - - - // console.time('sort'); for( var looper = 0; looper <= looperMax; looper++ ){ - elements = r.getCachedZSortedEles(); - // } console.timeEnd('sort') - - elesInDragLayer = []; - elesNotInDragLayer = []; - - for (var index = 0; index < elements.length; index++) { - element = elements[index]; - - if ( element._private.rscratch.inDragLayer ) { - elesInDragLayer.push( element ); - } else { - elesNotInDragLayer.push( element ); - } - } - - // console.time('updatecompounds'); for( var looper = 0; looper <= looperMax; looper++ ){ - // no need to update graph if there is no compound node - // if ( cy.hasCompoundNodes() ) - // { - // r.updateAllCompounds(elements); - // } - // } console.timeEnd('updatecompounds') - } - - - function drawElements( eleList, context ){ - var edges = []; - var nodes = []; - - for (var i = 0; i < eleList.length; i++) { - ele = eleList[i]; - - if ( ele.isNode() ) { - nodes.push( ele ); - - } else if ( ele.isEdge() ) { - r.drawEdge(context, ele); - edges.push( ele ); - } - } - - for (var i = 0; i < edges.length; i++) { - ele = edges[i]; - - r.drawEdgeText(context, ele); - r.drawEdge(context, ele, true); - } - - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - - r.drawNode(context, ele); - r.drawNodeText(context, ele); - r.drawNode(context, ele, true); - } - } - - - // console.time('drawing'); for( var looper = 0; looper <= looperMax; looper++ ){ - if (data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) { - // console.log("redrawing node layer"); - - var context = forcedContext || data.canvases[CanvasRenderer.NODE].getContext("2d"); - - setContextTransform( context ); - drawElements(elesNotInDragLayer, context); - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.NODE] = false; - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || drawAllLayers) { - - var context = forcedContext || data.canvases[CanvasRenderer.DRAG].getContext("2d"); - - setContextTransform( context ); - drawElements(elesInDragLayer, context); - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.DRAG] = false; - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] && !drawAllLayers) { - // console.log("redrawing selection box"); - - var context = forcedContext || data.canvases[CanvasRenderer.SELECT_BOX].getContext("2d"); - - setContextTransform( context ); - - var coreStyle = cy.style()._private.coreStyle; - - if (data.select[4] == 1) { - var zoom = data.cy.zoom(); - var borderWidth = coreStyle["selection-box-border-width"].value / zoom; - - context.lineWidth = borderWidth; - context.fillStyle = "rgba(" - + coreStyle["selection-box-color"].value[0] + "," - + coreStyle["selection-box-color"].value[1] + "," - + coreStyle["selection-box-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.fillRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - - if (borderWidth > 0) { - context.strokeStyle = "rgba(" - + coreStyle["selection-box-border-color"].value[0] + "," - + coreStyle["selection-box-border-color"].value[1] + "," - + coreStyle["selection-box-border-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.strokeRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - } - } - - if( data.bgActivePosistion ){ - var zoom = data.cy.zoom(); - var pos = data.bgActivePosistion; - - context.fillStyle = "rgba(" - + coreStyle["active-bg-color"].value[0] + "," - + coreStyle["active-bg-color"].value[1] + "," - + coreStyle["active-bg-color"].value[2] + "," - + coreStyle["active-bg-opacity"].value + ")"; - - context.beginPath(); - context.arc(pos.x, pos.y, coreStyle["active-bg-size"].pxValue / zoom, 0, 2 * Math.PI); - context.fill(); - } - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = false; - } - } - - // } console.timeEnd('drawing') - - var endTime = +new Date; - - if( r.averageRedrawTime === undefined ){ - r.averageRedrawTime = endTime - startTime; - } - - // use a weighted average with a bias from the previous average so we don't spike so easily - r.averageRedrawTime = r.averageRedrawTime/2 + (endTime - startTime)/2; - //console.log('actual: %i, average: %i', endTime - startTime, this.averageRedrawTime); - } - - if( !forcedContext ){ - setTimeout(drawToContext, 0); // makes direct renders to screen a bit more responsive - } else { - drawToContext(); - } - - if( !forcedContext && !r.initrender ){ - r.initrender = true; - cy.trigger('initrender'); - } - - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - -// @O Polygon drawing - CanvasRenderer.prototype.drawPolygonPath = function( - context, x, y, width, height, points) { - - //context.save(); - - - context.translate(x, y); - context.scale(width / 2, height / 2); - - context.beginPath(); - - context.moveTo(points[0], points[1]); - - for (var i = 1; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - - context.closePath(); - - context.scale(2/width, 2/height); - context.translate(-x, -y); - // context.restore(); - } - - CanvasRenderer.prototype.drawPolygon = function( - context, x, y, width, height, points) { - - // Draw path - this.drawPolygonPath(context, x, y, width, height, points); - - // Fill path - context.fill(); - } - - // Round rectangle drawing - CanvasRenderer.prototype.drawRoundRectanglePath = function( - context, x, y, width, height, radius) { - - var halfWidth = width / 2; - var halfHeight = height / 2; - var cornerRadius = $$.math.getRoundRectangleRadius(width, height); - context.translate(x, y); - - context.beginPath(); - - // Start at top middle - context.moveTo(0, -halfHeight); - // Arc from middle top to right side - context.arcTo(halfWidth, -halfHeight, halfWidth, 0, cornerRadius); - // Arc from right side to bottom - context.arcTo(halfWidth, halfHeight, 0, halfHeight, cornerRadius); - // Arc from bottom to left side - context.arcTo(-halfWidth, halfHeight, -halfWidth, 0, cornerRadius); - // Arc from left side to topBorder - context.arcTo(-halfWidth, -halfHeight, 0, -halfHeight, cornerRadius); - // Join line - context.lineTo(0, -halfHeight); - - /* - void arc(unrestricted double x, - unrestricted double y, - unrestricted double radius, - unrestricted double startAngle, - unrestricted double endAngle, - optional boolean anticlockwise = false); - */ - /* - context.arc(-width / 2 + cornerRadius, - -height / 2 + cornerRadius, - cornerRadius, - 0, - Math.PI * 2 * 0.999); - */ - - context.closePath(); - - context.translate(-x, -y); - } - - CanvasRenderer.prototype.drawRoundRectangle = function( - context, x, y, width, height, radius) { - - this.drawRoundRectanglePath(context, x, y, width, height, radius); - - context.fill(); - } - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.createBuffer = function(w, h) { - var buffer = document.createElement("canvas"); - buffer.width = w; - buffer.height = h; - - return [buffer, buffer.getContext("2d")]; - } - - CanvasRenderer.prototype.png = function( options ){ - var data = this.data; - var cy = data.cy; - var bb = cy.boundingBox(); - var width = options.full ? Math.ceil(bb.w) : this.data.container.clientWidth; - var height = options.full ? Math.ceil(bb.h) : this.data.container.clientHeight; - var buffCanvas = document.createElement("canvas"); - - buffCanvas.width = width; - buffCanvas.height = height; - - buffCanvas.style.width = width + 'px'; - buffCanvas.style.height = height + 'px'; - - var buffCxt = buffCanvas.getContext("2d"); - - // Rasterize the layers, but only if container has nonzero size - if (width > 0 && height > 0) { - - buffCxt.clearRect( 0, 0, width, height ); - - if( options.bg ){ - buffCxt.fillStyle = options.bg; - buffCxt.rect( 0, 0, width, height ); - buffCxt.fill(); - } - - buffCxt.globalCompositeOperation = "source-over"; - - if( options.full ){ // draw the full bounds of the graph - this.redraw({ - forcedContext: buffCxt, - drawAllLayers: true, - forcedZoom: 1, - forcedPan: { x: -bb.x1, y: -bb.y1 } - }); - } else { // draw the current view - this.redraw({ - forcedContext: buffCxt, - drawAllLayers: true - }); - } - } - - return buffCanvas.toDataURL("image/png"); - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.registerBinding = function(target, event, handler, useCapture){ - this.bindings.push({ - target: target, - event: event, - handler: handler, - useCapture: useCapture - }); - - target.addEventListener(event, handler, useCapture); - }; - - CanvasRenderer.prototype.load = function() { - var r = this; - - // helper function to determine which child nodes and inner edges - // of a compound node to be dragged as well as the grabbed and selected nodes - var addDescendantsToDrag = function(node, addSelected, dragElements) { - if (!addSelected) - { - var parents = node.parents(); - - // do not process descendants for this node, - // because those will be handled for the topmost selected parent - for (var i=0; i < parents.size(); i++) - { - if (parents[i]._private.selected) - { - return; - } - } - } - - var innerNodes = node.descendants(); - - var hasNonAutoParent = function(ele){ - while( ele.parent().nonempty() && ele.parent().id() !== node.id() ){ - parent = ele.parent()[0]; - var pstyle = parent._private.style; - - if( pstyle.width.value !== 'auto' || pstyle.height.value !== 'auto' ){ - return true; - } - - ele = ele.parent(); - } - - return false; - }; - - // TODO do not drag hidden children & children of hidden children? - for (var i=0; i < innerNodes.size(); i++) - { - // if addSelected is true, then add node in any case, - // if not, then add only non-selected nodes - if ( (addSelected || !innerNodes[i]._private.selected) ) - { - innerNodes[i]._private.rscratch.inDragLayer = true; - //innerNodes[i].trigger(new $$.Event(e, {type: "grab"})); - //innerNodes[i].trigger(event); - dragElements.push(innerNodes[i]); - - for (var j=0; j < innerNodes[i]._private.edges.length; j++) - { - innerNodes[i]._private.edges[j]._private.rscratch.inDragLayer = true; - } - } - } - }; - - // adds the given nodes, and its edges to the drag layer - var addNodeToDrag = function(node, dragElements) { - node._private.grabbed = true; - node._private.rscratch.inDragLayer = true; - - dragElements.push(node); - - for (var i=0;i containerPageCoords[0] && e.pageX < containerPageCoords[0] + r.data.container.clientWidth - && e.pageY > containerPageCoords[1] && e.pageY < containerPageCoords[1] + r.data.container.clientHeight) { - - } else { - return; - } - } - - var cy = r.data.cy; - var pos = r.projectIntoViewport(e.pageX, e.pageY); - var select = r.data.select; - - var near = r.findNearestElement(pos[0], pos[1], true); - var last = r.hoverData.last; - var down = r.hoverData.down; - - var disp = [pos[0] - select[2], pos[1] - select[3]]; - var nodes = r.getCachedNodes(); - var edges = r.getCachedEdges(); - - var draggedElements = r.dragData.possibleDragElements; - - - var shiftDown = e.shiftKey; - - - preventDefault = true; - - // Mousemove event - { - if (near != null) { - near - .trigger(new $$.Event(e, { - type: "mousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - - } else if (near == null) { - cy - .trigger(new $$.Event(e, { - type: "mousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } - - } - - - // trigger context drag if rmouse down - if( r.hoverData.which === 3 ){ - var cxtEvt = new $$.Event(e, { - type: "cxtdrag", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - r.hoverData.cxtDragged = true; - - // Check if we are drag panning the entire graph - } else if (r.hoverData.dragging) { - preventDefault = true; - - if( cy.panningEnabled() && cy.userPanningEnabled() ){ - var deltaP = {x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}; - - cy.panBy( deltaP ); - } - - // Needs reproject due to pan changing viewport - pos = r.projectIntoViewport(e.pageX, e.pageY); - - // Checks primary button down & out of time & mouse not moved much - } else if (select[4] == 1 && (down == null || down.isEdge()) - && ( !cy.boxSelectionEnabled() || +new Date - r.hoverData.downTime >= CanvasRenderer.panOrBoxSelectDelay ) - && (Math.abs(select[3] - select[1]) + Math.abs(select[2] - select[0]) < 4) - && cy.panningEnabled() && cy.userPanningEnabled() ) { - - r.hoverData.dragging = true; - select[4] = 0; - - } else { - // deactivate bg on box selection - if (cy.boxSelectionEnabled() && Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) > 7 && select[4]){ - clearTimeout( r.bgActiveTimeout ); - r.data.bgActivePosistion = undefined; - } - - if( down && down.isEdge() && down.active() ){ down.unactivate(); } - - if (near != last) { - - if (last) { - last.trigger( new $$.Event(e, { - type: "mouseout", - cyPosition: { x: pos[0], y: pos[1] } - }) ); - } - - if (near) { - near.trigger( new $$.Event(e, { - type: "mouseover", - cyPosition: { x: pos[0], y: pos[1] } - }) ); - } - - r.hoverData.last = near; - } - - if ( down && down.isNode() && r.nodeIsDraggable(down) ) { - r.dragData.didDrag = true; // indicate that we actually did drag the node - - r.hoverData.draggingEles = true; - - var toTrigger = []; - new $$.Collection(cy, draggedElements).positions(function(i, ele){ - // Locked nodes not draggable, as well as non-visible nodes - if (ele.isNode() && r.nodeIsDraggable(ele)) { - var pos = ele.position(); - - return { - x: pos.x + disp[0], - y: pos.y + disp[1] - }; - - toTrigger.push( ele ); - } - }); - - - (new $$.Collection(cy, toTrigger)) - .trigger("drag") - ; - - if (select[2] == select[0] && select[3] == select[1]) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - } - - if( cy.boxSelectionEnabled() ){ - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } - - // prevent the dragging from triggering text selection on the page - preventDefault = true; - } - - select[2] = pos[0]; select[3] = pos[1]; - - r.redraw(); - - if( preventDefault ){ - if(e.stopPropagation) e.stopPropagation(); - if(e.preventDefault) e.preventDefault(); - return false; - } - }, false); - - r.registerBinding(window, "mouseup", function(e) { - // console.log('--\nmouseup', e) - - var capture = r.hoverData.capture; if (!capture) { return; }; r.hoverData.capture = false; - - var cy = r.data.cy; var pos = r.projectIntoViewport(e.pageX, e.pageY); var select = r.data.select; - var near = r.findNearestElement(pos[0], pos[1], true); - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - var draggedElements = r.dragData.possibleDragElements; var down = r.hoverData.down; - var shiftDown = e.shiftKey; - - r.data.bgActivePosistion = undefined; // not active bg now - clearTimeout( r.bgActiveTimeout ); - - r.hoverData.cxtStarted = false; - r.hoverData.draggingEles = false; - - if( down ){ - down.unactivate(); - } - - if( r.hoverData.which === 3 ){ - var cxtEvt = new $$.Event(e, { - type: "cxttapend", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - if( !r.hoverData.cxtDragged ){ - var cxtTap = new $$.Event(e, { - type: "cxttap", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtTap ); - } else { - cy.trigger( cxtTap ); - } - } - - r.hoverData.cxtDragged = false; - r.hoverData.which = null; - - // if not right mouse - } else { - - // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something - if ( (down == null) // not mousedown on node - && !r.dragData.didDrag // didn't move the node around - && !(Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) > 7 && select[4]) // not box selection - && !r.hoverData.dragging // not panning - ) { - - // console.log('unselect all from bg'); - - //++clock+unselect - // var a = time(); - cy.$(':selected').unselect(); - - //++clock+unselect - // console.log("unselect", time() - a); - - if (draggedElements.length > 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - r.dragData.possibleDragElements = draggedElements = []; - } - - - // Mouseup event - { - // console.log('trigger mouseup et al'); - - if (near != null) { - near - .trigger(new $$.Event(e, { - type: "mouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapend", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } else if (near == null) { - cy - .trigger(new $$.Event(e, { - type: "mouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapend", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } - } - - // Click event - { - // console.log('trigger click et al'); - - if (Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) == 0) { - if (near != null) { - near - .trigger( new $$.Event(e, { - type: "click", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "tap", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "vclick", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - ; - } else if (near == null) { - cy - .trigger( new $$.Event(e, { - type: "click", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "tap", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "vclick", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - ; - } - } - } - - // Single selection - if (near == down && !r.dragData.didDrag) { - if (near != null && near._private.selectable) { - - // console.log('single selection') - - if( cy.selectionType() === 'additive' || shiftDown ){ - if( near.selected() ){ - near.unselect(); - } else { - near.select(); - } - } else { - if( !shiftDown ){ - cy.$(':selected').unselect(); - near.select(); - } - } - - - updateAncestorsInDragLayer(near, false); - - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - - } - // Ungrab single drag - } else if (near == down) { - if (near != null && near._private.grabbed) { - // console.log('ungrab single drag') - - var grabbedEles = cy.$(':grabbed'); - - for(var i = 0; i < grabbedEles.length; i++){ - var ele = grabbedEles[i]; - - ele._private.grabbed = false; - - var sEdges = ele._private.edges; - for (var j=0;j 7 && select[4] ) { - // console.log("box selection"); - - var newlySelected = []; - var box = r.getAllInBox(select[0], select[1], select[2], select[3]); - // console.log(box); - var event = new $$.Event(e, {type: "select"}); - for (var i=0;i 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - } - - // Cancel drag pan - r.hoverData.dragging = false; - - if (!select[4]) { - // console.log('free at end', draggedElements) - - for (var i=0;i 250) { - if (r.touchData.start) { - r.touchData.start.trigger( new $$.Event(e, { - type: "taphold", - cyPosition: { x: now[0], y: now[1] } - }) ); - } else { - r.data.cy.trigger( new $$.Event(e, { - type: "taphold", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.$(':selected').unselect(); - } - -// console.log("taphold"); - } - }, 1000); - } - - r.redraw(); - - }, false); - -// console.log = function(m){ $('#console').append('
                      '+m+'
                      '); }; - - r.registerBinding(window, "touchmove", function(e) { - - var select = r.data.select; - var capture = r.touchData.capture; //if (!capture) { return; }; - capture && e.preventDefault(); - - var cy = r.data.cy; - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - var now = r.touchData.now; var earlier = r.touchData.earlier; - - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - var disp = []; for (var j=0;j= 1.5 || distance2 >= 150 ){ - r.touchData.cxt = false; - if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; } - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - var cxtEvt = new $$.Event(e, { - type: "cxttapend", - cyPosition: { x: now[0], y: now[1] } - }); - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - } - - } - - if( capture && r.touchData.cxt ){ - var cxtEvt = new $$.Event(e, { - type: "cxtdrag", - cyPosition: { x: now[0], y: now[1] } - }); - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - if( r.touchData.start ){ r.touchData.start._private.grabbed = false; } - r.touchData.cxtDragged = true; - - //console.log('cxtdrag') - - } else if( capture && e.touches[2] && cy.boxSelectionEnabled() ){ - r.data.bgActivePosistion = undefined; - clearTimeout( this.threeFingerSelectTimeout ); - this.lastThreeTouch = +new Date; - - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if( !select || select.length === 0 || select[0] === undefined ){ - select[0] = (now[0] + now[2] + now[4])/3; - select[1] = (now[1] + now[3] + now[5])/3; - select[2] = (now[0] + now[2] + now[4])/3 + 1; - select[3] = (now[1] + now[3] + now[5])/3 + 1; - } else { - select[2] = (now[0] + now[2] + now[4])/3; - select[3] = (now[1] + now[3] + now[5])/3; - } - - select[4] = 1; - - } else if ( capture && e.touches[1] && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled() ) { // two fingers => pinch to zoom - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - // console.log('touchmove ptz'); - - // (x2, y2) for fingers 1 and 2 - var f1x2 = e.touches[0].pageX - offsetLeft, f1y2 = e.touches[0].pageY - offsetTop; - var f2x2 = e.touches[1].pageX - offsetLeft, f2y2 = e.touches[1].pageY - offsetTop; - - // console.log( f1x2, f1y2 ) - // console.log( f2x2, f2y2 ) - - var distance2 = distance( f1x2, f1y2, f2x2, f2y2 ); - var factor = distance2 / distance1; - - // console.log(distance2) - // console.log(factor) - - if( factor != 1 && twoFingersStartInside){ - - // console.log(factor) - // console.log(distance2 + ' / ' + distance1); - // console.log('--'); - - // delta finger1 - var df1x = f1x2 - f1x1; - var df1y = f1y2 - f1y1; - - // delta finger 2 - var df2x = f2x2 - f2x1; - var df2y = f2y2 - f2y1; - - // translation is the normalised vector of the two fingers movement - // i.e. so pinching cancels out and moving together pans - var tx = (df1x + df2x)/2; - var ty = (df1y + df2y)/2; - - // adjust factor by the speed multiplier - // var speed = 1.5; - // if( factor > 1 ){ - // factor = (factor - 1) * speed + 1; - // } else { - // factor = 1 - (1 - factor) * speed; - // } - - // now calculate the zoom - var zoom1 = cy.zoom(); - var zoom2 = zoom1 * factor; - var pan1 = cy.pan(); - - // the model center point converted to the current rendered pos - var ctrx = modelCenter1[0] * zoom1 + pan1.x; - var ctry = modelCenter1[1] * zoom1 + pan1.y; - - var pan2 = { - x: -zoom2/zoom1 * (ctrx - pan1.x - tx) + ctrx, - y: -zoom2/zoom1 * (ctry - pan1.y - ty) + ctry - }; - - // console.log(pan2); - // console.log(zoom2); - - cy._private.zoom = zoom2; - cy._private.pan = pan2; - cy - .trigger('pan zoom') - .notify('viewport') - ; - - distance1 = distance2; - f1x1 = f1x2; - f1y1 = f1y2; - f2x1 = f2x2; - f2y1 = f2y2; - - r.pinching = true; - } - - // Re-project - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - - } else if (e.touches[0]) { - var start = r.touchData.start; - var last = r.touchData.last; - - if ( start != null && start._private.group == "nodes" && r.nodeIsDraggable(start)) { - var draggedEles = r.dragData.touchDragEles; - - var dEleCol = new $$.Collection(cy, draggedEles).positions(function(i, draggedEle){ - if( r.nodeIsDraggable(draggedEle) ){ - r.dragData.didDrag = true; - var pos = draggedEle.position(); - - return { - x: pos.x + disp[0], - y: pos.y + disp[1] - }; - } - }); - - dEleCol - .trigger("drag") - ; - - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - - if (r.touchData.startPosition[0] == earlier[0] - && r.touchData.startPosition[1] == earlier[1]) { - - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - } - - // Touchmove event - { - if (start != null) { - start.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - start.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - start.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - - if (start == null) { - var near = r.findNearestElement(now[0], now[1], true); - - if (near != null) { - near.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - near.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - near.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - - if (near == null) { - cy.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - } - - // if (near != last) { - // if (last) { last.trigger(new $$.Event(e, {type: "touchout"})); } - // if (near) { near.trigger(new $$.Event(e, {type: "touchover"})); } - // } - - r.touchData.last = near; - } - - // Check to cancel taphold - for (var i=0;i 4) { - - r.touchData.singleTouchMoved = true; - } - } - - if ( capture && (start == null || start.isEdge()) && cy.panningEnabled() && cy.userPanningEnabled() ) { - if( start ){ - start.unactivate(); - - if( !r.data.bgActivePosistion ){ - r.data.bgActivePosistion = { - x: now[0], - y: now[1] - }; - } - - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } - - cy.panBy({x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}); - r.swipePanning = true; - - // Re-project - var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); - now[0] = pos[0]; now[1] = pos[1]; - } - } - - for (var j=0;j 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - //}, 100); - } - - if( !e.touches[1] ){ - r.pinching = false; - } - - var updateStartStyle = false; - - if( start != null ){ - start._private.active = false; - updateStartStyle = true; - start.trigger("unactivate"); - } - - if (e.touches[2]) { - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } else if (e.touches[1]) { - - } else if (e.touches[0]) { - - // Last touch released - } else if (!e.touches[0]) { - - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if (start != null ) { - - if (start._private.grabbed == true) { - start._private.grabbed = false; - start.trigger("free"); - start._private.rscratch.inDragLayer = false; - } - - var sEdges = start._private.edges; - for (var j=0;j cells ){ - var sm = small(); - var lg = large(); - - // reducing the small side takes away the most cells, so try it first - if( (sm - 1) * lg >= cells ){ - small(sm - 1); - } else if( (lg - 1) * sm >= cells ){ - large(lg - 1); - } - } else { - - // if rounding was too low, add rows or columns - while( cols * rows < cells ){ - var sm = small(); - var lg = large(); - - // try to add to larger side first (adds less in multiplication) - if( (lg + 1) * sm >= cells ){ - large(lg + 1); - } else { - small(sm + 1); - } - } - } - - var cellWidth = width / cols; - var cellHeight = height / rows; - - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - var w = node.outerWidth(); - var h = node.outerHeight(); - - cellWidth = Math.max( cellWidth, w ); - cellHeight = Math.max( cellHeight, h ); - } - - var cellUsed = {}; // e.g. 'c-0-2' => true - - var used = function(row, col){ - return cellUsed['c-' + row + '-' + col] ? true : false; - }; - - var use = function(row, col){ - cellUsed['c-' + row + '-' + col] = true; - }; - - // to keep track of current cell position - var row = 0; - var col = 0; - var moveToNextCell = function(){ - col++; - if( col >= cols ){ - col = 0; - row++; - } - }; - - // get a cache of all the manual positions - var id2manPos = {}; - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - var rcPos = options.position( node ); - - if( rcPos && (rcPos.row !== undefined || rcPos.col !== undefined) ){ // must have at least row or col def'd - var pos = { - row: rcPos.row, - col: rcPos.col - }; - - if( pos.col === undefined ){ // find unused col - pos.col = 0; - - while( used(pos.row, pos.col) ){ - pos.col++; - } - } else if( pos.row === undefined ){ // find unused row - pos.row = 0; - - while( used(pos.row, pos.col) ){ - pos.row++; - } - } - - id2manPos[ node.id() ] = pos; - use( pos.row, pos.col ); - } - } - - - var atLeastOneManSet = false; - nodes.positions(function(i, element){ - var x, y; - - if( element.locked() || element.isFullAutoParent() ){ - return false; - } - - // see if we have a manual position set - var rcPos = id2manPos[ element.id() ]; - if( rcPos ){ - x = rcPos.col * cellWidth + cellWidth/2; - y = rcPos.row * cellHeight + cellHeight/2; - - } else { // otherwise set automatically - - while( used(row, col) ){ - moveToNextCell(); - } - - x = col * cellWidth + cellWidth/2; - y = row * cellHeight + cellHeight/2; - use( row, col ); - - moveToNextCell(); - } - - return { x: x, y: y }; - - }); - } - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - GridLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "grid", GridLayout); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit to viewport - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - positions: undefined, // map of (node id) => (position obj) - zoom: undefined, // the zoom level to set (prob want fit = false if set) - pan: undefined, // the pan level to set (prob want fit = false if set) - padding: 30 // padding on fit - }; - - function PresetLayout( options ){ - this.options = $$.util.extend(true, {}, defaults, options); - } - - PresetLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - function getPosition(node){ - if( options.positions == null ){ - return null; - } - - if( options.positions[node._private.data.id] == null ){ - return null; - } - - return options.positions[node._private.data.id]; - } - - nodes.positions(function(i, node){ - var position = getPosition(node); - - if( node.locked() || position == null ){ - return false; - } - - return position; - }); - - if( options.pan != null ){ - cy.pan( options.pan ); - } - - if( options.zoom != null ){ - cy.zoom( options.zoom ); - } - - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - if( options.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - $$("layout", "preset", PresetLayout); - - $$("core", "presetLayout", function(){ - var cy = this; - var layout = {}; - var elements = {}; - - cy.nodes().each(function(i, ele){ - elements[ ele.data("id") ] = ele.position(); - }); - - layout.positions = elements; - layout.name = "preset"; - layout.zoom = cy.zoom(); - layout.pan = cy.pan(); - - return layout; - }); - -})(cytoscape); - -;(function($$){ "use strict"; - - var defaults = { - liveUpdate: true, // whether to show the layout as it's running - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - maxSimulationTime: 4000, // max length in ms to run the layout - fit: true, // reset viewport to fit default simulationBounds - padding: [ 50, 50, 50, 50 ], // top, right, bottom, left - simulationBounds: undefined, // [x1, y1, x2, y2]; [0, 0, width, height] by default - ungrabifyWhileSimulating: true, // so you can't drag nodes during layout - - // forces used by arbor (use arbor default on undefined) - repulsion: undefined, - stiffness: undefined, - friction: undefined, - gravity: true, - fps: undefined, - precision: undefined, - - // static numbers or functions that dynamically return what these - // values should be for each element - nodeMass: undefined, - edgeLength: undefined, - - stepSize: 1, // size of timestep in simulation - - // function that returns true if the system is stable to indicate - // that the layout can be stopped - stableEnergy: function( energy ){ - var e = energy; - return (e.max <= 0.5) || (e.mean <= 0.3); - } - }; - - function ArborLayout(options){ - this.options = $$.util.extend({}, defaults, options); - } - - ArborLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - var simulationBounds = options.simulationBounds; - - if( options.simulationBounds ){ - width = simulationBounds[2] - simulationBounds[0]; // x2 - x1 - height = simulationBounds[3] - simulationBounds[1]; // y2 - y1 - } else { - options.simulationBounds = [ - 0, - 0, - width, - height - ]; - } - - // make nice x & y fields - var simBB = options.simulationBounds; - simBB.x1 = simBB[0]; - simBB.y1 = simBB[1]; - simBB.x2 = simBB[2]; - simBB.y2 = simBB[3]; - - // arbor doesn't work with just 1 node - if( cy.nodes().size() <= 1 ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().position({ - x: Math.round( (simBB.x1 + simBB.x2)/2 ), - y: Math.round( (simBB.y1 + simBB.y2)/2 ) - }); - - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - - return; - } - - var sys = this.system = arbor.ParticleSystem(options.repulsion, options.stiffness, options.friction, options.gravity, options.fps, options.dt, options.precision); - this.system = sys; - - if( options.liveUpdate && options.fit ){ - cy.reset(); - }; - - var doneTime = 250; - var doneTimeout; - - var ready = false; - - var lastDraw = +new Date; - var sysRenderer = { - init: function(system){ - }, - redraw: function(){ - var energy = sys.energy(); - - // if we're stable (according to the client), we're done - if( options.stableEnergy != null && energy != null && energy.n > 0 && options.stableEnergy(energy) ){ - sys.stop(); - return; - } - - clearTimeout(doneTimeout); - doneTimeout = setTimeout(doneHandler, doneTime); - - var movedNodes = []; - - sys.eachNode(function(n, point){ - var id = n.name; - var data = n.data; - var node = data.element; - - if( node == null ){ - return; - } - - if( !node.locked() && !node.grabbed() ){ - node.silentPosition({ - x: simBB.x1 + point.x, - y: simBB.y1 + point.y - }); - - movedNodes.push( node ); - } - }); - - - var timeToDraw = (+new Date - lastDraw) >= 16; - if( options.liveUpdate && movedNodes.length > 0 && timeToDraw ){ - new $$.Collection(cy, movedNodes).rtrigger("position"); - lastDraw = +new Date; - } - - - if( !ready ){ - ready = true; - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - } - } - - }; - sys.renderer = sysRenderer; - sys.screenSize( width, height ); - sys.screenPadding( options.padding[0], options.padding[1], options.padding[2], options.padding[3] ); - sys.screenStep( options.stepSize ); - - function calculateValueForElement(element, value){ - if( value == null ){ - return undefined; - } else if( typeof value == typeof function(){} ){ - return value.apply(element, [element._private.data, { - nodes: nodes.length, - edges: edges.length, - element: element - }]); - } else { - return value; - } - } - - // TODO we're using a hack; sys.toScreen should work :( - function fromScreen(pos){ - var x = pos.x; - var y = pos.y; - var w = width; - var h = height; - - var left = -2; - var right = 2; - var top = -2; - var bottom = 2; - - var d = 4; - - return { - x: x/w * d + left, - y: y/h * d + right - }; - } - - var grabHandler = function(e){ - grabbed = this; - var pos = sys.fromScreen( this.position() ); - var p = arbor.Point(pos.x, pos.y); - this.scratch().arbor.p = p; - - switch( e.type ){ - case "grab": - this.scratch().arbor.fixed = true; - break; - case "dragstop": - this.scratch().arbor.fixed = false; - this.scratch().arbor.tempMass = 1000 - break; - } - }; - nodes.bind("grab drag dragstop", grabHandler); - - nodes.each(function(i, node){ - if( this.isFullAutoParent() ){ return; } // they don't exist in the sim - - var id = this._private.data.id; - var mass = calculateValueForElement(this, options.nodeMass); - var locked = this._private.locked; - - if( node.isFullAutoParent() ){ - return; - } - - var pos = fromScreen({ - x: node.position().x, - y: node.position().y - }); - - if( node.locked() ){ - return; - } - - this.scratch().arbor = sys.addNode(id, { - element: this, - mass: mass, - fixed: locked, - x: locked ? pos.x : undefined, - y: locked ? pos.y : undefined - }); - }); - - edges.each(function(){ - var id = this.id(); - var src = this.source().id(); - var tgt = this.target().id(); - var length = calculateValueForElement(this, options.edgeLength); - - this.scratch().arbor = sys.addEdge(src, tgt, { - length: length - }); - }); - - function packToCenter(callback){ - // TODO implement this for IE :( - - if( options.fit ){ - cy.fit(); - } - callback(); - }; - - var grabbableNodes = nodes.filter(":grabbable"); - // disable grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.ungrabify(); - } - - var doneHandler = function(){ - if( window.isIE ){ - packToCenter(function(){ - done(); - }); - } else { - done(); - } - - function done(){ - if( !options.liveUpdate ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().rtrigger("position"); - } - - // unbind handlers - nodes.unbind("grab drag dragstop", grabHandler); - - // enable back grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.grabify(); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - } - }; - - sys.start(); - setTimeout(function(){ - sys.stop(); - }, options.maxSimulationTime); - - }; - - ArborLayout.prototype.stop = function(){ - if( this.system != null ){ - system.stop(); - } - }; - - $$("layout", "arbor", ArborLayout); - - -})(cytoscape); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - rStepSize: 10, // the step size for increasing the radius if the nodes don't fit on screen - padding: 30, // the padding on fit - startAngle: 3/2 * Math.PI, // the position of the first node - counterclockwise: false // whether the layout should go counterclockwise (true) or clockwise (false) - }; - - function CircleLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - CircleLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes().filter(function(){ - return !this.isFullAutoParent(); - }); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var center = { - x: width/2, - y: height/2 - }; - - var padding = 50; - - var theta = options.startAngle; - var dTheta = 2 * Math.PI / nodes.length; - var maxNodeSize = 0; - - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - - maxNodeSize = Math.max( node.outerWidth(), node.outerHeight() ); - } - - var r = width/2 - maxNodeSize; - - function distanceBetweenNodes(){ - var t1 = 0; - var t2 = dTheta; - - var p1 = { - x: center.x + r * Math.cos(t1), - y: center.y + r * Math.sin(t1) - }; - - var p2 = { - x: center.x + r * Math.cos(t2), - y: center.y + r * Math.sin(t2) - }; - - var dist = Math.sqrt( (p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y) ); - - return dist; - } - - while( distanceBetweenNodes() < maxNodeSize && !(nodes.length < 2) ){ - r += options.rStepSize; - } - - - var i = 0; - nodes.positions(function(){ - var node = this; - var rx = r * Math.cos( theta ); - var ry = r * Math.sin( theta ); - var pos = { - x: center.x + rx, - y: center.y + ry - }; - - i++; - theta = options.counterclockwise ? theta - dTheta : theta + dTheta; - return pos; - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - CircleLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "circle", CircleLayout); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - directed: true, // whether the tree is directed downwards (or edges can point in any direction if false) - padding: 30, // padding on fit - circle: false, // put depths in concentric circles if true, put depths top down if false - roots: undefined, // the roots of the trees - maximalAdjustments: 0 // how many times to try to position the nodes in a maximal way (i.e. no backtracking) - }; - - function BreadthFirstLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - BreadthFirstLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var roots; - if( $$.is.elementOrCollection(options.roots) ){ - roots = options.roots; - } else if( $$.is.array(options.roots) ){ - var rootsArray = []; - - for( var i = 0; i < options.roots.length; i++ ){ - var id = options.roots[i]; - var ele = cy.getElementById( id ); - roots.push( ele ); - } - - roots = new $$.Collection( cy, rootsArray ); - } else { - roots = nodes.roots(); - } - - - var depths = []; - var foundByBfs = {}; - var id2depth = {}; - - // find the depths of the nodes - roots.bfs(function(i, depth){ - var ele = this[0]; - - if( !depths[depth] ){ - depths[depth] = []; - } - - depths[depth].push( ele ); - foundByBfs[ ele.id() ] = true; - id2depth[ ele.id() ] = depth; - }, options.directed); - - // check for nodes not found by bfs - var orphanNodes = []; - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - - if( foundByBfs[ ele.id() ] ){ - continue; - } else { - orphanNodes.push( ele ); - } - } - - // assign orphan nodes a depth from their neighborhood - var maxChecks = orphanNodes.length * 3; - var checks = 0; - while( orphanNodes.length !== 0 && checks < maxChecks ){ - var node = orphanNodes.shift(); - var neighbors = node.neighborhood().nodes(); - var assignedDepth = false; - - for( var i = 0; i < neighbors.length; i++ ){ - var depth = id2depth[ neighbors[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ - orphanNodes.push( node ); - } - - checks++; - } - - // assign orphan nodes that are still left to the depth of their subgraph - while( orphanNodes.length !== 0 ){ - var node = orphanNodes.shift(); - var subgraph = node.bfs(); - var assignedDepth = false; - - for( var i = 0; i < subgraph.length; i++ ){ - var depth = id2depth[ subgraph[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0 - if( depths.length === 0 ){ - depths.push([]); - } - - depths[0].push( node ); - } - } - - // assign the nodes a depth and index - var assignDepthsToEles = function(){ - for( var i = 0; i < depths.length; i++ ){ - var eles = depths[i]; - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - - ele._private.scratch.BreadthFirstLayout = { - depth: i, - index: j - }; - } - } - }; - assignDepthsToEles(); - - // make maximal if so set by adjusting depths - for( var adj = 0; adj < options.maximalAdjustments; adj++ ){ - - var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth - var edges = node.connectedEdges('[target = "' + node.id() + '"]'); - var thisInfo = node._private.scratch.BreadthFirstLayout; - var highestDepthOfOther = 0; - var highestOther; - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var otherNode = edge.source()[0]; - var otherInfo = otherNode._private.scratch.BreadthFirstLayout; - - if( thisInfo.depth < otherInfo.depth && highestDepthOfOther < otherInfo.depth ){ - highestDepthOfOther = otherInfo.depth; - highestOther = otherNode; - } - } - - return highestOther; - }; - - var nDepths = depths.length; - var elesToMove = []; - for( var i = 0; i < nDepths; i++ ){ - var depth = depths[i]; - - var nDepth = depth.length; - for( var j = 0; j < nDepth; j++ ){ - var ele = depth[j]; - var info = ele._private.scratch.BreadthFirstLayout; - var intEle = intersectsDepth(ele); - - if( intEle ){ - info.intEle = intEle; - elesToMove.push( ele ); - } - } - } - - for( var i = 0; i < elesToMove.length; i++ ){ - var ele = elesToMove[i]; - var info = ele._private.scratch.BreadthFirstLayout; - var intEle = info.intEle; - var intInfo = intEle._private.scratch.BreadthFirstLayout; - - depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index - - // add to end of new depth - var newDepth = intInfo.depth + 1; - while( newDepth > depths.length - 1 ){ - depths.push([]); - } - depths[ newDepth ].push( ele ); - - info.depth = newDepth; - info.index = depths[newDepth].length - 1; - } - - assignDepthsToEles(); - } - - // find min distance we need to leave between nodes - var minDistance = 0; - for( var i = 0; i < nodes.length; i++ ){ - var w = nodes[i].outerWidth(); - var h = nodes[i].outerHeight(); - - minDistance = Math.max(minDistance, w, h); - } - minDistance *= 1.75; // just to have some nice spacing - - // get the weighted percent for an element based on its connectivity to other levels - var cachedWeightedPercent = {}; - var getWeightedPercent = function( ele ){ - if( cachedWeightedPercent[ ele.id() ] ){ - return cachedWeightedPercent[ ele.id() ]; - } - - var eleDepth = ele._private.scratch.BreadthFirstLayout.depth; - var neighbors = ele.neighborhood().nodes(); - var percent = 0; - var samples = 0; - - for( var i = 0; i < neighbors.length; i++ ){ - var neighbor = neighbors[i]; - var nEdges = neighbor.edgesWith( ele ); - var index = neighbor._private.scratch.BreadthFirstLayout.index; - var depth = neighbor._private.scratch.BreadthFirstLayout.depth; - var nDepth = depths[depth].length; - - if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above - percent += index / nDepth; - samples++; - } - } - - samples = Math.max(1, samples); - percent = percent / samples; - - if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting - percent = undefined; - } - - cachedWeightedPercent[ ele.id() ] = percent; - return percent; - }; - - // rearrange the indices in each depth level based on connectivity - for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result - - for( var i = 0; i < depths.length; i++ ){ - var depth = i; - var newDepths = []; - - depths[i] = depths[i].sort(function(a, b){ - var apct = getWeightedPercent( a ); - var bpct = getWeightedPercent( b ); - - - return apct - bpct; - }); - } - assignDepthsToEles(); // and update - - } - - var center = { - x: width/2, - y: height/2 - }; - nodes.positions(function(){ - var ele = this[0]; - var info = ele._private.scratch.BreadthFirstLayout; - var depth = info.depth; - var index = info.index; - - var distanceX = Math.max( width / (depths[depth].length + 1), minDistance ); - var distanceY = Math.max( height / (depths.length + 1), minDistance ); - var radiusStepSize = Math.min( width / 2 / depths.length, height / 2 / depths.length ); - radiusStepSize = Math.max( radiusStepSize, minDistance ); - - if( options.circle ){ - var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0); - var theta = 2 * Math.PI / depths[depth].length * index; - - if( depth === 0 && depths[0].length === 1 ){ - radius = 1; - } - - return { - x: center.x + radius * Math.cos(theta), - y: center.y + radius * Math.sin(theta) - }; - - } else { - return { - x: (index + 1) * distanceX, - y: (depth + 1) * distanceY - }; - } - - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - BreadthFirstLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "breadthfirst", BreadthFirstLayout); - -})( cytoscape ); - -/* - The CoSE layout was written by Gerardo Huck. - - Modifications tracked on Github. -*/ - -;(function($$) { "use strict"; - - var DEBUG; - - /** - * @brief : default layout options - */ - var defaults = { - // Called on `layoutready` - ready : function() {}, - - // Called on `layoutstop` - stop : function() {}, - - // Number of iterations between consecutive screen positions update (0 -> only updated on the end) - refresh : 0, - - // Whether to fit the network view after when done - fit : true, - - // Padding on fit - padding : 30, - - - // Whether to randomize node positions on the beginning - randomize : true, - - // Whether to use the JS console to print debug messages - debug : false, - - // Node repulsion (non overlapping) multiplier - nodeRepulsion : 10000, - - // Node repulsion (overlapping) multiplier - nodeOverlap : 10, - - // Ideal edge (non nested) length - idealEdgeLength : 10, - - // Divisor to compute edge forces - edgeElasticity : 100, - - // Nesting factor (multiplier) to compute ideal edge length for nested edges - nestingFactor : 5, - - // Gravity force (constant) - gravity : 250, - - // Maximum number of iterations to perform - numIter : 100, - - // Initial temperature (maximum node displacement) - initialTemp : 200, - - // Cooling factor (how the temperature is reduced between consecutive iterations - coolingFactor : 0.95, - - // Lower temperature threshold (below this point the layout will end) - minTemp : 1 - }; - - - /** - * @brief : constructor - * @arg options : object containing layout options - */ - function CoseLayout(options) { - this.options = $$.util.extend({}, defaults, options); - } - - - /** - * @brief : runs the layout - */ - CoseLayout.prototype.run = function() { - var options = this.options; - var cy = options.cy; - - // Set DEBUG - Global variable - if (true == options.debug) { - DEBUG = true; - } else { - DEBUG = false; - } - - // Get start time - var startTime = new Date(); - - // Initialize layout info - var layoutInfo = createLayoutInfo(cy, options); - - // Show LayoutInfo contents if debugging - if (DEBUG) { - printLayoutInfo(layoutInfo); - } - - // If required, randomize node positions - if (true == options.randomize) { - randomizePositions(layoutInfo, cy); - - if (0 < options.refresh) { - refreshPositions(layoutInfo, cy, options); - } - } - - updatePositions(layoutInfo, cy, options); - - // Main loop - for (var i = 0; i < options.numIter; i++) { - // Do one step in the phisical simulation - step(layoutInfo, cy, options, i); - - // If required, update positions - if (0 < options.refresh && 0 == (i % options.refresh)) { - refreshPositions(layoutInfo, cy, options); - } - - // Update temperature - layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor; - logDebug("New temperature: " + layoutInfo.temperature); - - if (layoutInfo.temperature < options.minTemp) { - logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i); - break; - } - } - - refreshPositions(layoutInfo, cy, options); - - // Fit the graph if necessary - if (true == options.fit) { - cy.fit( options.padding ); - } - - // Get end time - var endTime = new Date(); - - console.info("Layout took " + (endTime - startTime) + " ms"); - - // Layout has finished - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - - /** - * @brief : called on continuous layouts to stop them before they finish - */ - CoseLayout.prototype.stop = function(){ - var options = this.options; - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - - /** - * @brief : Creates an object which is contains all the data - * used in the layout process - * @arg cy : cytoscape.js object - * @return : layoutInfo object initialized - */ - var createLayoutInfo = function(cy, options) { - var layoutInfo = { - layoutNodes : [], - idToIndex : {}, - nodeSize : cy.nodes().size(), - graphSet : [], - indexToGraph : [], - layoutEdges : [], - edgeSize : cy.edges().size(), - temperature : options.initialTemp - }; - - // Shortcut - var nodes = cy.nodes(); - - // Iterate over all nodes, creating layout nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var tempNode = {}; - tempNode.id = nodes[i].data('id'); - tempNode.parentId = nodes[i].data('parent'); - tempNode.children = []; - tempNode.positionX = nodes[i].position('x'); - tempNode.positionY = nodes[i].position('y'); - tempNode.offsetX = 0; - tempNode.offsetY = 0; - tempNode.height = nodes[i].height(); - tempNode.width = nodes[i].width(); - tempNode.maxX = tempNode.positionX + tempNode.width / 2; - tempNode.minX = tempNode.positionX - tempNode.width / 2; - tempNode.maxY = tempNode.positionY + tempNode.height / 2; - tempNode.minY = tempNode.positionY - tempNode.height / 2; - tempNode.padLeft = nodes[i]._private.style['padding-left'].pxValue; - tempNode.padRight = nodes[i]._private.style['padding-right'].pxValue; - tempNode.padTop = nodes[i]._private.style['padding-top'].pxValue; - tempNode.padBottom = nodes[i]._private.style['padding-bottom'].pxValue; - - // Add new node - layoutInfo.layoutNodes.push(tempNode); - // Add entry to id-index map - layoutInfo.idToIndex[tempNode.id] = i; - } - - // Inline implementation of a queue, used for traversing the graph in BFS order - var queue = []; - var start = 0; // Points to the start the queue - var end = -1; // Points to the end of the queue - - var tempGraph = []; - - // Second pass to add child information and - // initialize queue for hierarchical traversal - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - var p_id = n.parentId; - // Check if node n has a parent node - if (undefined != p_id) { - // Add node Id to parent's list of children - layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id); - } else { - // If a node doesn't have a parent, then it's in the root graph - queue[++end] = n.id; - tempGraph.push(n.id); - } - } - - // Add root graph to graphSet - layoutInfo.graphSet.push(tempGraph); - - // Traverse the graph, level by level, - while (start <= end) { - // Get the node to visit and remove it from queue - var node_id = queue[start++]; - var node_ix = layoutInfo.idToIndex[node_id]; - var node = layoutInfo.layoutNodes[node_ix]; - var children = node.children; - if (children.length > 0) { - // Add children nodes as a new graph to graph set - layoutInfo.graphSet.push(children); - // Add children to que queue to be visited - for (var i = 0; i < children.length; i++) { - queue[++end] = children[i]; - } - } - } - - // Create indexToGraph map - for (var i = 0; i < layoutInfo.graphSet.length; i++) { - var graph = layoutInfo.graphSet[i]; - for (var j = 0; j < graph.length; j++) { - var index = layoutInfo.idToIndex[graph[j]]; - layoutInfo.indexToGraph[index] = i; - } - } - - // Shortcut - var edges = cy.edges(); - - // Iterate over all edges, creating Layout Edges - for (var i = 0; i < layoutInfo.edgeSize; i++) { - var e = edges[i]; - var tempEdge = {}; - tempEdge.id = e.data('id'); - tempEdge.sourceId = e.data('source'); - tempEdge.targetId = e.data('target'); - - // Compute ideal length - var idealLength = options.idealEdgeLength; - - // Check if it's an inter graph edge - var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId]; - var targetIx = layoutInfo.idToIndex[tempEdge.targetId]; - var sourceGraph = layoutInfo.indexToGraph[sourceIx]; - var targetGraph = layoutInfo.indexToGraph[targetIx]; - - if (sourceGraph != targetGraph) { - // Find lowest common graph ancestor - var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo); - - // Compute sum of node depths, relative to lca graph - var lcaGraph = layoutInfo.graphSet[lca]; - var depth = 0; - - // Source depth - var tempNode = layoutInfo.layoutNodes[sourceIx]; - while (-1 == $.inArray(tempNode.id, lcaGraph)) { - tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; - depth++; - } - - // Target depth - tempNode = layoutInfo.layoutNodes[targetIx]; - while (-1 == $.inArray(tempNode.id, lcaGraph)) { - tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; - depth++; - } - - logDebug("LCA of nodes " + tempEdge.sourceId + " and " + tempEdge.targetId + - ". Index: " + lca + " Contents: " + lcaGraph.toString() + - ". Depth: " + depth); - - // Update idealLength - idealLength *= depth * options.nestingFactor; - } - - tempEdge.idealLength = idealLength; - - layoutInfo.layoutEdges.push(tempEdge); - } - - // Finally, return layoutInfo object - return layoutInfo; - }; - - - /** - * @brief : This function finds the index of the lowest common - * graph ancestor between 2 nodes in the subtree - * (from the graph hierarchy induced tree) whose - * root is graphIx - * - * @arg node1: node1's ID - * @arg node2: node2's ID - * @arg layoutInfo: layoutInfo object - * - */ - var findLCA = function(node1, node2, layoutInfo) { - // Find their common ancester, starting from the root graph - var res = findLCA_aux(node1, node2, 0, layoutInfo); - if (2 > res.count) { - // If aux function couldn't find the common ancester, - // then it is the root graph - return 0; - } else { - return res.graph; - } - }; - - - /** - * @brief : Auxiliary function used for LCA computation - * - * @arg node1 : node1's ID - * @arg node2 : node2's ID - * @arg graphIx : subgraph index - * @arg layoutInfo : layoutInfo object - * - * @return : object of the form {count: X, graph: Y}, where: - * X is the number of ancesters (max: 2) found in - * graphIx (and it's subgraphs), - * Y is the graph index of the lowest graph containing - * all X nodes - */ - var findLCA_aux = function(node1, node2, graphIx, layoutInfo) { - var graph = layoutInfo.graphSet[graphIx]; - // If both nodes belongs to graphIx - if (-1 < $.inArray(node1, graph) && -1 < $.inArray(node2, graph)) { - return {count:2, graph:graphIx}; - } - - // Make recursive calls for all subgraphs - var c = 0; - for (var i = 0; i < graph.length; i++) { - var nodeId = graph[i]; - var nodeIx = layoutInfo.idToIndex[nodeId]; - var children = layoutInfo.layoutNodes[nodeIx].children; - - // If the node has no child, skip it - if (0 == children.length) { - continue; - } - - var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]]; - var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo); - if (0 == result.count) { - // Neither node1 nor node2 are present in this subgraph - continue; - } else if (1 == result.count) { - // One of (node1, node2) is present in this subgraph - c++; - if (2 == c) { - // We've already found both nodes, no need to keep searching - break; - } - } else { - // Both nodes are present in this subgraph - return result; - } - } - - return {count:c, graph:graphIx}; - }; - - - /** - * @brief: printsLayoutInfo into js console - * Only used for debbuging - */ - var printLayoutInfo = function(layoutInfo) { - if (!DEBUG) { - return; - } - console.debug("layoutNodes:"); - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - var s = - "\nindex: " + i + - "\nId: " + n.id + - "\nChildren: " + n.children.toString() + - "\nparentId: " + n.parentId + - "\npositionX: " + n.positionX + - "\npositionY: " + n.positionY + - "\nOffsetX: " + n.offsetX + - "\nOffsetY: " + n.offsetY + - "\npadLeft: " + n.padLeft + - "\npadRight: " + n.padRight + - "\npadTop: " + n.padTop + - "\npadBottom: " + n.padBottom; - - console.debug(s); - } - - console.debug("idToIndex"); - for (var i in layoutInfo.idToIndex) { - console.debug("Id: " + i + "\nIndex: " + layoutInfo.idToIndex[i]); - } - - console.debug("Graph Set"); - var set = layoutInfo.graphSet; - for (var i = 0; i < set.length; i ++) { - console.debug("Set : " + i + ": " + set[i].toString()); - } - - var s = "IndexToGraph"; - for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) { - s += "\nIndex : " + i + " Graph: "+ layoutInfo.indexToGraph[i]; - } - console.debug(s); - - s = "Layout Edges"; - for (var i = 0; i < layoutInfo.layoutEdges.length; i++) { - var e = layoutInfo.layoutEdges[i]; - s += "\nEdge Index: " + i + " ID: " + e.id + - " SouceID: " + e.sourceId + " TargetId: " + e.targetId + - " Ideal Length: " + e.idealLength; - } - console.debug(s); - - s = "nodeSize: " + layoutInfo.nodeSize; - s += "\nedgeSize: " + layoutInfo.edgeSize; - s += "\ntemperature: " + layoutInfo.temperature; - console.debug(s); - - return; - }; - - - /** - * @brief : Randomizes the position of all nodes - */ - var randomizePositions = function(layoutInfo, cy) { - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - // No need to randomize compound nodes - if (true || 0 == n.children.length) { - n.positionX = Math.random() * width; - n.positionY = Math.random() * height; - } - } - } - - - /** - * @brief : Updates the positions of nodes in the network - * @arg layoutInfo : LayoutInfo object - * @arg cy : Cytoscape object - * @arg options : Layout options - */ - var refreshPositions = function(layoutInfo, cy, options) { - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - - var s = "Refreshing positions"; - logDebug(s); - - cy.nodes().positions(function(i, ele) { - var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]]; - s = "Node: " + lnode.id + ". Refreshed position: (" + - lnode.positionX + ", " + lnode.positionY + ")."; - logDebug(s); - return { - x: lnode.positionX, - y: lnode.positionY - }; - }); - - // Trigger layoutReady only on first call - if (true != layoutInfo.ready) { - s = "Triggering layoutready"; - logDebug(s); - layoutInfo.ready = true; - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - } - }; - - - /** - * @brief : Performs one iteration of the physical simulation - * @arg layoutInfo : LayoutInfo object already initialized - * @arg cy : Cytoscape object - * @arg options : Layout options - */ - var step = function(layoutInfo, cy, options, step) { - var s = "\n\n###############################"; - s += "\nSTEP: " + step; - s += "\n###############################\n"; - logDebug(s); - - // Calculate node repulsions - calculateNodeForces(layoutInfo, cy, options); - // Calculate edge forces - calculateEdgeForces(layoutInfo, cy, options); - // Calculate gravity forces - calculateGravityForces(layoutInfo, cy, options); - // Propagate forces from parent to child - propagateForces(layoutInfo, cy, options); - // Update positions based on calculated forces - updatePositions(layoutInfo, cy, options); - }; - - - /** - * @brief : Computes the node repulsion forces - */ - var calculateNodeForces = function(layoutInfo, cy, options) { - // Go through each of the graphs in graphSet - // Nodes only repel each other if they belong to the same graph - var s = "calculateNodeForces"; - logDebug(s); - for (var i = 0; i < layoutInfo.graphSet.length; i ++) { - var graph = layoutInfo.graphSet[i]; - var numNodes = graph.length; - - s = "Set: " + graph.toString(); - logDebug(s); - - // Now get all the pairs of nodes - // Only get each pair once, (A, B) = (B, A) - for (var j = 0; j < numNodes; j++) { - var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; - for (var k = j + 1; k < numNodes; k++) { - var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]]; - nodeRepulsion(node1, node2, layoutInfo, cy, options); - } - } - } - }; - - - /** - * @brief : Compute the node repulsion forces between a pair of nodes - */ - var nodeRepulsion = function(node1, node2, layoutInfo, cy, options) { - var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id; - - // Get direction of line connecting both node centers - var directionX = node2.positionX - node1.positionX; - var directionY = node2.positionY - node1.positionY; - s += "\ndirectionX: " + directionX + ", directionY: " + directionY; - - // If both centers are the same, apply a random force - if (0 == directionX && 0 == directionY) { - s += "\nNodes have the same position."; - return; // TODO - } - - var overlap = nodesOverlap(node1, node2, directionX, directionY); - - if (overlap > 0) { - s += "\nNodes DO overlap."; - s += "\nOverlap: " + overlap; - // If nodes overlap, repulsion force is proportional - // to the overlap - var force = options.nodeOverlap * overlap; - - // Compute the module and components of the force vector - var distance = Math.sqrt(directionX * directionX + directionY * directionY); - s += "\nDistance: " + distance; - var forceX = force * directionX / distance; - var forceY = force * directionY / distance; - - } else { - s += "\nNodes do NOT overlap."; - // If there's no overlap, force is inversely proportional - // to squared distance - - // Get clipping points for both nodes - var point1 = findClippingPoint(node1, directionX, directionY); - var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY); - - // Use clipping points to compute distance - var distanceX = point2.x - point1.x; - var distanceY = point2.y - point1.y; - var distanceSqr = distanceX * distanceX + distanceY * distanceY; - var distance = Math.sqrt(distanceSqr); - s += "\nDistance: " + distance; - - // Compute the module and components of the force vector - var force = options.nodeRepulsion / distanceSqr; - var forceX = force * distanceX / distance; - var forceY = force * distanceY / distance; - } - - // Apply force - node1.offsetX -= forceX; - node1.offsetY -= forceY; - node2.offsetX += forceX; - node2.offsetY += forceY; - - s += "\nForceX: " + forceX + " ForceY: " + forceY; - logDebug(s); - - return; - }; - - - /** - * @brief : Finds the point in which an edge (direction dX, dY) intersects - * the rectangular bounding box of it's source/target node - */ - var findClippingPoint = function(node, dX, dY) { - - // Shorcuts - var X = node.positionX; - var Y = node.positionY; - var H = node.height; - var W = node.width; - var dirSlope = dY / dX; - var nodeSlope = H / W; - var nodeinvSlope = W / H; - - var s = "Computing clipping point of node " + node.id + - " . Height: " + H + ", Width: " + W + - "\nDirection " + dX + ", " + dY; - - // Compute intersection - var res = {}; - do { - // Case: Vertical direction (up) - if (0 == dX && 0 < dY) { - res.x = X; - s += "\nUp direction"; - res.y = Y + H / 2; - break; - } - - // Case: Vertical direction (down) - if (0 == dX && 0 > dY) { - res.x = X; - res.y = Y + H / 2; - s += "\nDown direction"; - break; - } - - // Case: Intersects the right border - if (0 < dX && - -1 * nodeSlope <= dirSlope && - dirSlope <= nodeSlope) { - res.x = X + W / 2; - res.y = Y + (W * dY / 2 / dX); - s += "\nRightborder"; - break; - } - - // Case: Intersects the left border - if (0 > dX && - -1 * nodeSlope <= dirSlope && - dirSlope <= nodeSlope) { - res.x = X - W / 2; - res.y = Y - (W * dY / 2 / dX); - s += "\nLeftborder"; - break; - } - - // Case: Intersects the top border - if (0 < dY && - ( dirSlope <= -1 * nodeSlope || - dirSlope >= nodeSlope )) { - res.x = X + (H * dX / 2 / dY); - res.y = Y + H / 2; - s += "\nTop border"; - break; - } - - // Case: Intersects the bottom border - if (0 > dY && - ( dirSlope <= -1 * nodeSlope || - dirSlope >= nodeSlope )) { - res.x = X - (H * dX / 2 / dY); - res.y = Y - H / 2; - s += "\nBottom border"; - break; - } - - } while (false); - - s += "\nClipping point found at " + res.x + ", " + res.y; - logDebug(s); - return res; - }; - - - /** - * @brief : Determines whether two nodes overlap or not - * @return : Amount of overlapping (0 => no overlap) - */ - var nodesOverlap = function(node1, node2, dX, dY) { - - if (dX > 0) { - var overlapX = node1.maxX - node2.minX; - } else { - var overlapX = node2.maxX - node1.minX; - } - - if (dY > 0) { - var overlapY = node1.maxY - node2.minY; - } else { - var overlapY = node2.maxY - node1.minY; - } - - if (overlapX >= 0 && overlapY >= 0) { - return Math.sqrt(overlapX * overlapX + overlapY * overlapY); - } else { - return 0; - } - }; - - - /** - * @brief : Calculates all edge forces - */ - var calculateEdgeForces = function(layoutInfo, cy, options) { - // Iterate over all edges - for (var i = 0; i < layoutInfo.edgeSize; i++) { - // Get edge, source & target nodes - var edge = layoutInfo.layoutEdges[i]; - var sourceIx = layoutInfo.idToIndex[edge.sourceId]; - var source = layoutInfo.layoutNodes[sourceIx]; - var targetIx = layoutInfo.idToIndex[edge.targetId]; - var target = layoutInfo.layoutNodes[targetIx]; - - // Get direction of line connecting both node centers - var directionX = target.positionX - source.positionX; - var directionY = target.positionY - source.positionY; - - // If both centers are the same, do nothing. - // A random force has already been applied as node repulsion - if (0 == directionX && 0 == directionY) { - return; - } - - // Get clipping points for both nodes - var point1 = findClippingPoint(source, directionX, directionY); - var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY); - - - var lx = point2.x - point1.x; - var ly = point2.y - point1.y; - var l = Math.sqrt(lx * lx + ly * ly); - - var force = Math.pow(edge.idealLength - l, 2) / options.edgeElasticity; - - if (0 != l) { - var forceX = force * lx / l; - var forceY = force * ly / l; - } else { - var forceX = 0; - var forceY = 0; - } - - // Add this force to target and source nodes - source.offsetX += forceX; - source.offsetY += forceY; - target.offsetX -= forceX; - target.offsetY -= forceY; - - var s = "Edge force between nodes " + source.id + " and " + target.id; - s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")"; - logDebug(s); - } - }; - - - /** - * @brief : Computes gravity forces for all nodes - */ - var calculateGravityForces = function(layoutInfo, cy, options) { - var s = "calculateGravityForces"; - logDebug(s); - for (var i = 0; i < layoutInfo.graphSet.length; i ++) { - var graph = layoutInfo.graphSet[i]; - var numNodes = graph.length; - - s = "Set: " + graph.toString(); - logDebug(s); - - // Compute graph center - if (0 == i) { - var container = cy.container(); - var centerX = container.clientHeight / 2; - var centerY = container.clientWidth / 2; - } else { - // Get Parent node for this graph, and use its position as center - var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]]; - var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]]; - var centerX = parent.positionX; - var centerY = parent.positionY; - } - s = "Center found at: " + centerX + ", " + centerY; - logDebug(s); - - // Apply force to all nodes in graph - for (var j = 0; j < numNodes; j++) { - var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; - s = "Node: " + node.id; - var dx = centerX - node.positionX; - var dy = centerY - node.positionY; - var d = Math.sqrt(dx * dx + dy * dy); - if (d > 1.0) { // TODO: Use global variable for distance threshold - var fx = options.gravity * dx / d; - var fy = options.gravity * dy / d; - node.offsetX += fx; - node.offsetY += fy; - s += ": Applied force: " + fx + ", " + fy; - } else { - s += ": skypped since it's too close to center"; - } - logDebug(s); - } - } - }; - - - /** - * @brief : This function propagates the existing offsets from - * parent nodes to its descendents. - * @arg layoutInfo : layoutInfo Object - * @arg cy : cytoscape Object - * @arg options : Layout options - */ - var propagateForces = function(layoutInfo, cy, options) { - // Inline implementation of a queue, used for traversing the graph in BFS order - var queue = []; - var start = 0; // Points to the start the queue - var end = -1; // Points to the end of the queue - - logDebug("propagateForces"); - - // Start by visiting the nodes in the root graph - queue.push.apply(queue, layoutInfo.graphSet[0]); - end += layoutInfo.graphSet[0].length; - - // Traverse the graph, level by level, - while (start <= end) { - // Get the node to visit and remove it from queue - var nodeId = queue[start++]; - var nodeIndex = layoutInfo.idToIndex[nodeId]; - var node = layoutInfo.layoutNodes[nodeIndex]; - var children = node.children; - - // We only need to process the node if it's compound - if (0 < children.length) { - var offX = node.offsetX; - var offY = node.offsetY; - - var s = "Propagating offset from parent node : " + node.id + - ". OffsetX: " + offX + ". OffsetY: " + offY; - s += "\n Children: " + children.toString(); - logDebug(s); - - for (var i = 0; i < children.length; i++) { - var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]]; - // Propagate offset - childNode.offsetX += offX; - childNode.offsetY += offY; - // Add children to queue to be visited - queue[++end] = children[i]; - } - - // Reset parent offsets - node.offsetX = 0; - node.offsetY = 0; - } - - } - }; - - - /** - * @brief : Updates the layout model positions, based on - * the accumulated forces - */ - var updatePositions = function(layoutInfo, cy, options) { - var s = "Updating positions"; - logDebug(s); - - // Reset boundaries for compound nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - logDebug("Resetting boundaries of compound node: " + n.id); - n.maxX = undefined; - n.minX = undefined; - n.maxY = undefined; - n.minY = undefined; - } - } - - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - // No need to set compound node position - logDebug("Skipping position update of node: " + n.id); - continue; - } - s = "Node: " + n.id + " Previous position: (" + - n.positionX + ", " + n.positionY + ")."; - - // Limit displacement in order to improve stability - var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature); - n.positionX += tempForce.x; - n.positionY += tempForce.y; - n.offsetX = 0; - n.offsetY = 0; - n.minX = n.positionX - n.width; - n.maxX = n.positionX + n.width; - n.minY = n.positionY - n.height; - n.maxY = n.positionY + n.height; - s += " New Position: (" + n.positionX + ", " + n.positionY + ")."; - logDebug(s); - - // Update ancestry boudaries - updateAncestryBoundaries(n, layoutInfo); - } - - // Update size, position of compund nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - n.positionX = (n.maxX + n.minX) / 2; - n.positionY = (n.maxY + n.minY) / 2; - n.width = n.maxX - n.minX; - n.height = n.maxY - n.minY; - s = "Updating position, size of compound node " + n.id; - s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY; - s += "\nWidth: " + n.width + ", Height: " + n.height; - logDebug(s); - } - } - }; - - - /** - * @brief : Limits a force (forceX, forceY) to be not - * greater (in modulo) than max. - 8 Preserves force direction. - */ - var limitForce = function(forceX, forceY, max) { - var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max; - var force = Math.sqrt(forceX * forceX + forceY * forceY); - - if (force > max) { - var res = { - x : max * forceX / force, - y : max * forceY / force - }; - - } else { - var res = { - x : forceX, - y : forceY - }; - } - - s += ".\nResult: (" + res.x + ", " + res.y + ")"; - logDebug(s); - - return res; - }; - - - /** - * @brief : Function used for keeping track of compound node - * sizes, since they should bound all their subnodes. - */ - var updateAncestryBoundaries = function(node, layoutInfo) { - var s = "Propagating new position/size of node " + node.id; - var parentId = node.parentId; - if (undefined == parentId) { - // If there's no parent, we are done - s += ". No parent node."; - logDebug(s); - return; - } - - // Get Parent Node - var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]]; - var flag = false; - - // MaxX - if (undefined == p.maxX || node.maxX + p.padRight > p.maxX) { - p.maxX = node.maxX + p.padRight; - flag = true; - s += "\nNew maxX for parent node " + p.id + ": " + p.maxX; - } - - // MinX - if (undefined == p.minX || node.minX - p.padLeft < p.minX) { - p.minX = node.minX - p.padLeft; - flag = true; - s += "\nNew minX for parent node " + p.id + ": " + p.minX; - } - - // MaxY - if (undefined == p.maxY || node.maxY + p.padBottom > p.maxY) { - p.maxY = node.maxY + p.padBottom; - flag = true; - s += "\nNew maxY for parent node " + p.id + ": " + p.maxY; - } - - // MinY - if (undefined == p.minY || node.minY - p.padTop < p.minY) { - p.minY = node.minY - p.padTop; - flag = true; - s += "\nNew minY for parent node " + p.id + ": " + p.minY; - } - - // If updated boundaries, propagate changes upward - if (flag) { - logDebug(s); - return updateAncestryBoundaries(p, layoutInfo); - } - - s += ". No changes in boundaries/position of parent node " + p.id; - logDebug(s); - return; - }; - - - /** - * @brief : Logs a debug message in JS console, if DEBUG is ON - */ - var logDebug = function(text) { - if (DEBUG) { - console.debug(text); - } - }; - - - // register the layout - $$("layout", "cose", CoseLayout); - -})(cytoscape); diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.min.js deleted file mode 100755 index 8c0e8c08c3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/2.1.0/cytoscape.min.js +++ /dev/null @@ -1,27 +0,0 @@ - -/* cytoscape.min.js */ - -/** - * This file is part of cytoscape.js 2.1.0. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -var cytoscape;!function(e){"use strict";var t=cytoscape=function(){return cytoscape.init.apply(cytoscape,arguments)};t.init=function(e){return void 0===e&&(e={}),t.is.plainObject(e)?new t.Core(e):t.is.string(e)?t.extension.apply(t.extension,arguments):void 0},t.fn={},"undefined"!=typeof exports&&(exports=module.exports=cytoscape),e&&(e.cytoscape=cytoscape)}("undefined"==typeof window?null:window),function(e,t){"use strict";e.is={string:function(e){return null!=e&&"string"==typeof e},fn:function(e){return null!=e&&"function"==typeof e},array:function(e){return null!=e&&e instanceof Array},plainObject:function(t){return null!=t&&typeof t==typeof{}&&!e.is.array(t)&&t.constructor===Object},number:function(e){return null!=e&&"number"==typeof e&&!isNaN(e)},integer:function(t){return e.is.number(t)&&Math.floor(t)===t},color:function(e){return null!=e&&"string"==typeof e&&""!==$.Color(e).toString()},bool:function(e){return null!=e&&typeof e==typeof!0},elementOrCollection:function(t){return e.is.element(t)||e.is.collection(t)},element:function(t){return t instanceof e.Element&&t._private.single},collection:function(t){return t instanceof e.Collection&&!t._private.single},core:function(t){return t instanceof e.Core},style:function(t){return t instanceof e.Style},stylesheet:function(t){return t instanceof e.Stylesheet},event:function(t){return t instanceof e.Event},emptyString:function(t){return t?e.is.string(t)&&(""===t||t.match(/^\s+$/))?!0:!1:!0},nonemptyString:function(t){return t&&e.is.string(t)&&""!==t&&!t.match(/^\s+$/)?!0:!1},domElement:function(e){return"undefined"==typeof HTMLElement?!1:e instanceof HTMLElement},touch:function(){return t&&("ontouchstart"in t||t.DocumentTouch&&document instanceof DocumentTouch)}}}(cytoscape,"undefined"==typeof window?null:window),function(e){"use strict";e.util={extend:function(){var t,r,a,i,n,o,s=arguments[0]||{},l=1,c=arguments.length,d=!1;for("boolean"==typeof s&&(d=s,s=arguments[1]||{},l=2),"object"==typeof s||e.is.fn(s)||(s={}),c===l&&(s=this,--l);c>l;l++)if(null!=(t=arguments[l]))for(r in t)a=s[r],i=t[r],s!==i&&(d&&i&&(e.is.plainObject(i)||(n=e.is.array(i)))?(n?(n=!1,o=a&&e.is.array(a)?a:[]):o=a&&e.is.plainObject(a)?a:{},s[r]=e.util.extend(d,o,i)):void 0!==i&&(s[r]=i));return s},error:function(e){if(!console)throw e;if(console.error)console.error(e);else{if(!console.log)throw e;console.log(e)}},clone:function(e){var t={};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},copy:function(t){return null==t?t:e.is.array(t)?t.slice():e.is.plainObject(t)?e.util.clone(t):t},mapEmpty:function(e){var t=!0;if(null!=e)for(var r in e){t=!1;break}return t},pushMap:function(t){var r=e.util.getMap(t);null==r?e.util.setMap($.extend({},t,{value:[t.value]})):r.push(t.value)},setMap:function(t){for(var r,a=t.map,i=t.keys,n=i.length,o=0;n>o;o++){var r=i[o];e.is.plainObject(r)&&e.util.error("Tried to set map with object key"),on;n++){var o=a[n];if(e.is.plainObject(o)&&e.util.error("Tried to get map with object key"),r=r[o],null==r)return r}return r},deleteMap:function(t){for(var r=t.map,a=t.keys,i=a.length,n=t.keepChildren,o=0;i>o;o++){var s=a[o];e.is.plainObject(s)&&e.util.error("Tried to delete map with object key");var l=o===t.keys.length-1;if(l)if(n)for(var c in r)n[c]||delete r[c];else delete r[s];else r=r[s]}},capitalize:function(t){return e.is.emptyString(t)?t:t.charAt(0).toUpperCase()+t.substring(1)},camel2dash:function(e){for(var t=[],r=0;rt&&" "===e[r];r--);return e.substring(t,r+1)},hex2tuple:function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,r,a,i=4===e.length,n=16;return i?(t=parseInt(e[1]+e[1],n),r=parseInt(e[2]+e[2],n),a=parseInt(e[3]+e[3],n)):(t=parseInt(e[1]+e[2],n),r=parseInt(e[3]+e[4],n),a=parseInt(e[5]+e[6],n)),[t,r,a]}},hsl2tuple:function(t){function r(e,t,r){return 0>r&&(r+=1),r>1&&(r-=1),1/6>r?e+6*(t-e)*r:.5>r?t:2/3>r?e+(t-e)*(2/3-r)*6:e}var a,i,n,o,s,l,c,d,u=(e.util.regex.number,new RegExp("^"+e.util.regex.hsla+"$").exec(t));if(u){if(i=parseInt(u[1]),0>i?i=(360- -1*i%360)%360:i>360&&(i%=360),i/=360,n=parseFloat(u[2]),0>n||n>100)return;if(n/=100,o=parseFloat(u[3]),0>o||o>100)return;if(o/=100,s=u[4],void 0!==s&&(s=parseFloat(s),0>s||s>1))return;if(0===n)l=c=d=Math.round(255*o);else{var p=.5>o?o*(1+n):o+n-o*n,h=2*o-p;l=Math.round(255*r(h,p,i+1/3)),c=Math.round(255*r(h,p,i)),d=Math.round(255*r(h,p,i-1/3))}a=[l,c,d,s]}return a},rgb2tuple:function(t){var r,a=(e.util.regex.number,new RegExp("^"+e.util.regex.rgba+"$").exec(t));if(a){r=[];for(var i=[],n=1;3>=n;n++){var o=a[n];if("%"===o[o.length-1]&&(i[n]=!0),o=parseFloat(o),i[n]&&(o=o/100*255),0>o||o>255)return;r.push(Math.floor(o))}var s=i[1]||i[2]||i[3],l=i[1]&&i[2]&&i[3];if(s&&!l)return;var c=a[4];if(void 0!==c){if(c=parseFloat(c),0>c||c>1)return;r.push(c)}}return r},colorname2tuple:function(t){return e.util.colors[t.toLowerCase()]},color2tuple:function(t){return e.util.colorname2tuple(t)||e.util.hex2tuple(t)||e.util.rgb2tuple(t)||e.util.hsl2tuple(t)},tuple2hex:function(e){function t(e){var t=e.toString(16);return 1===t.length&&(t="0"+t),t}var r=e[0],a=e[1],i=e[2];return"#"+t(r)+t(a)+t(i)},colors:{transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},e.util.regex={},e.util.regex.number="(?:[-]?\\d*\\.\\d+|[-]?\\d+|[-]?\\d*\\.\\d+[eE]\\d+)",e.util.regex.rgba="rgb[a]?\\(("+e.util.regex.number+"[%]?)\\s*,\\s*("+e.util.regex.number+"[%]?)\\s*,\\s*("+e.util.regex.number+"[%]?)(?:\\s*,\\s*("+e.util.regex.number+"))?\\)",e.util.regex.rgbaNoBackRefs="rgb[a]?\\((?:"+e.util.regex.number+"[%]?)\\s*,\\s*(?:"+e.util.regex.number+"[%]?)\\s*,\\s*(?:"+e.util.regex.number+"[%]?)(?:\\s*,\\s*(?:"+e.util.regex.number+"))?\\)",e.util.regex.hsla="hsl[a]?\\(("+e.util.regex.number+")\\s*,\\s*("+e.util.regex.number+"[%])\\s*,\\s*("+e.util.regex.number+"[%])(?:\\s*,\\s*("+e.util.regex.number+"))?\\)",e.util.regex.hslaNoBackRefs="hsl[a]?\\((?:"+e.util.regex.number+")\\s*,\\s*(?:"+e.util.regex.number+"[%])\\s*,\\s*(?:"+e.util.regex.number+"[%])(?:\\s*,\\s*(?:"+e.util.regex.number+"))?\\)",e.util.regex.hex3="\\#[0-9a-fA-F]{3}",e.util.regex.hex6="\\#[0-9a-fA-F]{6}"}(cytoscape),function(e){"use strict";e.math={},e.math.signum=function(e){return e>0?1:0>e?-1:0},e.math.distance=function(e,t){var r=t.x-e.x,a=t.y-e.y;return Math.sqrt(r*r+a*a)},e.math.qbezierAt=function(e,t,r,a){return(1-a)*(1-a)*e+2*(1-a)*a*t+a*a*r},e.math.qbezierPtAt=function(t,r,a,i){return{x:e.math.qbezierAt(t.x,r.x,a.x,i),y:e.math.qbezierAt(t.y,r.y,a.y,i)}},e.math.roundRectangleIntersectLine=function(e,t,r,a,i,n,o){var s,l=this.getRoundRectangleRadius(i,n),c=i/2,d=n/2,u=r-c+l-o,p=a-d-o,h=r+c-l+o,v=p;if(s=this.finiteLinesIntersect(e,t,r,a,u,p,h,v,!1),s.length>0)return s;var g=r+c+o,f=a-d+l-o,y=g,m=a+d-l+o;if(s=this.finiteLinesIntersect(e,t,r,a,g,f,y,m,!1),s.length>0)return s;var b=r-c+l-o,x=a+d+o,w=r+c-l+o,_=x;if(s=this.finiteLinesIntersect(e,t,r,a,b,x,w,_,!1),s.length>0)return s;var E=r-c-o,S=a-d+l-o,P=E,M=a+d-l+o;if(s=this.finiteLinesIntersect(e,t,r,a,E,S,P,M,!1),s.length>0)return s;var k,C=r-c+l,D=a-d+l;if(k=this.intersectLineCircle(e,t,r,a,C,D,l+o),k.length>0&&k[0]<=C&&k[1]<=D)return[k[0],k[1]];var N=r+c-l,T=a-d+l;if(k=this.intersectLineCircle(e,t,r,a,N,T,l+o),k.length>0&&k[0]>=N&&k[1]<=T)return[k[0],k[1]];var I=r+c-l,z=a+d-l;if(k=this.intersectLineCircle(e,t,r,a,I,z,l+o),k.length>0&&k[0]>=I&&k[1]>=z)return[k[0],k[1]];var B=r-c+l,X=a+d-l;return k=this.intersectLineCircle(e,t,r,a,B,X,l+o),k.length>0&&k[0]<=B&&k[1]>=X?[k[0],k[1]]:[]},e.math.roundRectangleIntersectBox=function(e,t,r,a,i,n,o,s,l){var c=this.getRoundRectangleRadius(i,n),d=o-i/2-l,u=s-n/2+c-l,p=o+i/2+l,h=s+n/2-c+l,v=o-i/2+c-l,g=s-n/2-l,f=o+i/2-c+l,y=s+n/2+l,m=Math.min(e,r),b=Math.max(e,r),x=Math.min(t,a),w=Math.max(t,a);return d>b?!1:m>p?!1:g>w?!1:x>y?!1:d>=m&&b>=d&&u>=x&&w>=u?!0:p>=m&&b>=p&&u>=x&&w>=u?!0:p>=m&&b>=p&&h>=x&&w>=h?!0:d>=m&&b>=d&&h>=x&&w>=h?!0:m>=d&&p>=m&&x>=u&&h>=x?!0:b>=d&&p>=b&&x>=u&&h>=x?!0:b>=d&&p>=b&&w>=u&&h>=w?!0:m>=d&&p>=m&&w>=u&&h>=w?!0:v>=m&&b>=v&&g>=x&&w>=g?!0:f>=m&&b>=f&&g>=x&&w>=g?!0:f>=m&&b>=f&&y>=x&&w>=y?!0:v>=m&&b>=v&&y>=x&&w>=y?!0:m>=v&&f>=m&&x>=g&&y>=x?!0:b>=v&&f>=b&&x>=g&&y>=x?!0:b>=v&&f>=b&&w>=g&&y>=w?!0:m>=v&&f>=m&&w>=g&&y>=w?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,v+l,u+l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,f-l,u+l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,f-l,h-l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,v+l,h-l)?!0:!1},e.math.checkInBoundingCircle=function(e,t,r,a,i,n,o,s){return e=(e-o)/(i+a),t=(t-s)/(n+a),r>=e*e+t*t},e.math.checkInBoundingBox=function(e,t,r,a,i,n,o,s){for(var l=r[0],c=r[1],d=r[0],u=r[1],p=1;pd&&(d=r[2*p]),r[2*p+1]u&&(u=r[2*p+1]);return e-=o,t-=s,e/=i,t/=n,l>e?!1:e>d?!1:c>t?!1:t>u?!1:!0},e.math.boxInBezierVicinity=function(e,t,r,a,i,n,o,s,l,c,d){var u=.25*i+.5*o+.25*l,p=.25*n+.5*s+.25*c,h=Math.min(e,r)-d,v=Math.min(t,a)-d,g=Math.max(e,r)+d,f=Math.max(t,a)+d;if(i>=h&&g>=i&&n>=v&&f>=n)return 1;if(l>=h&&g>=l&&c>=v&&f>=c)return 1;if(u>=h&&g>=u&&p>=v&&f>=p)return 1;if(o>=h&&g>=o&&s>=v&&f>=s)return 1;var y=Math.min(i,u,l),m=Math.min(n,p,c),b=Math.max(i,u,l),x=Math.max(n,p,c);return y>g||h>b||m>f||v>x?0:1},e.math.checkBezierInBox=function(t,r,a,i,n,o,s,l,c,d){function u(u){var p=e.math.qbezierAt(n,s,c,u),h=e.math.qbezierAt(o,l,d,u);return p>=t&&a>=p&&h>=r&&i>=h}for(var p=0;1>=p;p+=.25)if(!u(p))return!1;return!0},e.math.checkStraightEdgeInBox=function(e,t,r,a,i,n,o,s){return i>=e&&r>=i&&o>=e&&r>=o&&n>=t&&a>=n&&s>=t&&a>=s},e.math.checkStraightEdgeCrossesBox=function(e,t,r,a,i,n,o,s,l){var c,d,u=Math.min(e,r)-l,p=Math.min(t,a)-l,h=Math.max(e,r)+l,v=Math.max(t,a)+l,g=o-i,f=i,y=s-n,m=n;if(Math.abs(g)<1e-4)return i>=u&&h>=i&&Math.min(n,s)<=p&&Math.max(n,s)>=v;var b=(u-f)/g;if(b>0&&1>=b&&(c=y*b+m,c>=p&&v>=c))return!0;var x=(h-f)/g;if(x>0&&1>=x&&(c=y*x+m,c>=p&&v>=c))return!0;var w=(p-m)/y;if(w>0&&1>=w&&(d=g*w+f,d>=u&&h>=d))return!0;var _=(v-m)/y;return _>0&&1>=_&&(d=g*_+f,d>=u&&h>=d)?!0:!1},e.math.checkBezierCrossesBox=function(e,t,r,a,i,n,o,s,l,c,d){var u=Math.min(e,r)-d,p=Math.min(t,a)-d,h=Math.max(e,r)+d,v=Math.max(t,a)+d;if(i>=u&&h>=i&&n>=p&&v>=n)return!0;if(l>=u&&h>=l&&c>=p&&v>=c)return!0;var g=i-2*o+l,f=-2*i+2*o,y=i,m=[];if(Math.abs(g)<1e-4){var b=(u-i)/f,x=(h-i)/f;m.push(b,x)}else{var w,_,E=f*f-4*g*(y-u);if(E>0){var S=Math.sqrt(E);w=(-f+S)/(2*g),_=(-f-S)/(2*g),m.push(w,_)}var P,M,k=f*f-4*g*(y-h);if(k>0){var S=Math.sqrt(k);P=(-f+S)/(2*g),M=(-f-S)/(2*g),m.push(P,M)}}m.sort(function(e,t){return e-t});var C=n-2*s+c,D=-2*n+2*s,N=n,T=[];if(Math.abs(C)<1e-4){var I=(p-n)/D,z=(v-n)/D;T.push(I,z)}else{var B,X,R=D*D-4*C*(N-p);if(R>0){var S=Math.sqrt(R);B=(-D+S)/(2*C),X=(-D-S)/(2*C),T.push(B,X)}var Y,L,V=D*D-4*C*(N-v);if(V>0){var S=Math.sqrt(V);Y=(-D+S)/(2*C),L=(-D-S)/(2*C),T.push(Y,L)}}T.sort(function(e,t){return e-t});for(var A=0;A=0&&m[A]<=1&&m[A+1]>T[q-1]&&T[q-1]<=1&&m[A+1]>=0)return!0;return!1},e.math.inLineVicinity=function(e,t,r,a,i,n,o){var s=o,l=Math.min(r,i),c=Math.max(r,i),d=Math.min(a,n),u=Math.max(a,n);return e>=l-s&&c+s>=e&&t>=d-s&&u+s>=t},e.math.inBezierVicinity=function(e,t,r,a,i,n,o,s,l){var c={x1:Math.min(r,o,i),x2:Math.max(r,o,i),y1:Math.min(a,s,n),y2:Math.max(a,s,n)};return ec.x2||tc.y2?!1:!0;var c},e.math.solveCubic=function(e,t,r,a,i){t/=e,r/=e,a/=e;var n,o,s,l,c,d,u,p;return o=(3*r-t*t)/9,s=-(27*a)+t*(9*r-2*t*t),s/=54,n=o*o*o+s*s,i[1]=0,u=t/3,n>0?(c=s+Math.sqrt(n),c=0>c?-Math.pow(-c,1/3):Math.pow(c,1/3),d=s-Math.sqrt(n),d=0>d?-Math.pow(-d,1/3):Math.pow(d,1/3),i[0]=-u+c+d,u+=(c+d)/2,i[4]=i[2]=-u,u=Math.sqrt(3)*(-d+c)/2,i[3]=u,void(i[5]=-u)):(i[5]=i[3]=0,0==n?(p=0>s?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=-u+2*p,void(i[4]=i[2]=-(p+u))):(o=-o,l=o*o*o,l=Math.acos(s/Math.sqrt(l)),p=2*Math.sqrt(o),i[0]=-u+p*Math.cos(l/3),i[2]=-u+p*Math.cos((l+2*Math.PI)/3),void(i[4]=-u+p*Math.cos((l+4*Math.PI)/3))))},e.math.sqDistanceToQuadraticBezier=function(e,t,r,a,i,n,o,s){var l=1*r*r-4*r*i+2*r*o+4*i*i-4*i*o+o*o+a*a-4*a*n+2*a*s+4*n*n-4*n*s+s*s,c=9*r*i-3*r*r-3*r*o-6*i*i+3*i*o+9*a*n-3*a*a-3*a*s-6*n*n+3*n*s,d=3*r*r-6*r*i+r*o-r*e+2*i*i+2*i*e-o*e+3*a*a-6*a*n+a*s-a*t+2*n*n+2*n*t-s*t,u=1*r*i-r*r+r*e-i*e+a*n-a*a+a*t-n*t,p=[];this.solveCubic(l,c,d,u,p);for(var h=1e-7,v=[],g=0;6>g;g+=2)Math.abs(p[g+1])=0&&p[g]<=1&&v.push(p[g]);v.push(1),v.push(0);for(var f,y,m,b,x=-1,w=0;w=0?x>b&&(x=b,f=v[w]):(x=b,f=v[w]);return x},e.math.sqDistanceToFiniteLine=function(e,t,r,a,i,n){var o=[e-r,t-a],s=[i-r,n-a],l=s[0]*s[0]+s[1]*s[1],c=o[0]*o[0]+o[1]*o[1],d=o[0]*s[0]+o[1]*s[1],u=d*d/l;return 0>d?c:u>l?(e-i)*(e-i)+(t-n)*(t-n):c-u},e.math.pointInsidePolygon=function(e,t,r,a,i,n,o,s,l){var c=new Array(r.length),d=Math.asin(s[1]/Math.sqrt(s[0]*s[0]+s[1]*s[1]));s[0]<0?d+=Math.PI/2:d=-d-Math.PI/2;for(var u=Math.cos(-d),p=Math.sin(-d),h=0;h0){var g=this.expandPolygon(c,-l);v=this.joinLines(g)}else v=c;for(var f,y,m,b,x,w=0,_=0,h=0;h=e&&e>=m||e>=f&&m>=e))continue;x=(e-f)/(m-f)*(b-y)+y,x>t&&w++,t>x&&_++}return w%2==0?!1:!0},e.math.joinLines=function(e){for(var t,r,a,i,n,o,s,l,c=new Array(e.length/2),d=0;dc)return[];var d=c/l;return[(r-e)*d+e,(a-t)*d+t]},e.math.dotProduct=function(e,t){if(2!=e.length||2!=t.length)throw"dot product: arguments are not vectors";return e[0]*t[0]+e[1]*t[1]},e.math.intersectLineCircle=function(e,t,r,a,i,n,o){var s=[r-e,a-t],l=[i,n],c=[e-i,t-n],d=s[0]*s[0]+s[1]*s[1],u=2*(c[0]*s[0]+c[1]*s[1]),l=c[0]*c[0]+c[1]*c[1]-o*o,p=u*u-4*d*l;if(0>p)return[];var h=(-u+Math.sqrt(p))/(2*d),v=(-u-Math.sqrt(p))/(2*d),g=Math.min(h,v),f=Math.max(h,v),y=[];if(g>=0&&1>=g&&y.push(g),f>=0&&1>=f&&y.push(f),0==y.length)return[];var m=y[0]*s[0]+e,b=y[0]*s[1]+t;if(y.length>1){if(y[0]==y[1])return[m,b];var x=y[1]*s[0]+e,w=y[1]*s[1]+t;return[m,b,x,w]}return[m,b]},e.math.findCircleNearPoint=function(e,t,r,a,i){var n=a-e,o=i-t,s=Math.sqrt(n*n+o*o),l=n/s,c=o/s;return[e+l*r,t+c*r]},e.math.findMaxSqDistanceToOrigin=function(e){for(var t,r=1e-6,a=0;ar&&(r=t);return r},e.math.finiteLinesIntersect=function(e,t,r,a,i,n,o,s,l){var c=(o-i)*(t-n)-(s-n)*(e-i),d=(r-e)*(t-n)-(a-t)*(e-i),u=(s-n)*(r-e)-(o-i)*(a-t);if(0!=u){var p=c/u,h=d/u;return p>=0&&1>=p&&h>=0&&1>=h?[e+p*(r-e),t+p*(a-t)]:l?[e+p*(r-e),t+p*(a-t)]:[]}return 0==c||0==d?[e,r,o].sort()[1]==o?[o,s]:[e,r,i].sort()[1]==i?[i,n]:[i,o,r].sort()[1]==r?[r,a]:[]:[]},e.math.boxIntersectEllipse=function(e,t,r,a,i,n,o,s,l){if(e>r){var c=e;e=r,r=c}if(t>a){var d=t;t=a,a=d}var u=[s-n/2-i,l],p=[s+n/2+i,l],h=[s,l-o/2-i],v=[s,l+o/2+i];return rp[0]?!1:t>v[1]?!1:a=e*e+t*t?!0:1>=r*r+t*t?!0:1>=r*r+a*a?!0:1>=e*e+a*a?!0:!1)},e.math.boxIntersectPolygon=function(t,r,a,i,n,o,s,l,c,d,u){if(t>a){var p=t;t=a,a=p}if(r>i){var h=r;r=i,i=h}var v=new Array(n.length),g=Math.asin(d[1]/Math.sqrt(d[0]*d[0]+d[1]*d[1]));d[0]<0?g+=Math.PI/2:g=-g-Math.PI/2;for(var f=Math.cos(-g),y=Math.sin(-g),m=0;mx&&(x=v[2*m]),v[2*m]_&&(_=v[2*m+1]),v[2*m+1]a)return!1;if(t>x+u)return!1;if(w-u>i)return!1;if(r>_+u)return!1;var E;if(u>0){var S=e.math.expandPolygon(v,-u);E=e.math.joinLines(S)}else E=v;for(var m=0;m0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,t,i,a,i,!1).length>0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,t,r,t,i,!1).length>0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,a,r,a,i,!1).length>0)return!0}return!1},e.math.polygonIntersectLine=function(t,r,a,i,n,o,s,l){for(var c,d=[],u=new Array(a.length),p=0;p0){var v=e.math.expandPolygon(u,-l);h=e.math.joinLines(v)}else h=u;for(var g,f,y,m,p=0;pn&&(n=1e-5),[t[0]+n*a[0],t[1]+n*a[1]]},e.math.generateUnitNgonPointsFitToSquare=function(t,r){var a=e.math.generateUnitNgonPoints(t,r);return a=e.math.fitPolygonToSquare(a)},e.math.fitPolygonToSquare=function(e){for(var t,r,a=e.length/2,i=1/0,n=1/0,o=-1/0,s=-1/0,l=0;a>l;l++)t=e[2*l],r=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),n=Math.min(n,r),s=Math.max(s,r);for(var c=2/(o-i),d=2/(s-n),l=0;a>l;l++)t=e[2*l]=e[2*l]*c,r=e[2*l+1]=e[2*l+1]*d,i=Math.min(i,t),o=Math.max(o,t),n=Math.min(n,r),s=Math.max(s,r);if(-1>n)for(var l=0;a>l;l++)r=e[2*l+1]=e[2*l+1]+(-1-n);return e},e.math.generateUnitNgonPoints=function(e,t){var r=1/e*2*Math.PI,a=e%2==0?Math.PI/2+r/2:Math.PI/2;a+=t;for(var i,n,o,s=new Array(2*e),l=0;e>l;l++)i=l*r+a,n=s[2*l]=Math.cos(i),o=s[2*l+1]=Math.sin(-i);return s},e.math.getRoundRectangleRadius=function(e,t){return Math.min(e/2,t/2,10)}}(cytoscape),function(e){"use strict";e.instances=[],e.instanceCounter=0,e.lastInstanceTime,e.registerInstance=function(t,r){var a;e.is.core(t)?a=t:e.is.domElement(t)&&(r=t);var i=e.getRegistrationForInstance(t,r);if(i)return i.cy?e.util.error("Tried to register on a pre-existing registration"):(i.cy=t,i.domElement=r),i;var n,o=+new Date;e.lastInstanceTime&&e.lastInstanceTime!==o?++e.instanceCounter:e.instanceCounter=0,e.lastInstanceTime=o,n=e.instanceCounter;var s="cy-"+o+"-"+n,l={id:s,cy:a,domElement:r,readies:[]};return e.instances.push(l),e.instances[s]=l,l},e.removeRegistrationForInstance=function(t,r){var a;if(e.is.core(t)?a=t:e.is.domElement(t)&&(r=t),e.is.core(a)){var i=a._private.instanceId;delete e.instances[i],e.instances.splice(i,1)}else if(e.is.domElement(r))for(var n=0;n=0;n--){var o=e.instances[n];if(o.domElement===r)return o}}}(cytoscape),function(e){"use strict";function t(t,r,a){var i={};switch(i[r]=a,t){case"core":case"collection":e.fn[t](i)}return e.util.setMap({map:n,keys:[t,r],value:a})}function r(t,r){return e.util.getMap({map:n,keys:[t,r]})}function a(t,r,a,i,n){return e.util.setMap({map:o,keys:[t,r,a,i],value:n})}function i(t,r,a,i){return e.util.getMap({map:o,keys:[t,r,a,i]})}var n={};e.extensions=n;var o={};e.modules=o,e.extension=function(){return 2==arguments.length?r.apply(this,arguments):3==arguments.length?t.apply(this,arguments):4==arguments.length?i.apply(this,arguments):5==arguments.length?a.apply(this,arguments):void $.error("Invalid extension access syntax")}}(cytoscape),function(e,t){"use strict";e&&(e.fn.cytoscape=function(r){var a=e(this);if("get"===r){var i=t.getRegistrationForInstance(a[0]);return i.cy}if(!t.is.fn(r)){if(t.is.plainObject(r))return a.each(function(){var t=e.extend({},r,{container:e(this)[0]});cytoscape(t)});for(var n=a[0],o=[],s=[],l=1;lu;u++)i.canSet(s[u])&&(s[u]._private[i.field][r]=a);i.updateMappers&&n.updateMappers(),i.onSet(n),i.settingTriggersEvent&&n[i.triggerFnName](i.settingEvent)}}}else if(i.allowSetting&&e.is.plainObject(r)){var h,v,g=r;for(h in g){v=g[h];var d=!i.immutableKeys[h];if(d)for(var u=0,p=s.length;p>u;u++)i.canSet(s[u])&&(s[u]._private[i.field][h]=v)}i.updateMappers&&n.updateMappers(),i.onSet(n),i.settingTriggersEvent&&n[i.triggerFnName](i.settingEvent)}else if(i.allowBinding&&e.is.fn(r)){var f=r;n.bind(i.bindingEvent,f)}else if(i.allowGetting&&void 0===r){var c;return l&&(c=l._private[i.field]),c}return n}},batchData:function(t){var r={field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{},updateMappers:!1},a=t=e.util.extend({},r,t);return function(t){var r=this,i=void 0!==r.length,n=i?r:r._private.elements;if(0===n.length)return r;for(var o=i?n[0]._private.cy:r,s=0;sc;c++){var d=s[c];if(!e.is.emptyString(d)){var u=!a.immutableKeys[d];if(u)for(var p=0,h=o.length;h>p;p++)delete o[p]._private[a.field][d]}}a.triggerEvent&&i[a.triggerFnName](a.event)}else if(void 0===r){for(var p=0,h=o.length;h>p;p++){var v=o[p]._private[a.field];for(var d in v){var g=!a.immutableKeys[d];g&&delete v[d]}}a.triggerEvent&&i[a.triggerFnName](a.event)}return i}},event:{regex:/(\w+)(\.\w+)?/,optionalTypeRegex:/(\w+)?(\.\w+)?/,falseCallback:function(){return!1}},on:function(t){var r={unbindSelfOnTrigger:!1,unbindAllBindersOnTrigger:!1};return t=e.util.extend({},r,t),function(r,a,i,n){var o=this,s=void 0!==o.length,l=s?o:[o],c=(s?o[0]:o,e.is.string(r)),d=t;if(e.is.plainObject(a)?(n=i,i=a,a=void 0):(e.is.fn(a)||a===!1)&&(n=a,i=void 0,a=void 0),(e.is.fn(i)||i===!1)&&(n=i,i=void 0),!e.is.fn(n)&&n!==!1&&c)return o;if(c){var u={};u[r]=n,r=u}for(var p in r)if(n=r[p],n===!1&&(n=e.define.event.falseCallback),e.is.fn(n)){p=p.split(/\s+/);for(var h=0;h\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",o="(?:[\\w-]|(?:\\\\"+n+"))+",s="=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",l="\\?|\\!|\\^",c='"(?:\\\\"|[^"])+"|'+"'(?:\\\\'|[^'])+'",d=$$.util.regex.number,u=c+"|"+d,p="degree|indegree|outdegree",h="\\s*,\\s*",v=o,g="\\s+",f="\\s+>\\s+",y="\\$",m=o,b=function(e){return e.replace(new RegExp("\\\\("+n+")","g"),function(e,t){return t})},x=s.split("|"),w=0;w=0;break;case"$=":matches=null!=new RegExp(valStr+"$").exec(fieldStr);break;case"^=":matches=null!=new RegExp("^"+valStr).exec(fieldStr);break;default:if(caseInsensitive){var expr="fieldStr "+operator+" valStr";matches=eval(expr)}else{var expr=params.fieldRef(field)+" "+operator+" "+value;matches=eval(expr)}}}else if(null!=operator)switch(operator){case"?":matches=params.fieldTruthy(field);break;case"!":matches=!params.fieldTruthy(field);break;case"^":matches=params.fieldUndefined(field)}else matches=!params.fieldUndefined(field);if(!matches){allDataMatches=!1;break}}return allDataMatches},allDataMatches=operandsMatch({name:"data",fieldValue:function(e){return element._private.data[e]},fieldRef:function(e){return"element._private.data."+e},fieldUndefined:function(e){return void 0===element._private.data[e]},fieldTruthy:function(e){return element._private.data[e]?!0:!1}});if(!allDataMatches)return!1;var allMetaMatches=operandsMatch({name:"meta",fieldValue:function(e){return element[e]()},fieldRef:function(e){return"element."+e+"()"},fieldUndefined:function(e){return void 0==element[e]()},fieldTruthy:function(e){return element[e]()?!0:!1}});if(!allMetaMatches)return!1;if(null!=query.collection){var matchesAny=null!=query.collection._private.ids[element.id()];if(!matchesAny)return!1}if(null!=query.filter&&0==element.collection().filter(query.filter).size())return!1;var confirmRelations=function(e,t){if(null!=e){var r=!1;t=t();for(var a=0;a "+i),null!=e.ancestor&&(i=r(e.ancestor)+" "+i),null!=e.child&&(i+=" > "+r(e.child)),null!=e.descendant&&(i+=" "+r(e.descendant)),i},a=0;a1&&an.length?l.substr(n.length):""}function i(){o=o.length>s.length?o.substr(s.length):""}var n,o,s,l=""+r;for(l=l.replace(/[/][*](\s|.)+?[*][/]/g,"");;){var c=l.match(/^\s*$/);if(c)break;var d=l.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!d){e.util.error("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+l);break}n=d[0];var u=d[1],p=new e.Selector(u);if(p._private.invalid)e.util.error("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),a();else{var h=d[2],v=!1;o=h;for(var g=[];;){var c=o.match(/^\s*$/);if(c)break;var f=o.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/);if(!f){e.util.error("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+h),v=!0;break}s=f[0];var y=f[1],m=f[2],b=e.style.properties[y];if(b){var x=t.parse(y,m);x?(g.push({name:y,val:m}),i()):(e.util.error("Skipping property: Invalid property definition in: "+s),i())}else e.util.error("Skipping property: Invalid property name in: "+s),i()}if(v){a();break}t.selector(u);for(var w=0;w node").css({width:"auto",height:"auto",shape:"rectangle","background-opacity":.5,"padding-top":10,"padding-right":10,"padding-left":10,"padding-bottom":10}).selector("edge").css({width:1}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}).selector("core").css({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"panning-cursor":"grabbing","active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":r?40:15})},e.styfn.clear=function(){this._private.newStyle=!0;for(var e=0;es.max)return null;var S={name:t,value:r,strValue:""+r+(m?m:""),units:m,bypass:a,pxValue:s.unitless||"%"===m?void 0:"px"!==m&&m?this.getEmSizeInPixels()*r:r};return S}if(s.color){var P=e.util.color2tuple(r);return{name:t,value:P,strValue:r,bypass:a}}if(!s.enums){if(s.regex){var M=new RegExp(s.regex),k=M.exec(r);return k?{name:t,value:k,strValue:r,bypass:a}:null}return s.string?{name:t,value:r,strValue:r,bypass:a}:null}for(var _=0;_0,s=n.properties;if(o){for(var l=0;lo;o++){var u=c[o],p=l[u];if(e.is.array(p))for(var h=0,v=p.length;v>h;h++){var g=p[h],f=e.util.extend({},g,{group:u});n.push(f)}}r=new e.Collection(a,n)}else{var g=t;r=new e.Element(a,g).collection()}return r},remove:function(t){if(e.is.elementOrCollection(t))t=t;else if(e.is.string(t)){var r=t;t=this.$(r)}return t.remove()},load:function(a,i,n){function o(){s.one("layoutready",function(e){s.notifications(!0),s.trigger(e),s.notify({type:"load",collection:s.elements()}),s.one("load",i),s.trigger("load")}).one("layoutstop",function(){s.one("done",n),s.trigger("done")}),s.layout(s._private.options.layout)}var s=this,l=s.elements();return l.length>0&&l.remove(),s.notifications(!1),null!=a&&(e.is.plainObject(a)||e.is.array(a))&&s.add(a),t?r(o):o(),this}})}(cytoscape,"undefined"==typeof window?null:window),function(e){"use strict";e.fn.core({addToAnimationPool:function(e){for(var t=this,r=t._private.aniEles,a=[],i=0;i0?c.shift():null;null!=d&&(d.callTime=+new Date,s.push(d))}for(var u=[],p=0;p0&&o.notify({type:"draw",collection:r});for(var p=0;p0||l.length>0;g||(r.splice(p,1),p--)}}function a(t,r,a){var s,l=o._private.style,c=r.properties,d=r.params,u=r.callTime;if(s=0===r.duration?1:Math.min(1,(a-u)/r.duration),0>s?s=0:s>1&&(s=1),null==c.delay){var p=r.startPosition,h=c.position,v=t._private.position;if(h&&(i(p.x,h.x)&&(v.x=n(p.x,h.x,s)),i(p.y,h.y)&&(v.y=n(p.y,h.y,s))),c.css)for(var g=e.style.properties,f=0;f=1&&(r.done=!0),s}function i(t,r){return null==t||null==r?!1:e.is.number(t)&&e.is.number(r)?!0:t&&r?!0:!1}function n(t,r,a){if(0>a?a=0:a>1&&(a=1),e.is.number(t)&&e.is.number(r))return t+(r-t)*a;if(e.is.number(t[0])&&e.is.number(r[0])){var i=t,n=r,o=function(e,t){var r=t-e,i=e;return Math.round(a*r+i)},s=o(i[0],n[0]),l=o(i[1],n[1]),c=o(i[2],n[2]);return"rgb("+s+", "+l+", "+c+")"}return void 0}var o=this,s=1e3/60,l=!1,c=!0;o._private.aniEles=[];var d="undefined"==typeof window?function(){}:window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;null!=d&&c||(d=function(e){window.setTimeout(function(){e(+new Date)},s)});var u=o.container();t()}})}(cytoscape),function(e){"use strict";e.fn.core({data:e.define.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0}),removeData:e.define.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0}),batchData:e.define.batchData({field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),scratch:e.define.data({field:"scratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeScratch:e.define.removeData({field:"scratch",triggerEvent:!1})})}(cytoscape),function(e){"use strict";e.fn.core({on:e.define.on(),one:e.define.on({unbindSelfOnTrigger:!0}),once:e.define.on({unbindAllBindersOnTrigger:!0}),off:e.define.off(),trigger:e.define.trigger()}),e.corefn.bind=e.corefn.on,e.corefn.unbind=e.corefn.off}(cytoscape),function(e){"use strict";e.fn.core({png:function(e){var t=this._private.renderer;return e=e||{},t.png(e)}})}(cytoscape),function(e){"use strict";e.fn.core({layout:function(e){var t=this;return this._private.layoutRunning?this:(null==e&&(e=this._private.options.layout),this.initLayout(e),t.trigger("layoutstart"),this._private.layoutRunning=!0,this.one("layoutstop",function(){t._private.layoutRunning=!1}),this._private.layout.run(),this)},initLayout:function(t){if(null==t)return void e.util.error("Layout options must be specified to run a layout");if(null==t.name)return void e.util.error("A `name` must be specified to run a layout");var r=t.name,a=e.extension("layout",r);return null==a?void e.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?",r):(this._private.layout=new a(e.util.extend({},t,{renderer:this._private.renderer,cy:this})),void(this._private.options.layout=t))}})}(cytoscape),function(e){"use strict";e.fn.core({notify:function(t){if(this._private.notificationsEnabled){var r=this.renderer(),a=this;if(e.is.element(t.collection)){var i=t.collection;t.collection=new e.Collection(a,[i])}else if(e.is.array(t.collection)){var n=t.collection;t.collection=new e.Collection(a,n)}r.notify(t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:void(t.notificationsEnabled=e?!0:!1)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)}})}(cytoscape),function(e){"use strict";e.fn.core({renderTo:function(e,t,r){var a=this._private.renderer;return a.renderTo(e,t,r),this},renderer:function(){return this._private.renderer},forceRender:function(){return this.notify({type:"draw"}),this},initRenderer:function(t){var r=this,a=e.extension("renderer",t.name);return null==a?void e.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?",t.name):void(this._private.renderer=new a(e.util.extend({},t,{cy:r,style:r._private.style})))},recalculateRenderedStyle:function(){var e=this.renderer();e.recalculateRenderedStyle&&e.recalculateRenderedStyle()}})}(cytoscape),function(e){"use strict";e.fn.core({collection:function(t){return e.is.string(t)?this.$(t):e.is.elementOrCollection(t)?t.collection():new e.Collection(this)},nodes:function(e){var t=this.$("node");return e?t.filter(e):t},edges:function(e){var t=this.$("edge");return e?t.filter(e):t},$:function(t){var r=new e.Collection(this,this._private.elements);return t?r.filter(t):r}}),e.corefn.elements=e.corefn.filter=e.corefn.$}(cytoscape),function(e){"use strict";e.fn.core({style:function(){return this._private.style}})}(cytoscape),function(e){"use strict";e.fn.core({panningEnabled:function(e){return void 0===e?this._private.panningEnabled:(this._private.panningEnabled=e?!0:!1,this)},userPanningEnabled:function(e){return void 0===e?this._private.userPanningEnabled:(this._private.userPanningEnabled=e?!0:!1,this)},zoomingEnabled:function(e){return void 0===e?this._private.zoomingEnabled:(this._private.zoomingEnabled=e?!0:!1,this)},userZoomingEnabled:function(e){return void 0===e?this._private.userZoomingEnabled:(this._private.userZoomingEnabled=e?!0:!1,this)},boxSelectionEnabled:function(e){return void 0===e?this._private.boxSelectionEnabled:(this._private.boxSelectionEnabled=e?!0:!1,this)},pan:function(){var t,r,a,i,n,o=arguments,s=this._private.pan;switch(o.length){case 0:return s;case 1:if(!this._private.panningEnabled)return this;if(e.is.string(o[0]))return t=o[0],s[t];e.is.plainObject(o[0])&&(a=o[0],i=a.x,n=a.y,e.is.number(i)&&(s.x=i),e.is.number(n)&&(s.y=n),this.trigger("pan"));break;case 2:if(!this._private.panningEnabled)return this;t=o[0],r=o[1],"x"!==t&&"y"!==t||!e.is.number(r)||(s[t]=r),this.trigger("pan")}return this.notify({type:"viewport"}),this},panBy:function(){var t,r,a,i,n,o=arguments,s=this._private.pan;if(!this._private.panningEnabled)return this;switch(o.length){case 1:e.is.plainObject(o[0])&&(a=o[0],i=a.x,n=a.y,e.is.number(i)&&(s.x+=i),e.is.number(n)&&(s.y+=n),this.trigger("pan"));break;case 2:t=o[0],r=o[1],"x"!==t&&"y"!==t||!e.is.number(r)||(s[t]+=r),this.trigger("pan")}return this.notify({type:"viewport"}),this},fit:function(t,r){if(e.is.number(t)&&void 0===r&&(r=t,t=void 0),!this._private.panningEnabled||!this._private.zoomingEnabled)return this;if(e.is.string(t)){var a=t;t=this.$(a)}else e.is.elementOrCollection(t)||(t=this.elements());var i,n=t.boundingBox(),o=this.style(),s=parseFloat(o.containerCss("width")),l=parseFloat(o.containerCss("height"));return r=e.is.number(r)?r:0,!isNaN(s)&&!isNaN(l)&&t.length>0&&(i=this._private.zoom=Math.min((s-2*r)/n.w,(l-2*r)/n.h),i=i>this._private.maxZoom?this._private.maxZoom:i,i=ithis._private.maxZoom?this._private.maxZoom:a,a=a1&&this._private.minZoom<1&&this.zoom(1),this.notify({type:"viewport"}),this):this}})}(cytoscape),function(e){"use strict";e.fn.collection=e.fn.eles=function(t){for(var r in t){var a=t[r];e.Collection.prototype[r]=a}};var t={prefix:{nodes:"n",edges:"e"},id:{nodes:0,edges:0},generate:function(t,r,a){var i=e.is.element(r)?r._private:r,n=i.group,o=null!=a?a:this.prefix[n]+this.id[n];if(t.getElementById(o).empty())this.id[n]++;else for(;!t.getElementById(o).empty();)o=this.prefix[n]+ ++this.id[n];return o}};e.Element=function(t,r,a){if(!(this instanceof e.Element))return new e.Element(t,r,a);var i=this;if(a=void 0===a||a?!0:!1,void 0===t||void 0===r||!e.is.core(t))return void e.util.error("An element must have a core reference and parameters set");if("nodes"!==r.group&&"edges"!==r.group)return void e.util.error("An element must be of type `nodes` or `edges`; you specified `"+r.group+"`");if(this.length=1,this[0]=this,this._private={cy:t,single:!0,data:r.data||{},layoutData:{},position:r.position||{},autoWidth:void 0,autoHeight:void 0,listeners:[],group:r.group,style:{},rstyle:{},styleCxts:[],removed:!0,selected:r.selected?!0:!1,selectable:void 0===r.selectable?!0:r.selectable?!0:!1,locked:r.locked?!0:!1,grabbed:!1,grabbable:void 0===r.grabbable?!0:r.grabbable?!0:!1,active:!1,classes:{},animation:{current:[],queue:[]},rscratch:{},scratch:{},edges:[],children:[]},r.renderedPosition){var n=r.renderedPosition,o=t.pan(),s=t.zoom();this._private.position={x:(n.x-o.x)/s,y:(n.y-o.y)/s}}if(e.is.string(r.classes))for(var l=r.classes.split(/\s+/),c=0,d=l.length;d>c;c++){var u=l[c];u&&""!==u&&(i._private.classes[u]=!0)}r.css&&t.style().applyBypass(this,r.css),(void 0===a||a)&&this.restore()},e.Collection=function(r,a){if(!(this instanceof e.Collection))return new e.Collection(r,a);if(void 0===r||!e.is.core(r))return void e.util.error("A collection must have a reference to the core");var i={},n=[],o=!1;if(a){if(a.length>0&&e.is.plainObject(a[0])&&!e.is.element(a[0])){o=!0;for(var s=[],l={},c=0,d=a.length;d>c;c++){var u=a[c];null==u.data&&(u.data={});var p=u.data;if(null==p.id)p.id=t.generate(r,u);else if(0!=r.getElementById(p.id).length||l[p.id])continue;var h=new e.Element(r,u,!1);s.push(h),l[p.id]=!0}a=s}}else a=[];for(var c=0,d=a.length;d>c;c++){var v=a[c];if(v){var g=v._private.data.id;i[g]||(i[g]=v,n.push(v))}}for(var c=0,d=n.length;d>c;c++)this[c]=n[c];this.length=n.length,this._private={cy:r,ids:i},o&&this.restore()},e.elefn=e.elesfn=e.Element.prototype=e.Collection.prototype,e.elesfn.cy=function(){return this._private.cy},e.elesfn.element=function(){return this[0]},e.elesfn.collection=function(){return e.is.collection(this)?this:new e.Collection(this._private.cy,[this])},e.elesfn.json=function(){var t=this.element();if(null==t)return void 0;var r=t._private,a=e.util.copy({data:r.data,position:r.position,group:r.group,bypass:r.bypass,removed:r.removed,selected:r.selected,selectable:r.selectable,locked:r.locked,grabbed:r.grabbed,grabbable:r.grabbable,classes:""}),i=[];for(var n in r.classes)i.push(n);for(var o=0;ou;u++){var h=a[u];h.isNode()?(s.push(h),c++):(l.push(h),d++)}o=s.concat(l);for(var u=0,p=o.length;p>u;u++){var h=o[u];if(h.removed()){var v=h._private,g=v.data;if(void 0===g.id)g.id=t.generate(n,h);else{if(e.is.emptyString(g.id)||!e.is.string(g.id)){e.util.error("Can not create element with invalid string ID `"+g.id+"`");continue}if(0!=n.getElementById(g.id).length){e.util.error("Can not create second element with ID `"+g.id+"`");continue}}{g.id}if(h.isEdge()){for(var f=h,y=["source","target"],m=y.length,b=!1,x=0;m>x;x++){var w=y[x],_=g[w];null==_||""===_?(e.util.error("Can not create edge `"+g.id+"` with unspecified "+w),b=!0):n.getElementById(_).empty()&&(e.util.error("Can not create edge `"+g.id+"` with nonexistant "+w+" `"+_+"`"),b=!0)}if(b)continue;var E=n.getElementById(g.source),S=n.getElementById(g.target);E._private.edges.push(f),S._private.edges.push(f)}v.ids={},v.ids[g.id]=h,v.removed=!1,n.addToPool(h),i.push(h)}}for(var u=0;c>u;u++){var P=o[u],g=P._private.data,M=(g.id,P._private.data.parent),k=null!=M;if(k){var C=n.getElementById(M);if(C.empty())delete g.parent;else{for(var D=!1,N=C;!N.empty();){if(P.same(N)){D=!0,delete g.parent;break}N=N.parent()}D||(C[0]._private.children.push(P),n._private.hasCompoundNodes=!0)}}}if(i=new e.Collection(n,i),i.length>0){var T=i.add(i.connectedNodes()).add(i.parent());T.updateStyle(r),r?i.rtrigger("add"):i.trigger("add")}return a},e.elesfn.removed=function(){var e=this[0];return e&&e._private.removed},e.elesfn.inside=function(){var e=this[0];return e&&!e._private.removed},e.elesfn.remove=function(t){function r(e){for(var t=e._private.edges,r=0;rp;p++){var v=s[p];i(v)}for(var p=0;p0&&(t&&this.cy().notify({type:"remove",collection:b}),b.trigger("remove"));for(var x={},p=0;p0:void 0},clearQueue:function(){for(var e=0;e0&&new e.Collection(this._private.cy,a).updateStyle(),r.trigger("class"),r},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes[e]?!0:!1},toggleClass:function(t,r){for(var a=t.split(/\s+/),i=this,n=[],o=0,s=i.length;s>o;o++)for(var l=i[o],c=0;c0&&new e.Collection(this._private.cy,n).updateStyle(),i.trigger("class"),i},removeClass:function(t){t=t.split(/\s+/);for(var r=this,a=[],i=0;i0&&new e.Collection(r._private.cy,a).updateStyle(),r.trigger("class"),r}})}(cytoscape),function(e){"use strict";e.fn.eles({allAre:function(e){return this.filter(e).length===this.length},is:function(e){return this.filter(e).length>0},same:function(e){return e=this.cy().collection(e),this.length!==e.length?!1:this.intersect(e).length===this.length},anySame:function(e){return e=this.cy().collection(e),this.intersect(e).length>0},allAreNeighbors:function(e){return e=this.cy().collection(e),this.neighborhood().intersect(e).length===e.length}})}(cytoscape),function(e){"use strict";var t=1,r=0;e.fn.eles({data:e.define.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),removeData:e.define.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),batchData:e.define.batchData({field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),scratch:e.define.data({field:"scratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeScratch:e.define.removeData({field:"scratch",triggerEvent:!1}),rscratch:e.define.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:e.define.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];return e?e._private.data.id:void 0},position:e.define.data({field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"rtrigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){var t=e.updateCompoundBounds();t.rtrigger("position")},canSet:function(e){return!e.locked()}}),silentPosition:e.define.data({field:"position",bindingEvent:"position",allowBinding:!1,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!1,triggerFnName:"trigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){e.updateCompoundBounds()},canSet:function(e){return!e.locked()}}),positions:function(t){if(e.is.plainObject(t))this.position(t);else if(e.is.fn(t)){for(var r=t,a=0;al?l:a,i=c>i?c:i,n=n>d?d:n,o=u>o?u:o}else if(v.isEdge()&&t.includeEdges){g=!0;var w=v.source()[0]._private.position,_=v.target()[0]._private.position,E=v._private.rstyle||{};if(l=w.x,c=_.x,d=w.y,u=_.y,l>c){var S=l;l=c,c=S}if(d>u){var S=d;d=u,u=S}a=a>l?l:a,i=c>i?c:i,n=n>d?d:n,o=u>o?u:o;for(var P=E.bezierPts||[],y=v._private.style.width.pxValue,M=0;Mi?k.x+y:i,n=k.y-yo?k.y+y:o}}var C=v._private.style,E=v._private.rstyle,D=C.content.strValue,N=C["font-size"],T=C["text-halign"],I=C["text-valign"],z=E.labelWidth,B=E.labelHeight||N.pxValue,X=E.labelX,R=E.labelY;if(g&&t.includeLabels&&D&&N&&void 0!=B&&void 0!=z&&void 0!=X&&void 0!=R&&T&&I){var Y,L,V,A,q=B,O=z;if(v.isEdge())Y=X-O/2,L=X+O/2,V=R-q/2,A=R+q/2;else{switch(T.value){case"left":Y=X-O,L=X;break;case"center":Y=X-O/2,L=X+O/2;break;case"right":Y=X,L=X+O}switch(I.value){case"top":V=R-q,A=R;break;case"center":V=R-q/2,A=R+q/2;break;case"bottom":V=R,A=R+q}}a=a>Y?Y:a,i=L>i?L:i,n=n>V?V:n,o=A>o?A:o}}}return{x1:a,x2:i,y1:n,y2:o,w:i-a,h:o-n}}})}(cytoscape),function(e){"use strict";function t(e){return function(){var t=this;if(0!==t.length&&t.isNode()&&!t.removed()){for(var r=0,a=t[0],i=a._private.edges,n=0;ne}),maxDegree:r("degree",function(e,t){return e>t}),minIndegree:r("indegree",function(e,t){return t>e}),maxIndegree:r("indegree",function(e,t){return e>t}),minOutdegree:r("outdegree",function(e,t){return t>e}),maxOutdegree:r("outdegree",function(e,t){return e>t})}),e.fn.eles({totalDegree:function(){for(var e=0,t=this.nodes(),r=0;rt&&(t=i+t),0>r&&(r=i+r);for(var n=t;n>=0&&r>n&&i>n;n++)a.push(this[n]);return new e.Collection(this.cy(),a)},size:function(){return this.length},eq:function(e){return this[e]},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(t){if(!e.is.fn(t))return this;var r=this.cy(),a=(new e.Collection(r),this.toArray().sort(t));return new e.Collection(r,a)},sortByZIndex:function(){return this.sort(e.Collection.zIndexSort)}}),e.Collection.zIndexSort=function(e,t){var r=function(e){return"nodes"==e._private.group?e.parents().size():"edges"==e._private.group?Math.max(e.source()[0].parents().size(),e.target()[0].parents().size()):0},a=e._private.style["z-index"].value-t._private.style["z-index"].value,i=0,n=0;return e.cy().hasCompoundNodes()&&(i=r(e),n=r(t)),i-n===0?"nodes"===e._private.group&&"edges"===t._private.group?1:"edges"===e._private.group&&"nodes"===t._private.group?-1:0===a?e._private.index-t._private.index:a:i-n}}(cytoscape),function(e){"use strict";e.fn.eles({updateStyle:function(e){var t=this._private.cy,r=t.style();e=e||void 0===e?!0:!1,r.apply(this);var a=this.updateCompoundBounds();return e?this.add(a).rtrigger("style"):this.add(a).trigger("style"),this},updateMappers:function(e){var t=this._private.cy,r=t.style();e=e||void 0===e?!0:!1,r.updateMappers(this);var a=this.updateCompoundBounds();return e?this.add(a).rtrigger("style"):this.add(a).trigger("style"),this},renderedCss:function(e){var t=this[0];if(t){var r=t.cy().style().getRenderedStyle(t);return void 0===e?r:r[e]}},css:function(t,r){var a=this.cy().style();if(e.is.plainObject(t)){var i=t;a.applyBypass(this,i),this.rtrigger("style")}else if(e.is.string(t)){if(void 0===r){var n=this[0];return n?n._private.style[t].strValue:void 0 -}a.applyBypass(this,t,r),this.rtrigger("style")}else if(void 0===t){var n=this[0];return n?a.getRawStyle(n):void 0}return this},removeCss:function(){for(var e=this.cy().style(),t=this,r=0;r0&&a.push(c)}return new e.Collection(n,a).filter(r)}}function r(t){return function(r){var a=[],i=this._private.cy,n=t||{};e.is.string(r)&&(r=i.$(r));for(var o=r.connectedEdges(),s=this._private.ids,l=0;l0;o||a.push(n)}}return new e.Collection(this._private.cy,a).filter(t)},kruskal:function(t){function r(e){for(var t=0;tl&&(n=l,a=s)}return{edge:a,dist:n}};0!==d.length;){var h=u(d),v=d.filter("#"+h);if(0!==v.length){if(d=d.not(v),v.same(t))break;if(o[h]===Math.Infinite)break;for(var g=v.neighborhood().nodes(),c=0;c0&&r.push(d[0]),r.push(c[0])}return new e.Collection(a,r).filter(t)},closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),e.fn.eles({source:t({attr:"source"}),target:t({attr:"target"})}),e.fn.eles({edgesWith:r(),edgesTo:r({thisIs:"source"})}),e.fn.eles({connectedEdges:function(t){for(var r=[],a=this._private.cy,i=this,n=0;n0&&r.push(o)}return new e.Collection(a,r).filter(t)},parents:function(t){for(var r=[],a=this.parent();a.nonempty();){for(var i=0;ie.math.sqDistanceToQuadraticBezier(r,a,f.startX,f.startY,f.cp2ax,f.cp2ay,f.selfEdgeMidX,f.selfEdgeMidY)||e.math.inBezierVicinity(r,a,f.selfEdgeMidX,f.selfEdgeMidY,f.cp2cx,f.cp2cy,f.endX,f.endY,Math.pow(s[h]._private.style.width.pxValue/2,2))&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToQuadraticBezier(r,a,f.selfEdgeMidX,f.selfEdgeMidY,f.cp2cx,f.cp2cy,f.endX,f.endY))&&(v=!0):"straight"==f.edgeType?e.math.inLineVicinity(r,a,f.startX,f.startY,f.endX,f.endY,2*s[h]._private.style.width.pxValue)&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToFiniteLine(r,a,f.startX,f.startY,f.endX,f.endY)&&(v=!0):"bezier"==f.edgeType&&e.math.inBezierVicinity(r,a,f.startX,f.startY,f.cp2x,f.cp2y,f.endX,f.endY,Math.pow(s[h]._private.style.width.pxValue/2,2))&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToQuadraticBezier(r,a,f.startX,f.startY,f.cp2x,f.cp2y,f.endX,f.endY)&&(v=!0),l.length&&l[l.length-1]==s[h]||(t.arrowShapes[s[h]._private.style["source-arrow-shape"].value].roughCollide(r,a,s[h]._private.rscratch.arrowStartX,s[h]._private.rscratch.arrowStartY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowStartX-s[h].source()[0]._private.position.x,s[h]._private.rscratch.arrowStartY-s[h].source()[0]._private.position.y],0)&&t.arrowShapes[s[h]._private.style["source-arrow-shape"].value].collide(r,a,s[h]._private.rscratch.arrowStartX,s[h]._private.rscratch.arrowStartY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowStartX-s[h].source()[0]._private.position.x,s[h]._private.rscratch.arrowStartY-s[h].source()[0]._private.position.y],0)||t.arrowShapes[s[h]._private.style["target-arrow-shape"].value].roughCollide(r,a,s[h]._private.rscratch.arrowEndX,s[h]._private.rscratch.arrowEndY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowEndX-s[h].target()[0]._private.position.x,s[h]._private.rscratch.arrowEndY-s[h].target()[0]._private.position.y],0)&&t.arrowShapes[s[h]._private.style["target-arrow-shape"].value].collide(r,a,s[h]._private.rscratch.arrowEndX,s[h]._private.rscratch.arrowEndY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowEndX-s[h].target()[0]._private.position.x,s[h]._private.rscratch.arrowEndY-s[h].target()[0]._private.position.y],0))&&(v=!0),v)if(i){var y=n.cy.getElementById(s[h]._private.data.source),m=n.cy.getElementById(s[h]._private.data.target);0!=s[h]._private.style.opacity.value&&"visible"==s[h]._private.style.visibility.value&&"element"==s[h]._private.style.display.value&&0!=y._private.style.opacity.value&&"visible"==y._private.style.visibility.value&&"element"==y._private.style.display.value&&0!=m._private.style.opacity.value&&"visible"==m._private.style.visibility.value&&"element"==m._private.style.display.value&&l.push(s[h])}else l.push(s[h])}return l.sort(this.zOrderSort),l.length>0?l[l.length-1]:null},t.prototype.getAllInBox=function(r,a,i,n){var o=(this.data,this.getCachedNodes()),s=this.getCachedEdges(),l=[],c=Math.min(r,i),d=Math.max(r,i),u=Math.min(a,n),p=Math.max(a,n);r=c,i=d,a=u,n=p;for(var h,v=0;vd?d+"-"+c:c+"-"+d,void 0==i[a]&&(i[a]=[]),i[a].push(l),o.push(a)}}for(var u,p,h,v,g,f,y,m,b,x,w,_,E,S,P,M=0;M1){var k=b.intersectLine(h.x,h.y,g,f,v.x,v.y,w/2),C=x.intersectLine(v.x,v.y,y,m,h.x,h.y,_/2),E={x:(k[0]+C[0])/2,y:(k[1]+C[1])/2},D=C[1]-k[1],N=C[0]-k[0],T=Math.sqrt(N*N+D*D),I={x:N,y:D},z={x:I.x/T,y:I.y/T};S={x:-z.y,y:z.x},(x.checkPoint(k[0],k[1],_/2,y,m,v.x,v.y)||b.checkPoint(C[0],C[1],w/2,g,f,h.x,h.y))&&(S={},P=!0)}for(var l,B,s=0;sdt,pt=e.math.distance({x:B.cp2x,y:B.cp2y},{x:B.endX,y:B.endY}),ht=ct>pt;if("bezier"===B.edgeType){var vt=!1;if(at||it||ut){vt=!0;var gt={x:B.cp2x-h.x,y:B.cp2y-h.y},ft=Math.sqrt(gt.x*gt.x+gt.y*gt.y),yt={x:gt.x/ft,y:gt.y/ft},mt=Math.max(g,f),bt={x:B.cp2x+2*yt.x*mt,y:B.cp2y+2*yt.y*mt},xt=b.intersectLine(h.x,h.y,g,f,bt.x,bt.y,w/2);ut?(B.cp2x=B.cp2x+yt.x*(ct-dt),B.cp2y=B.cp2y+yt.y*(ct-dt)):(B.cp2x=xt[0]+yt.x*ct,B.cp2y=xt[1]+yt.y*ct)}if(nt||ot||ht){vt=!0;var gt={x:B.cp2x-v.x,y:B.cp2y-v.y},ft=Math.sqrt(gt.x*gt.x+gt.y*gt.y),yt={x:gt.x/ft,y:gt.y/ft},mt=Math.max(g,f),bt={x:B.cp2x+2*yt.x*mt,y:B.cp2y+2*yt.y*mt},wt=x.intersectLine(v.x,v.y,y,m,bt.x,bt.y,_/2);ht?(B.cp2x=B.cp2x+yt.x*(ct-pt),B.cp2y=B.cp2y+yt.y*(ct-pt)):(B.cp2x=wt[0]+yt.x*ct,B.cp2y=wt[1]+yt.y*ct)}vt&&this.findEndpoints(l)}this.projectBezier(l)}}}return i},t.prototype.findEndpoints=function(r){var a,i=r.source()[0],n=r.target()[0],o=(i._private.position,n._private.position,r._private.style["target-arrow-shape"].value),s=r._private.style["source-arrow-shape"].value,l=n._private.style["border-width"].pxValue,c=i._private.style["border-width"].pxValue,d=r._private.rscratch; -if("self"==r._private.rscratch.edgeType){var u=[d.cp2cx,d.cp2cy];a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),u[0],u[1],l/2);var p=e.math.shortenIntersection(a,u,t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,u,t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1];var u=[d.cp2ax,d.cp2ay];a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),u[0],u[1],c/2);var v=e.math.shortenIntersection(a,u,t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,u,t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if("straight"==d.edgeType){a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),i.position().x,i.position().y,l/2),d.noArrowPlacement=0==a.length?!0:!1;var p=e.math.shortenIntersection(a,[i.position().x,i.position().y],t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,[i.position().x,i.position().y],t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1],a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),n.position().x,n.position().y,c/2),d.noArrowPlacement=0==a.length?!0:!1;var v=e.math.shortenIntersection(a,[n.position().x,n.position().y],t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,[n.position().x,n.position().y],t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if("bezier"==d.edgeType){var u=[d.cp2x,d.cp2y];a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),u[0],u[1],l/2);var p=e.math.shortenIntersection(a,u,t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,u,t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1],a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),u[0],u[1],c/2);var v=e.math.shortenIntersection(a,u,t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,u,t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if(d.isArcEdge)return},t.prototype.findEdges=function(e){for(var t=this.getCachedEdges(),r={},a=[],i=0;ip*v+h*g)t._private.rscratch.straightEdgeTooShort=!0;else{var u=t._private.rscratch;this.drawStyledEdge(t,e,[u.startX,u.startY,u.endX,u.endY],d,c),t._private.rscratch.straightEdgeTooShort=!1}}else{var u=t._private.rscratch;this.drawStyledEdge(t,e,[u.startX,u.startY,u.cp2x,u.cp2y,u.endX,u.endY],d,c)}t._private.rscratch.noArrowPlacement!==!0&&void 0!==t._private.rscratch.startX&&this.drawArrowheads(e,t,r)}}}}};var r=function(e,t){var r=Math.sqrt(Math.pow(e[4]-e[0],2)+Math.pow(e[5]-e[1],2));r+=Math.sqrt(Math.pow((e[4]+e[0])/2-e[2],2)+Math.pow((e[5]+e[1])/2-e[3],2));var a,i=Math.ceil(r/t);if(!(i>0))return null;a=new Array(2*i);for(var n=0;i>n;n++){var o=n/i;a[2*n]=e[0]*(1-o)*(1-o)+2*e[2]*(1-o)*o+e[4]*o*o,a[2*n+1]=e[1]*(1-o)*(1-o)+2*e[3]*(1-o)*o+e[5]*o*o}return a},a=function(e,t){var r,a=Math.sqrt(Math.pow(e[2]-e[0],2)+Math.pow(e[3]-e[1],2)),i=Math.ceil(a/t);if(!(i>0))return null;r=new Array(2*i);for(var n=[e[2]-e[0],e[3]-e[1]],o=0;i>o;o++){var s=o/i;r[2*o]=n[0]*s+e[0],r[2*o+1]=n[1]*s+e[1]}return r};t.prototype.drawStyledEdge=function(e,t,i,n,o){var s=this.data.cy,l=s.zoom();if("solid"==n)t.beginPath(),t.moveTo(i[0],i[1]),6==i.length?t.quadraticCurveTo(i[2],i[3],i[4],i[5]):t.lineTo(i[2],i[3]),t.stroke();else if("dotted"==n){var c;if(c=6==i.length?r(i,16,!0):a(i,16,!0),!c)return;var d=Math.max(1.6*o,3.4)*l,u=2*d,p=2*d;u=Math.max(u,1),p=Math.max(p,1);var h=this.createBuffer(u,p),v=h[1];v.setTransform(1,0,0,1,0,0),v.clearRect(0,0,u,p),v.fillStyle=t.strokeStyle,v.beginPath(),v.arc(u/2,p/2,.5*d,0,2*Math.PI,!1),v.fill(),t.beginPath();for(var g=0;gn?s+=Math.PI/2:s=-(Math.PI/2+s),e.translate(a,i),e.moveTo(0,0),e.rotate(-s);var l=this.getArrowWidth(e.lineWidth);e.scale(l,l),e.beginPath(),t.arrowShapes[r].draw(e),e.closePath(),e.fill(),e.scale(1/l,1/l),e.rotate(s),e.translate(-a,-i)}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas"),r={},a=9e3;t.prototype.getCachedImage=function(e,t){if(r[e]&&r[e].image)return r[e].keepTime=a,r[e].image;var i=r[e];return void 0==i&&(r[e]=new Object,r[e].image=new Image,r[e].image.onload=t,r[e].image.src=e,r[e].keepTime=a,i=r[e]),i.image},t.prototype.swapCachedImage=function(e){if(r[e]){if(r[e].image&&r[e].image.complete){var t=r[e].image,a=document.createElement("canvas");return a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(t,0,0),r[e].image=a,r[e].swappedWithCanvas=!0,a}return null}return null},t.prototype.updateImageCaches=function(){for(var e in r)r[e].keepTime<=0?(void 0!=r[e].image&&(r[e].image.src=void 0,r[e].image=void 0),r[e]=void 0):r[e]-=1},t.prototype.drawImage=function(e,t,r,a,i,n,o){o.widthScale=.5,o.heightScale=.5,o.rotate=n;canvas.drawImage(o,t,r)},t.prototype.drawInscribedImage=function(e,r,a){var i=this,n=(this.data.cy._private.zoom,a._private.position.x),o=a._private.position.y,s=this.getNodeWidth(a),l=this.getNodeHeight(a);e.save(),t.nodeShapes[i.getNodeShape(a)].drawPath(e,n,o,s,l),e.clip();var c=[r.width,r.height];e.drawImage(r,n-c[0]/2,o-c[1]/2,c[0],c[1]),e.restore(),a._private.style["border-width"].value>0&&e.stroke()}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawEdgeText=function(e,t){if(t.visible()&&(!this.hideEdgesOnViewport||!(this.dragData.didDrag||this.pinching||this.hoverData.dragging||this.data.wheel||this.swipePanning))){var r=t._private.style["font-size"].pxValue*t.cy().zoom(),a=t._private.style["min-zoomed-font-size"].pxValue;if(!(a>r)){e.textAlign="center",e.textBaseline="middle",this.recalculateEdgeLabelProjection(t);var i=t._private.rscratch;this.drawText(e,t,i.labelX,i.labelY)}}},t.prototype.drawNodeText=function(e,t){if(t.visible()){var r=t._private.style["font-size"].pxValue*t.cy().zoom(),a=t._private.style["min-zoomed-font-size"].pxValue;if(!(a>r)){this.recalculateNodeLabelProjection(t);var i=t._private.style["text-halign"].strValue,n=t._private.style["text-valign"].strValue,o=t._private.rscratch;switch(i){case"left":e.textAlign="right";break;case"right":e.textAlign="left";break;case"center":default:e.textAlign="center"}switch(n){case"top":e.textBaseline="bottom";break;case"bottom":e.textBaseline="top";break;case"center":default:e.textBaseline="middle"}this.drawText(e,t,o.labelX,o.labelY)}}},t.prototype.setupTextStyle=function(e,t){var r=t.effectiveOpacity(),a=t._private.style,i=a["font-style"].strValue,n=a["font-size"].pxValue+"px",o=a["font-family"].strValue,s=(a["font-variant"].strValue,a["font-weight"].strValue);e.font=i+" "+s+" "+n+" "+o;var l=String(a.content.value),c=a["text-transform"].value;return"none"==c||("uppercase"==c?l=l.toUpperCase():"lowercase"==c&&(l=l.toLowerCase())),e.lineJoin="round",e.fillStyle="rgba("+a.color.value[0]+","+a.color.value[1]+","+a.color.value[2]+","+a["text-opacity"].value*a.opacity.value*r+")",e.strokeStyle="rgba("+a["text-outline-color"].value[0]+","+a["text-outline-color"].value[1]+","+a["text-outline-color"].value[2]+","+a["text-opacity"].value*a.opacity.value*r+")",l},t.prototype.drawText=function(e,t,r,a){var i=t._private.style,n=t.effectiveOpacity();if(0!==n){var o=this.setupTextStyle(e,t);if(void 0!=o&&!isNaN(r)&&!isNaN(a)){var s=2*i["text-outline-width"].value;s>0&&(e.lineWidth=s,e.strokeText(o,r,a)),e.fillText(""+o,r,a)}}}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawNode=function(e,r,a){var i,n;if(r.visible()){var o=r.effectiveOpacity();if(0!==o)if(i=this.getNodeWidth(r),n=this.getNodeHeight(r),e.lineWidth=r._private.style["border-width"].pxValue,void 0!==a&&a){var s=r._private.style["overlay-padding"].pxValue,l=r._private.style["overlay-opacity"].value,c=r._private.style["overlay-color"].value;l>0&&(e.fillStyle="rgba( "+c[0]+", "+c[1]+", "+c[2]+", "+l+" )",t.nodeShapes.roundrectangle.draw(e,r._private.position.x,r._private.position.y,i+2*s,n+2*s))}else{e.fillStyle="rgba("+r._private.style["background-color"].value[0]+","+r._private.style["background-color"].value[1]+","+r._private.style["background-color"].value[2]+","+r._private.style["background-opacity"].value*r._private.style.opacity.value*o+")",e.strokeStyle="rgba("+r._private.style["border-color"].value[0]+","+r._private.style["border-color"].value[1]+","+r._private.style["border-color"].value[2]+","+r._private.style["border-opacity"].value*r._private.style.opacity.value*o+")",e.lineJoin="miter";var d=r._private.style["background-image"].value[2]||r._private.style["background-image"].value[1];if(void 0!=d){var u=this,p=this.getCachedImage(d,function(){u.data.canvasNeedsRedraw[t.NODE]=!0,u.data.canvasNeedsRedraw[t.DRAG]=!0,u.swapCachedImage(d),u.redraw()});0==p.complete?(t.nodeShapes[u.getNodeShape(r)].drawPath(e,r._private.position.x,r._private.position.y,i,n),e.stroke(),e.fillStyle="#555555",e.fill()):this.drawInscribedImage(e,p,r)}else t.nodeShapes[this.getNodeShape(r)].draw(e,r._private.position.x,r._private.position.y,i,n);this.drawPie(e,r),r._private.style["border-width"].pxValue>0&&(t.nodeShapes[this.getNodeShape(r)].drawPath(e,r._private.position.x,r._private.position.y,i,n),e.stroke())}}},t.prototype.hasPie=function(t){t=t[0];for(var r=1;r<=e.style.pieBackgroundN;r++){var a=t._private.style["pie-"+r+"-background-size"].value;if(a>0)return!0}return!1},t.prototype.drawPie=function(r,a){if(a=a[0],this.hasPie(a)){var i=this.getNodeWidth(a),n=this.getNodeHeight(a),o=a._private.position.x,s=a._private.position.y,l=Math.min(i,n)/2,c=0;r.save(),t.nodeShapes[this.getNodeShape(a)].drawPath(r,o,s,i,n),r.clip();for(var d=1;d<=e.style.pieBackgroundN;d++){{var u=a._private.style["pie-"+d+"-background-size"].value,p=a._private.style["pie-"+d+"-background-color"],h=u/100,v=1.5*Math.PI+2*Math.PI*c,g=2*Math.PI*h,f=v+g;o+l*Math.cos(v),s+l*Math.sin(v)}0===u||c>=1||c+h>1||(r.beginPath(),r.moveTo(o,s),r.arc(o,s,l,v,f),r.closePath(),r.fillStyle="rgb("+p.value[0]+","+p.value[1]+","+p.value[2]+")",r.fill(),c+=h)}r.restore()}}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.getPixelRatio=function(){var e=this.data.canvases[0],t=e.getContext("2d"),r=t.backingStorePixelRatio||t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1,a="undefined"!=typeof InstallTrigger;return a?1:(window.devicePixelRatio||1)/r},t.prototype.matchCanvasSize=function(e){var r,a=this.data,i=e.clientWidth,n=e.clientHeight,o=i,s=n,l=this.getPixelRatio();o*=l,s*=l;var c=a.canvasContainer;c.style.width=i+"px",c.style.height=n+"px";for(var d=0;d0&&(_.strokeStyle="rgba("+E["selection-box-border-color"].value[0]+","+E["selection-box-border-color"].value[1]+","+E["selection-box-border-color"].value[2]+","+E["selection-box-opacity"].value+")",_.strokeRect(d.select[0],d.select[1],d.select[2]-d.select[0],d.select[3]-d.select[1]))}if(d.bgActivePosistion){var p=d.cy.zoom(),P=d.bgActivePosistion;_.fillStyle="rgba("+E["active-bg-color"].value[0]+","+E["active-bg-color"].value[1]+","+E["active-bg-color"].value[2]+","+E["active-bg-opacity"].value+")",_.beginPath(),_.arc(P.x,P.y,E["active-bg-size"].pxValue/p,0,2*Math.PI),_.fill()}i||(d.canvasNeedsRedraw[t.SELECT_BOX]=!1)}var M=+new Date;void 0===s.averageRedrawTime&&(s.averageRedrawTime=M-y),s.averageRedrawTime=s.averageRedrawTime/2+(M-y)/2}e=e||{};var a=e.forcedContext,i=e.drawAllLayers,n=e.forcedZoom,o=e.forcedPan,s=this,l=this.getPixelRatio(),c=s.data.cy,d=s.data;clearTimeout(this.redrawTimeout),void 0===this.averageRedrawTime&&(this.averageRedrawTime=0);var u=1e3/60,p=1e3,h=this.averageRedrawTime;h=Math.max(u,h),h=Math.min(h,p),void 0===this.lastDrawTime&&(this.lastDrawTime=0);var v=+new Date,g=v-this.lastDrawTime,f=g>=h;if(!a){if(!f)return clearTimeout(this.redrawTimeout),void(this.redrawTimeout=setTimeout(function(){s.redraw()},h));this.lastDrawTime=v}var y=v;a?r():setTimeout(r,0),a||s.initrender||(s.initrender=!0,c.trigger("initrender"))}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawPolygonPath=function(e,t,r,a,i,n){e.translate(t,r),e.scale(a/2,i/2),e.beginPath(),e.moveTo(n[0],n[1]);for(var o=1;o0&&n>0&&(s.clearRect(0,0,i,n),e.bg&&(s.fillStyle=e.bg,s.rect(0,0,i,n),s.fill()),s.globalCompositeOperation="source-over",this.redraw(e.full?{forcedContext:s,drawAllLayers:!0,forcedZoom:1,forcedPan:{x:-a.x1,y:-a.y1}}:{forcedContext:s,drawAllLayers:!0})),o.toDataURL("image/png")}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.registerBinding=function(e,t,r,a){this.bindings.push({target:e,event:t,handler:r,useCapture:a}),e.addEventListener(t,r,a)},t.prototype.load=function(){var r=this,a=function(e,t,r){if(!t)for(var a=e.parents(),i=0;io[0]&&a.pageXo[1]&&a.pageY=t.panOrBoxSelectDelay)&&Math.abs(c[3]-c[1])+Math.abs(c[2]-c[0])<4&&s.panningEnabled()&&s.userPanningEnabled())r.hoverData.dragging=!0,c[4]=0;else{if(s.boxSelectionEnabled()&&Math.pow(c[2]-c[0],2)+Math.pow(c[3]-c[1],2)>7&&c[4]&&(clearTimeout(r.bgActiveTimeout),r.data.bgActivePosistion=void 0),p&&p.isEdge()&&p.active()&&p.unactivate(),d!=u&&(u&&u.trigger(new e.Event(a,{type:"mouseout",cyPosition:{x:l[0],y:l[1]}})),d&&d.trigger(new e.Event(a,{type:"mouseover",cyPosition:{x:l[0],y:l[1]}})),r.hoverData.last=d),p&&p.isNode()&&r.nodeIsDraggable(p)){r.dragData.didDrag=!0,r.hoverData.draggingEles=!0;var y=[];new e.Collection(s,v).positions(function(e,t){if(t.isNode()&&r.nodeIsDraggable(t)){var a=t.position();return{x:a.x+h[0],y:a.y+h[1]}}}),new e.Collection(s,y).trigger("drag"),c[2]==c[0]&&c[3]==c[1]&&(r.data.canvasNeedsRedraw[t.NODE]=!0),r.data.canvasNeedsRedraw[t.DRAG]=!0}s.boxSelectionEnabled()&&(r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0),i=!0}return c[2]=l[0],c[3]=l[1],r.redraw(),i?(a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),!1):void 0},!1),r.registerBinding(window,"mouseup",function(a){var i=r.hoverData.capture;if(i){r.hoverData.capture=!1;var o=r.data.cy,s=r.projectIntoViewport(a.pageX,a.pageY),l=r.data.select,c=r.findNearestElement(s[0],s[1],!0),d=(r.getCachedNodes(),r.getCachedEdges(),r.dragData.possibleDragElements),u=r.hoverData.down,p=a.shiftKey;if(r.data.bgActivePosistion=void 0,clearTimeout(r.bgActiveTimeout),r.hoverData.cxtStarted=!1,r.hoverData.draggingEles=!1,u&&u.unactivate(),3===r.hoverData.which){var h=new e.Event(a,{type:"cxttapend",cyPosition:{x:s[0],y:s[1]}});if(u?u.trigger(h):o.trigger(h),!r.hoverData.cxtDragged){var v=new e.Event(a,{type:"cxttap",cyPosition:{x:s[0],y:s[1]}});u?u.trigger(v):o.trigger(v)}r.hoverData.cxtDragged=!1,r.hoverData.which=null}else{if(null!=u||r.dragData.didDrag||Math.pow(l[2]-l[0],2)+Math.pow(l[3]-l[1],2)>7&&l[4]||r.hoverData.dragging||(o.$(":selected").unselect(),d.length>0&&(r.data.canvasNeedsRedraw[t.NODE]=!0),r.dragData.possibleDragElements=d=[]),null!=c?c.trigger(new e.Event(a,{type:"mouseup",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tapend",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vmouseup",cyPosition:{x:s[0],y:s[1]}})):null==c&&o.trigger(new e.Event(a,{type:"mouseup",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tapend",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vmouseup",cyPosition:{x:s[0],y:s[1]}})),Math.pow(l[2]-l[0],2)+Math.pow(l[3]-l[1],2)==0&&(null!=c?c.trigger(new e.Event(a,{type:"click",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tap",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vclick",cyPosition:{x:s[0],y:s[1]}})):null==c&&o.trigger(new e.Event(a,{type:"click",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tap",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vclick",cyPosition:{x:s[0],y:s[1]}}))),c!=u||r.dragData.didDrag){if(c==u&&null!=c&&c._private.grabbed){for(var g=o.$(":grabbed"),f=0;f7&&l[4]){for(var x=[],w=r.getAllInBox(l[0],l[1],l[2],l[3]),f=(new e.Event(a,{type:"select"}),0);f0&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}if(r.hoverData.dragging=!1,!l[4]){for(var f=0;f=0&&m>=l&&d>=0&&m>=d&&c>=0&&b>=c&&u>=0&&b>=u; -var C=s.pan(),D=s.zoom();if(p=x(l,c,d,u),h=[(l+d)/2,(c+u)/2],v=[(h[0]-C.x)/D,(h[1]-C.y)/D],100>p){var N=r.findNearestElement(E[0],E[1],!0),T=r.findNearestElement(E[2],E[3],!0);return N&&N.isNode()?(N.activate().trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=N):T&&T.isNode()?(T.activate().trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=T):(s.trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=null),r.touchData.start&&(r.touchData.start._private.grabbed=!1),r.touchData.cxt=!0,r.touchData.cxtDragged=!1,r.data.bgActivePosistion=void 0,void r.redraw()}}if(o.touches[2]);else if(o.touches[1]);else if(o.touches[0]){var I=r.findNearestElement(E[0],E[1],!0);if(null!=I){if(I.activate(),r.touchData.start=I,"nodes"==I._private.group&&r.nodeIsDraggable(I)){var z=r.dragData.touchDragEles=[];if(i(I,z),I.trigger("grab"),I.selected()){z=r.dragData.touchDragEles=[];for(var B=s.$("node:selected"),X=0;X250&&(r.touchData.start?r.touchData.start.trigger(new e.Event(o,{type:"taphold",cyPosition:{x:E[0],y:E[1]}})):(r.data.cy.trigger(new e.Event(o,{type:"taphold",cyPosition:{x:E[0],y:E[1]}})),s.$(":selected").unselect()))},1e3)}}r.redraw()},!1),r.registerBinding(window,"touchmove",function(a){var i=r.data.select,n=r.touchData.capture;n&&a.preventDefault();var o=r.data.cy,s=(r.getCachedNodes(),r.getCachedEdges(),r.touchData.now),h=r.touchData.earlier;if(a.touches[0]){var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}if(a.touches[1]){var m=r.projectIntoViewport(a.touches[1].pageX,a.touches[1].pageY);s[2]=m[0],s[3]=m[1]}if(a.touches[2]){var m=r.projectIntoViewport(a.touches[2].pageX,a.touches[2].pageY);s[4]=m[0],s[5]=m[1]}for(var b=[],w=0;w=1.5||M>=150){r.touchData.cxt=!1,r.touchData.start&&(r.touchData.start.unactivate(),r.touchData.start=null),r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;var C=new e.Event(a,{type:"cxttapend",cyPosition:{x:s[0],y:s[1]}});r.touchData.start?r.touchData.start.trigger(C):o.trigger(C)}}if(n&&r.touchData.cxt){var C=new e.Event(a,{type:"cxtdrag",cyPosition:{x:s[0],y:s[1]}});r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,r.touchData.start?r.touchData.start.trigger(C):o.trigger(C),r.touchData.start&&(r.touchData.start._private.grabbed=!1),r.touchData.cxtDragged=!0}else if(n&&a.touches[2]&&o.boxSelectionEnabled())r.data.bgActivePosistion=void 0,clearTimeout(this.threeFingerSelectTimeout),this.lastThreeTouch=+new Date,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),i[4]=1;else if(n&&a.touches[1]&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;var _=a.touches[0].pageX-g,E=a.touches[0].pageY-f,S=a.touches[1].pageX-g,P=a.touches[1].pageY-f,M=x(_,E,S,P),k=M/p;if(1!=k&&y){var D=_-l,N=E-c,T=S-d,I=P-u,z=(D+T)/2,B=(N+I)/2,X=o.zoom(),R=X*k,Y=o.pan(),L=v[0]*X+Y.x,V=v[1]*X+Y.y,A={x:-R/X*(L-Y.x-z)+L,y:-R/X*(V-Y.y-B)+V};o._private.zoom=R,o._private.pan=A,o.trigger("pan zoom").notify("viewport"),p=M,l=_,c=E,d=S,u=P,r.pinching=!0}if(a.touches[0]){var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}if(a.touches[1]){var m=r.projectIntoViewport(a.touches[1].pageX,a.touches[1].pageY);s[2]=m[0],s[3]=m[1]}if(a.touches[2]){var m=r.projectIntoViewport(a.touches[2].pageX,a.touches[2].pageY);s[4]=m[0],s[5]=m[1]}}else if(a.touches[0]){{var q=r.touchData.start;r.touchData.last}if(null!=q&&"nodes"==q._private.group&&r.nodeIsDraggable(q)){var O=r.dragData.touchDragEles,F=new e.Collection(o,O).positions(function(e,t){if(r.nodeIsDraggable(t)){r.dragData.didDrag=!0;var a=t.position();return{x:a.x+b[0],y:a.y+b[1]}}});F.trigger("drag"),r.data.canvasNeedsRedraw[t.DRAG]=!0,r.touchData.startPosition[0]==h[0]&&r.touchData.startPosition[1]==h[1]&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}if(null!=q&&(q.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),q.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),q.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}}))),null==q){var $=r.findNearestElement(s[0],s[1],!0);null!=$&&($.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),$.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),$.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}}))),null==$&&(o.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),o.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),o.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}})))}r.touchData.last=$;for(var j=0;j4&&(r.touchData.singleTouchMoved=!0);if(n&&(null==q||q.isEdge())&&o.panningEnabled()&&o.userPanningEnabled()){q&&(q.unactivate(),r.data.bgActivePosistion||(r.data.bgActivePosistion={x:s[0],y:s[1]}),r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0),o.panBy({x:b[0]*o.zoom(),y:b[1]*o.zoom()}),r.swipePanning=!0;var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}}for(var w=0;w0&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}a.touches[1]||(r.pinching=!1);var y=!1;if(null!=d&&(d._private.active=!1,y=!0,d.trigger("unactivate")),a.touches[2])r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;else if(a.touches[1]);else if(a.touches[0]);else if(!a.touches[0]){if(r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,null!=d){1==d._private.grabbed&&(d._private.grabbed=!1,d.trigger("free"),d._private.rscratch.inDragLayer=!1);for(var m=d._private.edges,b=0;b=t||r.drawPolygon(e._private.position.x,e._private.position.y,t,a,nodeSapes.roundrectangle2.points)},intersectLine:function(t,r,i,n,o){return e.math.findPolygonIntersection(t,r,i,n,o,a.square.points)},intersectBox:function(){a.square.points}},a.pentagon={points:e.math.generateUnitNgonPointsFitToSquare(5,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.pentagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.pentagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.pentagon.points,e,t,i/2,n/2,l)},intersectBox:function(t,r,i,n,o,s,l,c,d){var u=a.pentagon.points;return e.math.boxIntersectPolygon(t,r,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.pentagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.pentagon.points,s,l,n,o,[0,-1],i)}},a.hexagon={points:e.math.generateUnitNgonPointsFitToSquare(6,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.hexagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.hexagon.points)},intersectLine:function(t,r,i,n,o,s,l){return e.math.polygonIntersectLine(o,s,a.hexagon.points,t,r,i/2,n/2,l)},intersectBox:function(t,r,i,n,o,s,l,c,d){var u=a.hexagon.points;return e.math.boxIntersectPolygon(t,r,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.hexagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.hexagon.points,s,l,n,o,[0,-1],i)}},a.heptagon={points:e.math.generateUnitNgonPointsFitToSquare(7,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.heptagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.heptagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.heptagon.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.heptagon.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.heptagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.heptagon.points,s,l,n,o,[0,-1],i)}},a.octagon={points:e.math.generateUnitNgonPointsFitToSquare(8,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.octagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.octagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.octagon.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.octagon.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.octagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.octagon.points,s,l,n,o,[0,-1],i)}};var i=new Array(20),n=e.math.generateUnitNgonPoints(5,0),o=e.math.generateUnitNgonPoints(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;ll;l++)i[4*l]=n[2*l],i[4*l+1]=n[2*l+1],i[4*l+2]=o[2*l],i[4*l+3]=o[2*l+1];i=e.math.fitPolygonToSquare(i),a.star5=a.star={points:i,draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.star5.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.star5.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.star5.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.star5.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.star5.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.star5.points,s,l,n,o,[0,-1],i)}}}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend(!0,{},r,t)}var r={ready:function(){},stop:function(){}};t.prototype.run=function(){var e=this.options,t=e.cy;t.nodes().positions(function(){return{x:0,y:0}}),t.one("layoutready",e.ready),t.trigger("layoutready"),t.one("layoutstop",e.stop),t.trigger("layoutstop")},t.prototype.stop=function(){var e=this.options;cy.one("layoutstop",e.stop),cy.trigger("layoutstop")},e("layout","null",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend(!0,{},r,t)}var r={ready:void 0,stop:void 0,fit:!0,padding:30};t.prototype.run=function(){var e=this.options,t=e.cy,r=t.nodes(),a=(t.edges(),t.container()),i=a.clientWidth,n=a.clientHeight;r.positions(function(e,t){return t.locked()?!1:{x:Math.round(Math.random()*i),y:Math.round(Math.random()*n)}}),t.one("layoutready",e.ready),t.trigger("layoutready"),e.fit&&t.fit(e.padding),t.one("layoutstop",e.stop),t.trigger("layoutstop")},t.prototype.stop=function(){},e("layout","random",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},r,t)}var r={fit:!0,padding:30,rows:void 0,columns:void 0,position:function(){},ready:void 0,stop:void 0};t.prototype.run=function(){var e=this.options,t=e,r=e.cy,a=r.nodes(),i=(r.edges(),r.container()),n=i.clientWidth,o=i.clientHeight;if(0==o||0==n)a.positions(function(){return{x:0,y:0}});else{var s=a.size(),l=Math.sqrt(s*o/n),c=Math.round(l),d=Math.round(n/o*l),u=function(e){if(void 0==e)return Math.min(c,d);var t=Math.min(c,d);t==c?c=e:d=e},p=function(e){if(void 0==e)return Math.max(c,d);var t=Math.max(c,d);t==c?c=e:d=e};if(null!=t.rows&&null!=t.columns)c=t.rows,d=t.columns;else if(null!=t.rows&&null==t.columns)c=t.rows,d=Math.ceil(s/c);else if(null==t.rows&&null!=t.columns)d=t.columns,c=Math.ceil(s/d);else if(d*c>s){var h=u(),v=p();(h-1)*v>=s?u(h-1):(v-1)*h>=s&&p(v-1)}else for(;s>d*c;){var h=u(),v=p();(v+1)*h>=s?p(v+1):u(h+1)}for(var g=n/d,f=o/c,y=0;y=d&&(P=0,S++)},k={},y=0;y0&&i.stableEnergy(t))return void h.stop();clearTimeout(v),v=setTimeout(w,g);var r=[];h.eachNode(function(e,t){var a=(e.name,e.data),i=a.element;null!=i&&(i.locked()||i.grabbed()||(i.silentPosition({x:p.x1+t.x,y:p.y1+t.y}),r.push(i)))});var a=+new Date-y>=16;i.liveUpdate&&r.length>0&&a&&(new e.Collection(n,r).rtrigger("position"),y=+new Date),f||(f=!0,n.one("layoutready",i.ready),n.trigger("layoutready"))}};h.renderer=m,h.screenSize(c,d),h.screenPadding(i.padding[0],i.padding[1],i.padding[2],i.padding[3]),h.screenStep(i.stepSize);var b=function(e){grabbed=this;var t=h.fromScreen(this.position()),r=arbor.Point(t.x,t.y);switch(this.scratch().arbor.p=r,e.type){case"grab":this.scratch().arbor.fixed=!0;break;case"dragstop":this.scratch().arbor.fixed=!1,this.scratch().arbor.tempMass=1e3}};o.bind("grab drag dragstop",b),o.each(function(e,a){if(!this.isFullAutoParent()){var n=this._private.data.id,o=t(this,i.nodeMass),s=this._private.locked;if(!a.isFullAutoParent()){var l=r({x:a.position().x,y:a.position().y});a.locked()||(this.scratch().arbor=h.addNode(n,{element:this,mass:o,fixed:s,x:s?l.x:void 0,y:s?l.y:void 0}))}}}),s.each(function(){var e=(this.id(),this.source().id()),r=this.target().id(),a=t(this,i.edgeLength);this.scratch().arbor=h.addEdge(e,r,{length:a})});var x=o.filter(":grabbable");i.ungrabifyWhileSimulating&&x.ungrabify();var w=function(){function e(){i.liveUpdate||(i.fit&&n.reset(),n.nodes().rtrigger("position")),o.unbind("grab drag dragstop",b),i.ungrabifyWhileSimulating&&x.grabify(),n.one("layoutstop",i.stop),n.trigger("layoutstop")}window.isIE?a(function(){e()}):e()};h.start(),setTimeout(function(){h.stop()},i.maxSimulationTime)},t.prototype.stop=function(){null!=this.system&&system.stop()},e("layout","arbor",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},r,t)}var r={fit:!0,ready:void 0,stop:void 0,rStepSize:10,padding:30,startAngle:1.5*Math.PI,counterclockwise:!1};t.prototype.run=function(){function e(){var e=0,t=d,r={x:l.x+v*Math.cos(e),y:l.y+v*Math.sin(e)},a={x:l.x+v*Math.cos(t),y:l.y+v*Math.sin(t)},i=Math.sqrt((a.x-r.x)*(a.x-r.x)+(a.y-r.y)*(a.y-r.y));return i}for(var t=this.options,r=t,a=t.cy,i=a.nodes().filter(function(){return!this.isFullAutoParent()}),n=(a.edges(),a.container()),o=n.clientWidth,s=n.clientHeight,l={x:o/2,y:s/2},c=r.startAngle,d=2*Math.PI/i.length,u=0,p=0;pm;){for(var b=f.shift(),x=b.neighborhood().nodes(),w=!1,d=0;dd;d++)for(var _=h[d],D=_.length,N=0;D>N;N++){var p=_[N],T=p._private.scratch.BreadthFirstLayout,I=M(p);I&&(T.intEle=I,C.push(p))}for(var d=0;dh.length-1;)h.push([]);h[B].push(p),T.depth=B,T.index=h[B].length-1}S()}for(var X=0,d=0;dl||0===t)&&(a+=s/c,i++)}return i=Math.max(1,i),a/=i,0===i&&(a=void 0),L[e.id()]=a,a},A=0;3>A;A++){for(var d=0;d0&&h[0].length<=3?c/2:0),u=2*Math.PI/h[r].length*i;return 0===r&&1===h[0].length&&(d=1),{x:q.x+d*Math.cos(u),y:q.y+d*Math.sin(u)}}return{x:(i+1)*n,y:(r+1)*o}}),r.fit&&i.fit(a.padding),i.one("layoutready",r.ready),i.trigger("layoutready"),i.one("layoutstop",r.stop),i.trigger("layoutstop")},t.prototype.stop=function(){},e("layout","breadthfirst",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},a,t)}var r,a={ready:function(){},stop:function(){},refresh:0,fit:!0,padding:30,randomize:!0,debug:!1,nodeRepulsion:1e4,nodeOverlap:10,idealEdgeLength:10,edgeElasticity:100,nestingFactor:5,gravity:250,numIter:100,initialTemp:200,coolingFactor:.95,minTemp:1};t.prototype.run=function(){var e=this.options,t=e.cy;r=1==e.debug?!0:!1;var a=new Date,n=i(t,e);r&&s(n),1==e.randomize&&(l(n,t),0=l;){var h=s[l++],v=r.idToIndex[h],g=r.layoutNodes[v],f=g.children;if(f.length>0){r.graphSet.push(f);for(var i=0;ia.count?0:a.graph},o=function(e,t,r,a){var i=a.graphSet[r];if(-1<$.inArray(e,i)&&-1<$.inArray(t,i))return{count:2,graph:r};for(var n=0,s=0;ss;s++)for(var l=e.layoutNodes[e.idToIndex[n[s]]],c=s+1;o>c;c++){var d=e.layoutNodes[e.idToIndex[n[c]]];p(l,d,e,t,r)}}},p=function(e,t,r,a,i){var n="Node repulsion. Node1: "+e.id+" Node2: "+t.id,o=t.positionX-e.positionX,s=t.positionY-e.positionY;if(n+="\ndirectionX: "+o+", directionY: "+s,0==o&&0==s)return void(n+="\nNodes have the same position.");var l=v(e,t,o,s);if(l>0){n+="\nNodes DO overlap.",n+="\nOverlap: "+l;var c=i.nodeOverlap*l,d=Math.sqrt(o*o+s*s);n+="\nDistance: "+d;var u=c*o/d,p=c*s/d}else{n+="\nNodes do NOT overlap.";var g=h(e,o,s),f=h(t,-1*o,-1*s),y=f.x-g.x,m=f.y-g.y,b=y*y+m*m,d=Math.sqrt(b);n+="\nDistance: "+d;var c=i.nodeRepulsion/b,u=c*y/d,p=c*m/d}e.offsetX-=u,e.offsetY-=p,t.offsetX+=u,t.offsetY+=p,n+="\nForceX: "+u+" ForceY: "+p,w(n)},h=function(e,t,r){var a=e.positionX,i=e.positionY,n=e.height,o=e.width,s=r/t,l=n/o,c="Computing clipping point of node "+e.id+" . Height: "+n+", Width: "+o+"\nDirection "+t+", "+r,d={};do{if(0==t&&r>0){d.x=a,c+="\nUp direction",d.y=i+n/2;break}if(0==t&&0>r){d.x=a,d.y=i+n/2,c+="\nDown direction";break}if(t>0&&s>=-1*l&&l>=s){d.x=a+o/2,d.y=i+o*r/2/t,c+="\nRightborder";break}if(0>t&&s>=-1*l&&l>=s){d.x=a-o/2,d.y=i-o*r/2/t,c+="\nLeftborder";break}if(r>0&&(-1*l>=s||s>=l)){d.x=a+n*t/2/r,d.y=i+n/2,c+="\nTop border";break}if(0>r&&(-1*l>=s||s>=l)){d.x=a-n*t/2/r,d.y=i-n/2,c+="\nBottom border";break}}while(!1);return c+="\nClipping point found at "+d.x+", "+d.y,w(c),d},v=function(e,t,r,a){if(r>0)var i=e.maxX-t.minX;else var i=t.maxX-e.minX;if(a>0)var n=e.maxY-t.minY;else var n=t.maxY-e.minY;return i>=0&&n>=0?Math.sqrt(i*i+n*n):0},g=function(e,t,r){for(var a=0;ap;p++){var h=e.layoutNodes[e.idToIndex[n[p]]];a="Node: "+h.id;var v=l-h.positionX,g=c-h.positionY,f=Math.sqrt(v*v+g*g);if(f>1){var y=r.gravity*v/f,m=r.gravity*g/f;h.offsetX+=y,h.offsetY+=m,a+=": Applied force: "+y+", "+m}else a+=": skypped since it's too close to center";w(a)}}},y=function(e){var t=[],r=0,a=-1;for(w("propagateForces"),t.push.apply(t,e.graphSet[0]),a+=e.graphSet[0].length;a>=r;){var i=t[r++],n=e.idToIndex[i],o=e.layoutNodes[n],s=o.children;if(0r)var n={x:r*e/i,y:r*t/i};else var n={x:e,y:t};return a+=".\nResult: ("+n.x+", "+n.y+")",w(a),n},x=function(e,t){var r="Propagating new position/size of node "+e.id,a=e.parentId;if(void 0==a)return r+=". No parent node.",void w(r);var i=t.layoutNodes[t.idToIndex[a]],n=!1;return(void 0==i.maxX||e.maxX+i.padRight>i.maxX)&&(i.maxX=e.maxX+i.padRight,n=!0,r+="\nNew maxX for parent node "+i.id+": "+i.maxX),(void 0==i.minX||e.minX-i.padLefti.maxY)&&(i.maxY=e.maxY+i.padBottom,n=!0,r+="\nNew maxY for parent node "+i.id+": "+i.maxY),(void 0==i.minY||e.minY-i.padTop - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/arbor.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/arbor.js deleted file mode 100755 index b6ae116d31..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/arbor.js +++ /dev/null @@ -1,67 +0,0 @@ -// -// arbor.js - version 0.91 -// a graph vizualization toolkit -// -// Copyright (c) 2011 Samizdat Drafting Co. -// Physics code derived from springy.js, copyright (c) 2010 Dennis Hotson -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -(function($){ - - /* etc.js */ var trace=function(msg){if(typeof(window)=="undefined"||!window.console){return}var len=arguments.length;var args=[];for(var i=0;i0){return a[0]}else{return null}}; - /* kernel.js */ var Kernel=function(b){var k=window.location.protocol=="file:"&&navigator.userAgent.toLowerCase().indexOf("chrome")>-1;var a=(window.Worker!==undefined&&!k);var i=null;var c=null;var f=[];f.last=new Date();var l=null;var e=null;var d=null;var h=null;var g=false;var j={system:b,tween:null,nodes:{},init:function(){if(typeof(Tween)!="undefined"){c=Tween()}else{if(typeof(arbor.Tween)!="undefined"){c=arbor.Tween()}else{c={busy:function(){return false},tick:function(){return true},to:function(){trace("Please include arbor-tween.js to enable tweens");c.to=function(){};return}}}}j.tween=c;var m=b.parameters();if(a){trace("using web workers");l=setInterval(j.screenUpdate,m.timeout);i=new Worker(arbor_path()+"arbor.js");i.onmessage=j.workerMsg;i.onerror=function(n){trace("physics:",n)};i.postMessage({type:"physics",physics:objmerge(m,{timeout:Math.ceil(m.timeout)})})}else{trace("couldn't use web workers, be careful...");i=Physics(m.dt,m.stiffness,m.repulsion,m.friction,j.system._updateGeometry);j.start()}return j},graphChanged:function(m){if(a){i.postMessage({type:"changes",changes:m})}else{i._update(m)}j.start()},particleModified:function(n,m){if(a){i.postMessage({type:"modify",id:n,mods:m})}else{i.modifyNode(n,m)}j.start()},physicsModified:function(m){if(!isNaN(m.timeout)){if(a){clearInterval(l);l=setInterval(j.screenUpdate,m.timeout)}else{clearInterval(d);d=null}}if(a){i.postMessage({type:"sys",param:m})}else{i.modifyPhysics(m)}j.start()},workerMsg:function(n){var m=n.data.type;if(m=="geometry"){j.workerUpdate(n.data)}else{trace("physics:",n.data)}},_lastPositions:null,workerUpdate:function(m){j._lastPositions=m;j._lastBounds=m.bounds},_lastFrametime:new Date().valueOf(),_lastBounds:null,_currentRenderer:null,screenUpdate:function(){var n=new Date().valueOf();var m=false;if(j._lastPositions!==null){j.system._updateGeometry(j._lastPositions);j._lastPositions=null;m=true}if(c&&c.busy()){m=true}if(j.system._updateBounds(j._lastBounds)){m=true}if(m){var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}if(c){c.tick()}o.redraw();var p=f.last;f.last=new Date();f.push(f.last-p);if(f.length>50){f.shift()}}}},physicsUpdate:function(){if(c){c.tick()}i.tick();var n=j.system._updateBounds();if(c&&c.busy()){n=true}var o=j.system.renderer;var m=new Date();var o=j.system.renderer;if(o!==undefined){if(o!==e){o.init(j.system);e=o}o.redraw({timestamp:m})}var q=f.last;f.last=m;f.push(f.last-q);if(f.length>50){f.shift()}var p=i.systemEnergy();if((p.mean+p.max)/2<0.05){if(h===null){h=new Date().valueOf()}if(new Date().valueOf()-h>1000){clearInterval(d);d=null}else{}}else{h=null}},fps:function(n){if(n!==undefined){var q=1000/Math.max(1,targetFps);j.physicsModified({timeout:q})}var r=0;for(var p=0,o=f.length;p0);if(y){$.extend(c.adjacency[D][E].data,z.data);return}else{c.edges[z._id]=z;c.adjacency[D][E].push(z);var x=(z.length!==undefined)?z.length:1;k.push({t:"addSpring",id:z._id,fm:D,to:E,l:x});h._notify()}return z},pruneEdge:function(C){k.push({t:"dropSpring",id:C._id});delete c.edges[C._id];for(var z in c.adjacency){for(var D in c.adjacency[z]){var A=c.adjacency[z][D];for(var B=A.length-1;B>=0;B--){if(c.adjacency[z][D][B]._id===C._id){c.adjacency[z][D].splice(B,1)}}}}h._notify()},getEdges:function(y,x){y=h.getNode(y);x=h.getNode(x);if(!y||!x){return[]}if(typeof(c.adjacency[y._id])!=="undefined"&&typeof(c.adjacency[y._id][x._id])!=="undefined"){return c.adjacency[y._id][x._id]}return[]},getEdgesFrom:function(x){x=h.getNode(x);if(!x){return[]}if(typeof(c.adjacency[x._id])!=="undefined"){var y=[];$.each(c.adjacency[x._id],function(A,z){y=y.concat(z)});return y}return[]},getEdgesTo:function(x){x=h.getNode(x);if(!x){return[]}var y=[];$.each(c.edges,function(A,z){if(z.target==x){y.push(z)}});return y},eachEdge:function(x){$.each(c.edges,function(B,z){var A=c.nodes[z.source._id]._p;var y=c.nodes[z.target._id]._p;if(A.x==null||y.x==null){return}A=(w!==null)?h.toScreen(A):A;y=(w!==null)?h.toScreen(y):y;if(A&&y){x.call(h,z,A,y)}})},prune:function(y){var x={dropped:{nodes:[],edges:[]}};if(y===undefined){$.each(c.nodes,function(A,z){x.dropped.nodes.push(z);h.pruneNode(z)})}else{h.eachNode(function(A){var z=y.call(h,A,{from:h.getEdgesFrom(A),to:h.getEdgesTo(A)});if(z){x.dropped.nodes.push(A);h.pruneNode(A)}})}return x},graft:function(y){var x={added:{nodes:[],edges:[]}};if(y.nodes){$.each(y.nodes,function(A,z){var B=h.getNode(A);if(B){B.data=z}else{x.added.nodes.push(h.addNode(A,z))}c.kernel.start()})}if(y.edges){$.each(y.edges,function(B,z){var A=h.getNode(B);if(!A){x.added.nodes.push(h.addNode(B,{}))}$.each(z,function(F,C){var E=h.getNode(F);if(!E){x.added.nodes.push(h.addNode(F,{}))}var D=h.getEdges(B,F);if(D.length>0){D[0].data=C}else{x.added.edges.push(h.addEdge(B,F,C))}})})}return x},merge:function(y){var x={added:{nodes:[],edges:[]},dropped:{nodes:[],edges:[]}};$.each(c.edges,function(C,B){if((y.edges[B.source.name]===undefined||y.edges[B.source.name][B.target.name]===undefined)){h.pruneEdge(B);x.dropped.edges.push(B)}});var A=h.prune(function(C,B){if(y.nodes[C.name]===undefined){x.dropped.nodes.push(C);return true}});var z=h.graft(y);x.added.nodes=x.added.nodes.concat(z.added.nodes);x.added.edges=x.added.edges.concat(z.added.edges);x.dropped.nodes=x.dropped.nodes.concat(A.dropped.nodes);x.dropped.edges=x.dropped.edges.concat(A.dropped.edges);return x},tweenNode:function(A,x,z){var y=h.getNode(A);if(y){c.tween.to(y,x,z)}},tweenEdge:function(y,x,B,A){if(A===undefined){h._tweenEdge(y,x,B)}else{var z=h.getEdges(y,x);$.each(z,function(C,D){h._tweenEdge(D,B,A)})}},_tweenEdge:function(y,x,z){if(y&&y._id!==undefined){c.tween.to(y,x,z)}},_updateGeometry:function(A){if(A!=undefined){var x=(A.epoch1||C.y*w.height>1){p=_newBounds;return true}else{return false}},energy:function(){return a},bounds:function(){var y=null;var x=null;$.each(c.nodes,function(B,A){if(!y){y=new Point(A._p);x=new Point(A._p);return}var z=A._p;if(z.x===null||z.y===null){return}if(z.x>y.x){y.x=z.x}if(z.y>y.y){y.y=z.y}if(z.x0){c.kernel.graphChanged(k);k=[];i=null}}};c.kernel=Kernel(h);c.tween=c.kernel.tween||null;var e=(window.__defineGetter__==null||window.__defineSetter__==null)?function(y,x,z){if(!y.hasOwnProperty(x)){Object.defineProperty(y,x,z)}}:function(y,x,z){if(z.get){y.__defineGetter__(x,z.get)}if(z.set){y.__defineSetter__(x,z.set)}};var n=function(x){this._n=x;this._state=c};n.prototype=new Point();e(n.prototype,"x",{get:function(){return this._n._p.x},set:function(x){this._state.kernel.particleModified(this._n._id,{x:x})}});e(n.prototype,"y",{get:function(){return this._n._p.y},set:function(x){this._state.kernel.particleModified(this._n._id,{y:x})}});e(Node.prototype,"p",{get:function(){return new n(this)},set:function(x){this._p.x=x.x;this._p.y=x.y;this._state.kernel.particleModified(this._id,{x:x.x,y:x.y})}});e(Node.prototype,"mass",{get:function(){return this._mass},set:function(x){this._mass=x;this._state.kernel.particleModified(this._id,{m:x})}});e(Node.prototype,"tempMass",{set:function(x){this._state.kernel.particleModified(this._id,{_m:x})}});e(Node.prototype,"fixed",{get:function(){return this._fixed},set:function(x){this._fixed=x;this._state.kernel.particleModified(this._id,{f:x?1:0})}});return h}; - /* barnes-hut.js */ var BarnesHutTree=function(){var b=[];var a=0;var e=null;var d=0.5;var c={init:function(g,h,f){d=f;a=0;e=c._newBranch();e.origin=g;e.size=h.subtract(g)},insert:function(j){var f=e;var g=[j];while(g.length){var h=g.shift();var m=h._m||h.m;var p=c._whichQuad(h,f);if(f[p]===undefined){f[p]=h;f.mass+=m;if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}}else{if("origin" in f[p]){f.mass+=(m);if(f.p){f.p=f.p.add(h.p.multiply(m))}else{f.p=h.p.multiply(m)}f=f[p];g.unshift(h)}else{var l=f.size.divide(2);var n=new Point(f.origin);if(p[0]=="s"){n.y+=l.y}if(p[1]=="e"){n.x+=l.x}var o=f[p];f[p]=c._newBranch();f[p].origin=n;f[p].size=l;f.mass=m;f.p=h.p.multiply(m);f=f[p];if(o.p.x===h.p.x&&o.p.y===h.p.y){var k=l.x*0.08;var i=l.y*0.08;o.p.x=Math.min(n.x+l.x,Math.max(n.x,o.p.x-k/2+Math.random()*k));o.p.y=Math.min(n.y+l.y,Math.max(n.y,o.p.y-i/2+Math.random()*i))}g.push(o);g.unshift(h)}}}},applyForces:function(m,g){var f=[e];while(f.length){node=f.shift();if(node===undefined){continue}if(m===node){continue}if("f" in node){var k=m.p.subtract(node.p);var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node._m||node.m)).divide(l*l))}else{var j=m.p.subtract(node.p.divide(node.mass)).magnitude();var h=Math.sqrt(node.size.x*node.size.y);if(h/j>d){f.push(node.ne);f.push(node.nw);f.push(node.se);f.push(node.sw)}else{var k=m.p.subtract(node.p.divide(node.mass));var l=Math.max(1,k.magnitude());var i=((k.magnitude()>0)?k:Point.random(1)).normalize();m.applyForce(i.multiply(g*(node.mass)).divide(l*l))}}}},_whichQuad:function(i,f){if(i.p.exploded()){return null}var h=i.p.subtract(f.origin);var g=f.size.divide(2);if(h.y-1){o.splice(p,1)}delete c.particles[r];delete l.particles[r]},modifyNode:function(r,p){if(r in c.particles){var q=c.particles[r];if("x" in p){q.p.x=p.x}if("y" in p){q.p.y=p.y}if("m" in p){q.m=p.m}if("f" in p){q.fixed=(p.f===1)}if("_m" in p){if(q._m===undefined){q._m=q.m}q.m=p._m}}},addSpring:function(t){var s=t.id;var p=t.l;var r=c.particles[t.fm];var q=c.particles[t.to];if(r!==undefined&&q!==undefined){c.springs[s]=new Spring(r,q,p,i.stiffness);k.push(c.springs[s]);r.connections++;q.connections++;delete l.particles[t.fm];delete l.particles[t.to]}},dropSpring:function(s){var r=s.id;var q=c.springs[r];q.point1.connections--;q.point2.connections--;var p=$.inArray(q,k);if(p>-1){k.splice(p,1)}delete c.springs[r]},_update:function(p){d++;$.each(p,function(q,r){if(r.t in i){i[r.t](r)}});return d},tick:function(){i.tendParticles();i.eulerIntegrator(i.dt);i.tock()},tock:function(){var p=[];$.each(c.particles,function(r,q){p.push(r);p.push(q.p.x);p.push(q.p.y)});if(h){h({geometry:p,epoch:d,energy:b,bounds:g})}},tendParticles:function(){$.each(c.particles,function(q,p){if(p._m!==undefined){if(Math.abs(p.m-p._m)<1){p.m=p._m;delete p._m}else{p.m*=0.98}}p.v.x=p.v.y=0})},eulerIntegrator:function(p){if(i.repulsion>0){if(i.theta>0){i.applyBarnesHutRepulsion()}else{i.applyBruteForceRepulsion()}}if(i.stiffness>0){i.applySprings()}i.applyCenterDrift();if(i.gravity){i.applyCenterGravity()}i.updateVelocity(p);i.updatePosition(p)},applyBruteForceRepulsion:function(){$.each(c.particles,function(q,p){$.each(c.particles,function(s,r){if(p!==r){var u=p.p.subtract(r.p);var v=Math.max(1,u.magnitude());var t=((u.magnitude()>0)?u:Point.random(1)).normalize();p.applyForce(t.multiply(i.repulsion*(r._m||r.m)*0.5).divide(v*v*0.5));r.applyForce(t.multiply(i.repulsion*(p._m||p.m)*0.5).divide(v*v*-0.5))}})})},applyBarnesHutRepulsion:function(){if(!g.topleft||!g.bottomright){return}var q=new Point(g.bottomright);var p=new Point(g.topleft);f.init(p,q,i.theta);$.each(c.particles,function(s,r){f.insert(r)});$.each(c.particles,function(s,r){f.applyForces(r,i.repulsion)})},applySprings:function(){$.each(c.springs,function(t,p){var s=p.point2.p.subtract(p.point1.p);var q=p.length-s.magnitude();var r=((s.magnitude()>0)?s:Point.random(1)).normalize();p.point1.applyForce(r.multiply(p.k*q*-0.5));p.point2.applyForce(r.multiply(p.k*q*0.5))})},applyCenterDrift:function(){var q=0;var r=new Point(0,0);$.each(c.particles,function(t,s){r.add(s.p);q++});if(q==0){return}var p=r.divide(-q);$.each(c.particles,function(t,s){s.applyForce(p)})},applyCenterGravity:function(){$.each(c.particles,function(r,p){var q=p.p.multiply(-1);p.applyForce(q.multiply(i.repulsion/100))})},updateVelocity:function(p){$.each(c.particles,function(t,q){if(q.fixed){q.v=new Point(0,0);q.f=new Point(0,0);return}var s=q.v.magnitude();q.v=q.v.add(q.f.multiply(p)).multiply(1-i.friction);q.f.x=q.f.y=0;var r=q.v.magnitude();if(r>j){q.v=q.v.divide(r*r)}})},updatePosition:function(q){var r=0,p=0,u=0;var t=null;var s=null;$.each(c.particles,function(w,v){v.p=v.p.add(v.v.multiply(q));var x=v.v.magnitude();var z=x*x;r+=z;p=Math.max(z,p);u++;if(!t){t=new Point(v.p.x,v.p.y);s=new Point(v.p.x,v.p.y);return}var y=v.p;if(y.x===null||y.y===null){return}if(y.x>t.x){t.x=y.x}if(y.y>t.y){t.y=y.y}if(y.x1000){e.stop()}else{}}else{c=null}},tock:function(h){h.type="geometry";postMessage(h)},modifyNode:function(i,h){a.modifyNode(i,h);e.go()},modifyPhysics:function(h){a.modifyPhysics(h)},update:function(h){var i=a._update(h)}};return e};var physics=PhysicsWorker();onmessage=function(a){if(!a.data.type){postMessage("ÂżkĂ©rnèl?");return}if(a.data.type=="physics"){var b=a.data.physics;physics.init(a.data.physics);return}switch(a.data.type){case"modify":physics.modifyNode(a.data.id,a.data.mods);break;case"changes":physics.update(a.data.changes);physics.go();break;case"start":physics.go();break;case"stop":physics.stop();break;case"sys":var b=a.data.param||{};if(!isNaN(b.timeout)){physics.timeout(b.timeout)}physics.modifyPhysics(b);physics.go();break}}; - })() - - - arbor = (typeof(arbor)!=='undefined') ? arbor : {} - $.extend(arbor, { - // object constructors (don't use â€new’, just call them) - ParticleSystem:ParticleSystem, - Point:function(x, y){ return new Point(x, y) }, - - // immutable object with useful methods - etc:{ - trace:trace, // Ć’(msg) -> safe console logging - dirname:dirname, // Ć’(path) -> leading part of path - basename:basename, // Ć’(path) -> trailing part of path - ordinalize:ordinalize, // Ć’(num) -> abbrev integers (and add commas) - objcopy:objcopy, // Ć’(old) -> clone an object - objcmp:objcmp, // Ć’(a, b, strict_ordering) -> t/f comparison - objkeys:objkeys, // Ć’(obj) -> array of all keys in obj - objmerge:objmerge, // Ć’(dst, src) -> like $.extend but non-destructive - uniq:uniq, // Ć’(arr) -> array of unique items in arr - arbor_path:arbor_path, // Ć’() -> guess the directory of the lib code - } - }) - -})(this.jQuery) \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.js deleted file mode 100755 index cac3e78cb7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.js +++ /dev/null @@ -1,17710 +0,0 @@ - -/* cytoscape.js */ - -/** - * This file is part of cytoscape.js 2.1.0. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - - -// this is put as a global var in the browser -// or it's just a global to this module if commonjs -var cytoscape; - -(function(window){ "use strict"; - - // the object iteself is a function that init's an instance of cytoscape - var $$ = cytoscape = function(){ - return cytoscape.init.apply(cytoscape, arguments); - }; - - // allow functional access to cytoscape.js - // e.g. var cyto = $.cytoscape({ selector: "#foo", ... }); - // var nodes = cyto.nodes(); - $$.init = function( options ){ - - // if no options specified, use default - if( options === undefined ){ - options = {}; - } - - // create instance - if( $$.is.plainObject( options ) ){ - return new $$.Core( options ); - } - - // allow for registration of extensions - // e.g. $.cytoscape("renderer", "svg", SvgRenderer); - // e.g. $.cytoscape("renderer", "svg", "nodeshape", "ellipse", SvgEllipseNodeShape); - // e.g. $.cytoscape("core", "doSomething", function(){ /* doSomething code */ }); - // e.g. $.cytoscape("collection", "doSomething", function(){ /* doSomething code */ }); - else if( $$.is.string( options ) ) { - return $$.extension.apply($$.extension, arguments); - } - }; - - // define the function namespace here, since it has members in many places - $$.fn = {}; - - // TODO test that this works: - if( typeof exports !== 'undefined' ){ // expose as a commonjs module - exports = module.exports = cytoscape; - } - - // make sure we always register in the window just in case (e.g. w/ derbyjs) - if( window ){ - window.cytoscape = cytoscape; - } - -})( typeof window === 'undefined' ? null : window ); - -// type testing utility functions - -;(function($$, window){ "use strict"; - - $$.is = { - string: function(obj){ - return obj != null && typeof obj == typeof ""; - }, - - fn: function(obj){ - return obj != null && typeof obj === typeof function(){}; - }, - - array: function(obj){ - return obj != null && obj instanceof Array; - }, - - plainObject: function(obj){ - return obj != null && typeof obj === typeof {} && !$$.is.array(obj) && obj.constructor === Object; - }, - - number: function(obj){ - return obj != null && typeof obj === typeof 1 && !isNaN(obj); - }, - - integer: function( obj ){ - return $$.is.number(obj) && Math.floor(obj) === obj; - }, - - color: function(obj){ - return obj != null && typeof obj === typeof "" && $.Color(obj).toString() !== ""; - }, - - bool: function(obj){ - return obj != null && typeof obj === typeof true; - }, - - elementOrCollection: function(obj){ - return $$.is.element(obj) || $$.is.collection(obj); - }, - - element: function(obj){ - return obj instanceof $$.Element && obj._private.single; - }, - - collection: function(obj){ - return obj instanceof $$.Collection && !obj._private.single; - }, - - core: function(obj){ - return obj instanceof $$.Core; - }, - - style: function(obj){ - return obj instanceof $$.Style; - }, - - stylesheet: function(obj){ - return obj instanceof $$.Stylesheet; - }, - - event: function(obj){ - return obj instanceof $$.Event; - }, - - emptyString: function(obj){ - if( !obj ){ // null is empty - return true; - } else if( $$.is.string(obj) ){ - if( obj === "" || obj.match(/^\s+$/) ){ - return true; // empty string is empty - } - } - - return false; // otherwise, we don't know what we've got - }, - - nonemptyString: function(obj){ - if( obj && $$.is.string(obj) && obj !== "" && !obj.match(/^\s+$/) ){ - return true; - } - - return false; - }, - - domElement: function(obj){ - if( typeof HTMLElement === 'undefined' ){ - return false; // we're not in a browser so it doesn't matter - } else { - return obj instanceof HTMLElement; - } - - - }, - - touch: function(){ - return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ); - } - }; - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ "use strict"; - - // utility functions only for internal use - - $$.util = { - - // the jquery extend() function - // NB: modified to use $$.is etc since we can't use jquery functions - extend: function() { - var options, name, src, copy, copyIsArray, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !$$.is.fn(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( length === i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( $$.is.plainObject(copy) || (copyIsArray = $$.is.array(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && $$.is.array(src) ? src : []; - - } else { - clone = src && $$.is.plainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = $$.util.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; - }, - - error: function( msg ){ - if( console ){ - if( console.error ){ - console.error( msg ); - } else if( console.log ){ - console.log( msg ); - } else { - throw msg; - } - } else { - throw msg; - } - }, - - clone: function( obj ){ - var target = {}; - for (var i in obj) { - if ( obj.hasOwnProperty(i) ) { // TODO is this hasOwnProperty() call necessary for our use? - target[i] = obj[i]; - } - } - return target; - }, - - // gets a shallow copy of the argument - copy: function( obj ){ - if( obj == null ){ - return obj; - } if( $$.is.array(obj) ){ - return obj.slice(); - } else if( $$.is.plainObject(obj) ){ - return $$.util.clone( obj ); - } else { - return obj; - } - }, - - // has anything been set in the map - mapEmpty: function( map ){ - var empty = true; - - if( map != null ){ - for(var i in map){ - empty = false; - break; - } - } - - return empty; - }, - - // pushes to the array at the end of a map (map may not be built) - pushMap: function( options ){ - var array = $$.util.getMap(options); - - if( array == null ){ // if empty, put initial array - $$.util.setMap( $.extend({}, options, { - value: [ options.value ] - }) ); - } else { - array.push( options.value ); - } - }, - - // sets the value in a map (map may not be built) - setMap: function( options ){ - var obj = options.map; - var key; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to set map with object key"); - } - - if( i < keys.length - 1 ){ - - // extend the map if necessary - if( obj[key] == null ){ - obj[key] = {}; - } - - obj = obj[key]; - } else { - // set the value - obj[key] = options.value; - } - } - }, - - // gets the value in a map even if it's not built in places - getMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to get map with object key"); - } - - obj = obj[key]; - - if( obj == null ){ - return obj; - } - } - - return obj; - }, - - // deletes the entry in the map - deleteMap: function( options ){ - var obj = options.map; - var keys = options.keys; - var l = keys.length; - var keepChildren = options.keepChildren; - - for(var i = 0; i < l; i++){ - var key = keys[i]; - - if( $$.is.plainObject( key ) ){ - $$.util.error("Tried to delete map with object key"); - } - - var lastKey = i === options.keys.length - 1; - if( lastKey ){ - - if( keepChildren ){ // then only delete child fields not in keepChildren - for( var child in obj ){ - if( !keepChildren[child] ){ - delete obj[child]; - } - } - } else { - delete obj[key]; - } - - } else { - obj = obj[key]; - } - } - }, - - capitalize: function(str){ - if( $$.is.emptyString(str) ){ - return str; - } - - return str.charAt(0).toUpperCase() + str.substring(1); - }, - - camel2dash: function( str ){ - var ret = []; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var chLowerCase = ch.toLowerCase(); - var isUpperCase = ch !== chLowerCase; - - if( isUpperCase ){ - ret.push( "-" ); - ret.push( chLowerCase ); - } else { - ret.push( ch ); - } - } - - var noUpperCases = ret.length === str.length; - if( noUpperCases ){ return str } // cheaper than .join() - - return ret.join(""); - }, - - dash2camel: function( str ){ - var ret = []; - var nextIsUpper = false; - - for( var i = 0; i < str.length; i++ ){ - var ch = str[i]; - var isDash = ch === "-"; - - if( isDash ){ - nextIsUpper = true; - } else { - if( nextIsUpper ){ - ret.push( ch.toUpperCase() ); - } else { - ret.push( ch ); - } - - nextIsUpper = false; - } - } - - return ret.join(""); - }, - - // strip spaces from beginning of string and end of string - trim: function( str ){ - var first, last; - - // find first non-space char - for( first = 0; first < str.length && str[first] === " "; first++ ){} - - // find last non-space char - for( last = str.length - 1; last > first && str[last] === " "; last-- ){} - - return str.substring(first, last + 1); - }, - - // get [r, g, b] from #abc or #aabbcc - hex2tuple: function( hex ){ - if( !(hex.length === 4 || hex.length === 7) || hex[0] !== "#" ){ return; } - - var shortHex = hex.length === 4; - var r, g, b; - var base = 16; - - if( shortHex ){ - r = parseInt( hex[1] + hex[1], base ); - g = parseInt( hex[2] + hex[2], base ); - b = parseInt( hex[3] + hex[3], base ); - } else { - r = parseInt( hex[1] + hex[2], base ); - g = parseInt( hex[3] + hex[4], base ); - b = parseInt( hex[5] + hex[6], base ); - } - - return [r, g, b]; - }, - - // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0) - hsl2tuple: function( hsl ){ - var ret; - var number = $$.util.regex.number; - var h, s, l, a, r, g, b; - function hue2rgb(p, q, t){ - if(t < 0) t += 1; - if(t > 1) t -= 1; - if(t < 1/6) return p + (q - p) * 6 * t; - if(t < 1/2) return q; - if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; - return p; - } - - var m = new RegExp("^" + $$.util.regex.hsla + "$").exec(hsl); - if( m ){ - - // get hue - h = parseInt( m[1] ); - if( h < 0 ){ - h = ( 360 - (-1*h % 360) ) % 360; - } else if( h > 360 ){ - h = h % 360; - } - h /= 360; // normalise on [0, 1] - - s = parseFloat( m[2] ); - if( s < 0 || s > 100 ){ return; } // saturation is [0, 100] - s = s/100; // normalise on [0, 1] - - l = parseFloat( m[3] ); - if( l < 0 || l > 100 ){ return; } // lightness is [0, 100] - l = l/100; // normalise on [0, 1] - - a = m[4]; - if( a !== undefined ){ - a = parseFloat( a ); - - if( a < 0 || a > 1 ){ return; } // alpha is [0, 1] - } - - // now, convert to rgb - // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - if( s === 0 ){ - r = g = b = Math.round(l * 255); // achromatic - } else { - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = Math.round( 255 * hue2rgb(p, q, h + 1/3) ); - g = Math.round( 255 * hue2rgb(p, q, h) ); - b = Math.round( 255 * hue2rgb(p, q, h - 1/3) ); - } - - ret = [r, g, b, a]; - } - - return ret; - }, - - // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0) - rgb2tuple: function( rgb ){ - var ret; - var number = $$.util.regex.number; - - var m = new RegExp("^" + $$.util.regex.rgba + "$").exec(rgb); - if( m ){ - ret = []; - - var isPct = []; - for( var i = 1; i <= 3; i++ ){ - var channel = m[i]; - - if( channel[ channel.length - 1 ] === "%" ){ - isPct[i] = true; - } - channel = parseFloat( channel ); - - if( isPct[i] ){ - channel = channel/100 * 255; // normalise to [0, 255] - } - - if( channel < 0 || channel > 255 ){ return; } // invalid channel value - - ret.push( Math.floor(channel) ); - } - - var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3]; - var allArePct = isPct[1] && isPct[2] && isPct[3]; - if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is - - var alpha = m[4]; - if( alpha !== undefined ){ - alpha = parseFloat( alpha ); - - if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value - - ret.push( alpha ); - } - } - - return ret; - }, - - colorname2tuple: function( color ){ - return $$.util.colors[ color.toLowerCase() ]; - }, - - color2tuple: function( color ){ - return $$.util.colorname2tuple(color) - || $$.util.hex2tuple(color) - || $$.util.rgb2tuple(color) - || $$.util.hsl2tuple(color); - }, - - tuple2hex: function( tuple ){ - var r = tuple[0]; - var g = tuple[1]; - var b = tuple[2]; - - function ch2hex( ch ){ - var hex = ch.toString(16); - - if( hex.length === 1 ){ - hex = '0' + hex; - } - - return hex; - } - - return '#' + ch2hex(r) + ch2hex(g) + ch2hex(b); - }, - - colors: { - // special colour names - transparent: [0,0,0,0], // NB alpha === 0 - - // regular colours - aliceblue: [240,248,255], - antiquewhite: [250,235,215], - aqua: [0,255,255], - aquamarine: [127,255,212], - azure: [240,255,255], - beige: [245,245,220], - bisque: [255,228,196], - black: [0,0,0], - blanchedalmond: [255,235,205], - blue: [0,0,255], - blueviolet: [138,43,226], - brown: [165,42,42], - burlywood: [222,184,135], - cadetblue: [95,158,160], - chartreuse: [127,255,0], - chocolate: [210,105,30], - coral: [255,127,80], - cornflowerblue: [100,149,237], - cornsilk: [255,248,220], - crimson: [220,20,60], - cyan: [0,255,255], - darkblue: [0,0,139], - darkcyan: [0,139,139], - darkgoldenrod: [184,134,11], - darkgray: [169,169,169], - darkgreen: [0,100,0], - darkgrey: [169,169,169], - darkkhaki: [189,183,107], - darkmagenta: [139,0,139], - darkolivegreen: [85,107,47], - darkorange: [255,140,0], - darkorchid: [153,50,204], - darkred: [139,0,0], - darksalmon: [233,150,122], - darkseagreen: [143,188,143], - darkslateblue: [72,61,139], - darkslategray: [47,79,79], - darkslategrey: [47,79,79], - darkturquoise: [0,206,209], - darkviolet: [148,0,211], - deeppink: [255,20,147], - deepskyblue: [0,191,255], - dimgray: [105,105,105], - dimgrey: [105,105,105], - dodgerblue: [30,144,255], - firebrick: [178,34,34], - floralwhite: [255,250,240], - forestgreen: [34,139,34], - fuchsia: [255,0,255], - gainsboro: [220,220,220], - ghostwhite: [248,248,255], - gold: [255,215,0], - goldenrod: [218,165,32], - gray: [128,128,128], - grey: [128,128,128], - green: [0,128,0], - greenyellow: [173,255,47], - honeydew: [240,255,240], - hotpink: [255,105,180], - indianred: [205,92,92], - indigo: [75,0,130], - ivory: [255,255,240], - khaki: [240,230,140], - lavender: [230,230,250], - lavenderblush: [255,240,245], - lawngreen: [124,252,0], - lemonchiffon: [255,250,205], - lightblue: [173,216,230], - lightcoral: [240,128,128], - lightcyan: [224,255,255], - lightgoldenrodyellow: [250,250,210], - lightgray: [211,211,211], - lightgreen: [144,238,144], - lightgrey: [211,211,211], - lightpink: [255,182,193], - lightsalmon: [255,160,122], - lightseagreen: [32,178,170], - lightskyblue: [135,206,250], - lightslategray: [119,136,153], - lightslategrey: [119,136,153], - lightsteelblue: [176,196,222], - lightyellow: [255,255,224], - lime: [0,255,0], - limegreen: [50,205,50], - linen: [250,240,230], - magenta: [255,0,255], - maroon: [128,0,0], - mediumaquamarine: [102,205,170], - mediumblue: [0,0,205], - mediumorchid: [186,85,211], - mediumpurple: [147,112,219], - mediumseagreen: [60,179,113], - mediumslateblue: [123,104,238], - mediumspringgreen: [0,250,154], - mediumturquoise: [72,209,204], - mediumvioletred: [199,21,133], - midnightblue: [25,25,112], - mintcream: [245,255,250], - mistyrose: [255,228,225], - moccasin: [255,228,181], - navajowhite: [255,222,173], - navy: [0,0,128], - oldlace: [253,245,230], - olive: [128,128,0], - olivedrab: [107,142,35], - orange: [255,165,0], - orangered: [255,69,0], - orchid: [218,112,214], - palegoldenrod: [238,232,170], - palegreen: [152,251,152], - paleturquoise: [175,238,238], - palevioletred: [219,112,147], - papayawhip: [255,239,213], - peachpuff: [255,218,185], - peru: [205,133,63], - pink: [255,192,203], - plum: [221,160,221], - powderblue: [176,224,230], - purple: [128,0,128], - red: [255,0,0], - rosybrown: [188,143,143], - royalblue: [65,105,225], - saddlebrown: [139,69,19], - salmon: [250,128,114], - sandybrown: [244,164,96], - seagreen: [46,139,87], - seashell: [255,245,238], - sienna: [160,82,45], - silver: [192,192,192], - skyblue: [135,206,235], - slateblue: [106,90,205], - slategray: [112,128,144], - slategrey: [112,128,144], - snow: [255,250,250], - springgreen: [0,255,127], - steelblue: [70,130,180], - tan: [210,180,140], - teal: [0,128,128], - thistle: [216,191,216], - tomato: [255,99,71], - turquoise: [64,224,208], - violet: [238,130,238], - wheat: [245,222,179], - white: [255,255,255], - whitesmoke: [245,245,245], - yellow: [255,255,0], - yellowgreen: [154,205,50] - } - - }; - - $$.util.regex = {}; - - $$.util.regex.number = "(?:[-]?\\d*\\.\\d+|[-]?\\d+|[-]?\\d*\\.\\d+[eE]\\d+)"; - - $$.util.regex.rgba = "rgb[a]?\\(("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)\\s*,\\s*("+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.rgbaNoBackRefs = "rgb[a]?\\((?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)\\s*,\\s*(?:"+ $$.util.regex.number +"[%]?)(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hsla = "hsl[a]?\\(("+ $$.util.regex.number +")\\s*,\\s*("+ $$.util.regex.number +"[%])\\s*,\\s*("+ $$.util.regex.number +"[%])(?:\\s*,\\s*("+ $$.util.regex.number +"))?\\)"; - $$.util.regex.hslaNoBackRefs = "hsl[a]?\\((?:"+ $$.util.regex.number +")\\s*,\\s*(?:"+ $$.util.regex.number +"[%])\\s*,\\s*(?:"+ $$.util.regex.number +"[%])(?:\\s*,\\s*(?:"+ $$.util.regex.number +"))?\\)"; - - $$.util.regex.hex3 = "\\#[0-9a-fA-F]{3}"; - $$.util.regex.hex6 = "\\#[0-9a-fA-F]{6}"; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.math = {}; - - $$.math.signum = function(x){ - if( x > 0 ){ - return 1; - } else if( x < 0 ){ - return -1; - } else { - return 0; - } - }; - - $$.math.distance = function( p1, p2 ){ - var dx = p2.x - p1.x; - var dy = p2.y - p1.y; - - return Math.sqrt( dx*dx + dy*dy ); - }; - - // from http://en.wikipedia.org/wiki/BĂ©zier_curve#Quadratic_curves - $$.math.qbezierAt = function(p0, p1, p2, t){ - return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2; - } - - $$.math.qbezierPtAt = function(p0, p1, p2, t){ - return { - x: $$.math.qbezierAt( p0.x, p1.x, p2.x, t ), - y: $$.math.qbezierAt( p0.y, p1.y, p2.y, t ) - }; - } - - $$.math.roundRectangleIntersectLine = function( - x, y, nodeX, nodeY, width, height, padding) { - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var halfWidth = width / 2; - var halfHeight = height / 2; - - // Check intersections with straight line segments - var straightLineIntersections; - - // Top segment, left to right - { - var topStartX = nodeX - halfWidth + cornerRadius - padding; - var topStartY = nodeY - halfHeight - padding; - var topEndX = nodeX + halfWidth - cornerRadius + padding; - var topEndY = topStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Right segment, top to bottom - { - var rightStartX = nodeX + halfWidth + padding; - var rightStartY = nodeY - halfHeight + cornerRadius - padding; - var rightEndX = rightStartX; - var rightEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Bottom segment, left to right - { - var bottomStartX = nodeX - halfWidth + cornerRadius - padding; - var bottomStartY = nodeY + halfHeight + padding; - var bottomEndX = nodeX + halfWidth - cornerRadius + padding; - var bottomEndY = bottomStartY; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Left segment, top to bottom - { - var leftStartX = nodeX - halfWidth - padding; - var leftStartY = nodeY - halfHeight + cornerRadius - padding; - var leftEndX = leftStartX; - var leftEndY = nodeY + halfHeight - cornerRadius + padding; - - straightLineIntersections = this.finiteLinesIntersect( - x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false); - - if (straightLineIntersections.length > 0) { - return straightLineIntersections; - } - } - - // Check intersections with arc segments - var arcIntersections; - - // Top Left - { - var topLeftCenterX = nodeX - halfWidth + cornerRadius; - var topLeftCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topLeftCenterX, topLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= topLeftCenterX - && arcIntersections[1] <= topLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Top Right - { - var topRightCenterX = nodeX + halfWidth - cornerRadius; - var topRightCenterY = nodeY - halfHeight + cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - topRightCenterX, topRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= topRightCenterX - && arcIntersections[1] <= topRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Right - { - var bottomRightCenterX = nodeX + halfWidth - cornerRadius; - var bottomRightCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomRightCenterX, bottomRightCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] >= bottomRightCenterX - && arcIntersections[1] >= bottomRightCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - // Bottom Left - { - var bottomLeftCenterX = nodeX - halfWidth + cornerRadius; - var bottomLeftCenterY = nodeY + halfHeight - cornerRadius - arcIntersections = this.intersectLineCircle( - x, y, nodeX, nodeY, - bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding); - - // Ensure the intersection is on the desired quarter of the circle - if (arcIntersections.length > 0 - && arcIntersections[0] <= bottomLeftCenterX - && arcIntersections[1] >= bottomLeftCenterY) { - return [arcIntersections[0], arcIntersections[1]]; - } - } - - return []; // if nothing - }; - - $$.math.roundRectangleIntersectBox = function( - boxX1, boxY1, boxX2, boxY2, width, height, centerX, centerY, padding) { - - // We have the following shpae - - // _____ - // _| |_ - // | | - // |_ _| - // |_____| - // - // With a quarter circle at each corner. - - var cornerRadius = this.getRoundRectangleRadius(width, height); - - var hBoxTopLeftX = centerX - width / 2 - padding; - var hBoxTopLeftY = centerY - height / 2 + cornerRadius - padding; - var hBoxBottomRightX = centerX + width / 2 + padding; - var hBoxBottomRightY = centerY + height / 2 - cornerRadius + padding; - - var vBoxTopLeftX = centerX - width / 2 + cornerRadius - padding; - var vBoxTopLeftY = centerY - height / 2 - padding; - var vBoxBottomRightX = centerX + width / 2 - cornerRadius + padding; - var vBoxBottomRightY = centerY + height / 2 + padding; - - // Check if the box is out of bounds - var boxMinX = Math.min(boxX1, boxX2); - var boxMaxX = Math.max(boxX1, boxX2); - var boxMinY = Math.min(boxY1, boxY2); - var boxMaxY = Math.max(boxY1, boxY2); - - if (boxMaxX < hBoxTopLeftX) { - return false; - } else if (boxMinX > hBoxBottomRightX) { - return false; - } - - if (boxMaxY < vBoxTopLeftY) { - return false; - } else if (boxMinY > vBoxBottomRightY) { - return false; - } - - // Check if an hBox point is in given box - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxTopLeftY >= boxMinY && hBoxTopLeftY <= boxMaxY) { - return true; - } - - if (hBoxBottomRightX >= boxMinX && hBoxBottomRightX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - if (hBoxTopLeftX >= boxMinX && hBoxTopLeftX <= boxMaxX - && hBoxBottomRightY >= boxMinY && hBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the hBox - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMinY >= hBoxTopLeftY && boxMinY <= hBoxBottomRightY) { - return true; - } - - if (boxMaxX >= hBoxTopLeftX && boxMaxX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - if (boxMinX >= hBoxTopLeftX && boxMinX <= hBoxBottomRightX - && boxMaxY >= hBoxTopLeftY && boxMaxY <= hBoxBottomRightY) { - return true; - } - - // Check if an vBox point is in given box - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxTopLeftY >= boxMinY && vBoxTopLeftY <= boxMaxY) { - return true; - } - - if (vBoxBottomRightX >= boxMinX && vBoxBottomRightX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - if (vBoxTopLeftX >= boxMinX && vBoxTopLeftX <= boxMaxX - && vBoxBottomRightY >= boxMinY && vBoxBottomRightY <= boxMaxY) { - return true; - } - - // Check if a given point box is in the vBox - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMinY >= vBoxTopLeftY && boxMinY <= vBoxBottomRightY) { - return true; - } - - if (boxMaxX >= vBoxTopLeftX && boxMaxX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - if (boxMinX >= vBoxTopLeftX && boxMinX <= vBoxBottomRightX - && boxMaxY >= vBoxTopLeftY && boxMaxY <= vBoxBottomRightY) { - return true; - } - - // Lastly, check if one of the ellipses coincide with the box - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxTopLeftY + padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxBottomRightX - padding, hBoxBottomRightY - padding)) { - return true; - } - - if (this.boxIntersectEllipse(boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxBottomRightY - padding)) { - return true; - } - - return false; - }; - - // @O Approximate collision functions - $$.math.checkInBoundingCircle = function( - x, y, farthestPointSqDistance, padding, width, height, centerX, centerY) { - - x = (x - centerX) / (width + padding); - y = (y - centerY) / (height + padding); - - return (x * x + y * y) <= farthestPointSqDistance; - }; - - $$.math.checkInBoundingBox = function( - x, y, points, padding, width, height, centerX, centerY) { - - // Assumes width, height >= 0, points.length > 0 - - var minX = points[0], minY = points[1]; - var maxX = points[0], maxY = points[1]; - - for (var i = 1; i < points.length / 2; i++) { - - if (points[i * 2] < minX) { - minX = points[i * 2]; - } else if (points[i * 2] > maxX) { - maxX = points[i * 2]; - } - - if (points[i * 2 + 1] < minY) { - minY = points[i * 2 + 1]; - } else if (points[i * 2 + 1] > maxY) { - maxY = points[i * 2 + 1]; - } - } - - x -= centerX; - y -= centerY; - - x /= width; - y /= height; - - if (x < minX) { - return false; - } else if (x > maxX) { - return false; - } - - if (y < minY) { - return false; - } else if (y > maxY) { - return false; - } - - return true; - }; - - $$.math.boxInBezierVicinity = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - // Return values: - // 0 - curve is not in box - // 1 - curve may be in box; needs precise check - // 2 - curve is in box - - // midpoint - var midX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var midY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { // (x1, y1) in box - return 1; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { // (x3, y3) in box - return 1; - } else if (midX >= boxMinX && midX <= boxMaxX && midY >= boxMinY && midY <= boxMaxY) { // (midX, midY) in box - return 1; - } else if (x2 >= boxMinX && x2 <= boxMaxX && y2 >= boxMinY && y2 <= boxMaxY) { // ctrl pt in box - return 1; - } - - var curveMinX = Math.min(x1, midX, x3); - var curveMinY = Math.min(y1, midY, y3); - var curveMaxX = Math.max(x1, midX, x3); - var curveMaxY = Math.max(y1, midY, y3); - - /* - console.log(curveMinX + ", " + curveMinY + ", " + curveMaxX - + ", " + curveMaxY); - if (curveMinX == undefined) { - console.log("undefined curveMinX: " + x1 + ", " + x2 + ", " + x3); - } - */ - - if (curveMinX > boxMaxX - || curveMaxX < boxMinX - || curveMinY > boxMaxY - || curveMaxY < boxMinY) { - - return 0; - } - - return 1; - }; - - $$.math.checkBezierInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - function sampleInBox(t){ - var x = $$.math.qbezierAt(x1, x2, x3, t); - var y = $$.math.qbezierAt(y1, y2, y3, t); - - return x1box <= x && x <= x2box - && y1box <= y && y <= y2box - ; - } - - for( var t = 0; t <= 1; t += 0.25 ){ - if( !sampleInBox(t) ){ - return false; - } - } - - return true; - }; - - $$.math.checkStraightEdgeInBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - return x1box <= x1 && x1 <= x2box - && x1box <= x2 && x2 <= x2box - && y1box <= y1 && y1 <= y2box - && y1box <= y2 && y2 <= y2box - ; - }; - - $$.math.checkStraightEdgeCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, tolerance) { - - //console.log(arguments); - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - // Check left + right bounds - var aX = x2 - x1; - var bX = x1; - var yValue; - - // Top and bottom - var aY = y2 - y1; - var bY = y1; - var xValue; - - if (Math.abs(aX) < 0.0001) { - return (x1 >= boxMinX && x1 <= boxMaxX - && Math.min(y1, y2) <= boxMinY - && Math.max(y1, y2) >= boxMaxY); - } - - var tLeft = (boxMinX - bX) / aX; - if (tLeft > 0 && tLeft <= 1) { - yValue = aY * tLeft + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tRight = (boxMaxX - bX) / aX; - if (tRight > 0 && tRight <= 1) { - yValue = aY * tRight + bY; - if (yValue >= boxMinY && yValue <= boxMaxY) { - return true; - } - } - - var tTop = (boxMinY - bY) / aY; - if (tTop > 0 && tTop <= 1) { - xValue = aX * tTop + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - var tBottom = (boxMaxY - bY) / aY; - if (tBottom > 0 && tBottom <= 1) { - xValue = aX * tBottom + bX; - if (xValue >= boxMinX && xValue <= boxMaxX) { - return true; - } - } - - return false; - }; - - $$.math.checkBezierCrossesBox = function( - x1box, y1box, x2box, y2box, x1, y1, x2, y2, x3, y3, tolerance) { - - var boxMinX = Math.min(x1box, x2box) - tolerance; - var boxMinY = Math.min(y1box, y2box) - tolerance; - var boxMaxX = Math.max(x1box, x2box) + tolerance; - var boxMaxY = Math.max(y1box, y2box) + tolerance; - - if (x1 >= boxMinX && x1 <= boxMaxX && y1 >= boxMinY && y1 <= boxMaxY) { - return true; - } else if (x3 >= boxMinX && x3 <= boxMaxX && y3 >= boxMinY && y3 <= boxMaxY) { - return true; - } - - var aX = x1 - 2 * x2 + x3; - var bX = -2 * x1 + 2 * x2; - var cX = x1; - - var xIntervals = []; - - if (Math.abs(aX) < 0.0001) { - var leftParam = (boxMinX - x1) / bX; - var rightParam = (boxMaxX - x1) / bX; - - xIntervals.push(leftParam, rightParam); - } else { - // Find when x coordinate of the curve crosses the left side of the box - var discriminantX1 = bX * bX - 4 * aX * (cX - boxMinX); - var tX1, tX2; - if (discriminantX1 > 0) { - var sqrt = Math.sqrt(discriminantX1); - tX1 = (-bX + sqrt) / (2 * aX); - tX2 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX1, tX2); - } - - var discriminantX2 = bX * bX - 4 * aX * (cX - boxMaxX); - var tX3, tX4; - if (discriminantX2 > 0) { - var sqrt = Math.sqrt(discriminantX2); - tX3 = (-bX + sqrt) / (2 * aX); - tX4 = (-bX - sqrt) / (2 * aX); - - xIntervals.push(tX3, tX4); - } - } - - xIntervals.sort(function(a, b) { return a - b; }); - - var aY = y1 - 2 * y2 + y3; - var bY = -2 * y1 + 2 * y2; - var cY = y1; - - var yIntervals = []; - - if (Math.abs(aY) < 0.0001) { - var topParam = (boxMinY - y1) / bY; - var bottomParam = (boxMaxY - y1) / bY; - - yIntervals.push(topParam, bottomParam); - } else { - var discriminantY1 = bY * bY - 4 * aY * (cY - boxMinY); - - var tY1, tY2; - if (discriminantY1 > 0) { - var sqrt = Math.sqrt(discriminantY1); - tY1 = (-bY + sqrt) / (2 * aY); - tY2 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY1, tY2); - } - - var discriminantY2 = bY * bY - 4 * aY * (cY - boxMaxY); - - var tY3, tY4; - if (discriminantY2 > 0) { - var sqrt = Math.sqrt(discriminantY2); - tY3 = (-bY + sqrt) / (2 * aY); - tY4 = (-bY - sqrt) / (2 * aY); - - yIntervals.push(tY3, tY4); - } - } - - yIntervals.sort(function(a, b) { return a - b; }); - - for (var index = 0; index < xIntervals.length; index += 2) { - for (var yIndex = 1; yIndex < yIntervals.length; yIndex += 2) { - - // Check if there exists values for the Bezier curve - // parameter between 0 and 1 where both the curve's - // x and y coordinates are within the bounds specified by the box - if (xIntervals[index] < yIntervals[yIndex] - && yIntervals[yIndex] >= 0.0 - && xIntervals[index] <= 1.0 - && xIntervals[index + 1] > yIntervals[yIndex - 1] - && yIntervals[yIndex - 1] <= 1.0 - && xIntervals[index + 1] >= 0.0) { - - return true; - } - } - } - - return false; - }; - - $$.math.inLineVicinity = function(x, y, lx1, ly1, lx2, ly2, tolerance){ - var t = tolerance; - - var x1 = Math.min(lx1, lx2); - var x2 = Math.max(lx1, lx2); - var y1 = Math.min(ly1, ly2); - var y2 = Math.max(ly1, ly2); - - return x1 - t <= x && x <= x2 + t - && y1 - t <= y && y <= y2 + t; - }; - - $$.math.inBezierVicinity = function( - x, y, x1, y1, x2, y2, x3, y3, toleranceSquared) { - - // unfortunately yue's function makes several assumptions about the beziers - // and is not generic enough to be used properly - // a rough bounding box of the bezier curve - var bb = { - x1: Math.min( x1, x3, x2 ), - x2: Math.max( x1, x3, x2 ), - y1: Math.min( y1, y3, y2 ), - y2: Math.max( y1, y3, y2 ) - }; - - // if outside the rough bounding box for the bezier, then it can't be a hit - if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){ - // console.log('bezier out of rough bb') - return false; - } else { - // console.log('do more expensive check'); - return true; - } - - /// END STOP USING YUE'S IMPL - - // Middle point occurs when t = 0.5, this is when the Bezier - // is closest to (x2, y2) - var middlePointX = 0.25 * x1 + 0.5 * x2 + 0.25 * x3; - var middlePointY = 0.25 * y1 + 0.5 * y2 + 0.25 * y3; - - // a rough bounding box of the bezier curve - var bb = { - x1: Math.min( x1, x3, middlePointX ), - x2: Math.max( x1, x3, middlePointX ), - y1: Math.min( y1, y3, middlePointY ), - y2: Math.max( y1, y3, middlePointY ) - }; - - // if outside the rough bounding box for the bezier, then it can't be a hit - if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){ - // console.log('bezier out of rough bb') - return false; - } else { - // console.log('do more expensive check'); - return true; - } - - var displacementX, displacementY, offsetX, offsetY; - var dotProduct, dotSquared, hypSquared; - var outside = function(x, y, startX, startY, endX, endY, - toleranceSquared, counterClockwise) { - - dotProduct = (endY - startY) * (x - startX) + (startX - endX) * (y - startY); - dotSquared = dotProduct * dotProduct; - sideSquared = (endY - startY) * (endY - startY) - + (startX - endX) * (startX - endX); - - if (counterClockwise) { - if (dotProduct > 0) { - return false; - } - } else { - if (dotProduct < 0) { - return false; - } - } - - return (dotSquared / sideSquared > toleranceSquared); - }; - - // Used to check if the test polygon winding is clockwise or counterclockwise - var testPointX = (middlePointX + x2) / 2.0; - var testPointY = (middlePointY + y2) / 2.0; - - var counterClockwise = true; - - // The test point is always inside - if (outside(testPointX, testPointY, x1, y1, x2, y2, 0, counterClockwise)) { - counterClockwise = !counterClockwise; - } - - /* - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, middlePointX, middlePointY, toleranceSquared, - counterClockwise) - && !outside(x, y, middlePointX, middlePointY, x1, y1, toleranceSquared, - counterClockwise) - ); - */ - - return (!outside(x, y, x1, y1, x2, y2, toleranceSquared, counterClockwise) - && !outside(x, y, x2, y2, x3, y3, toleranceSquared, counterClockwise) - && !outside(x, y, x3, y3, x1, y1, toleranceSquared, - counterClockwise) - ); - }; - - $$.math.solveCubic = function(a, b, c, d, result) { - - // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where - // r is the real component, i is the imaginary component - - // An implementation of the Cardano method from the year 1545 - // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots - - b /= a; - c /= a; - d /= a; - - var discriminant, q, r, dum1, s, t, term1, r13; - - q = (3.0 * c - (b * b)) / 9.0; - r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b)); - r /= 54.0; - - discriminant = q * q * q + r * r; - result[1] = 0; - term1 = (b / 3.0); - - if (discriminant > 0) { - s = r + Math.sqrt(discriminant); - s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0))); - t = r - Math.sqrt(discriminant); - t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0))); - result[0] = -term1 + s + t; - term1 += (s + t) / 2.0; - result[4] = result[2] = -term1; - term1 = Math.sqrt(3.0) * (-t + s) / 2; - result[3] = term1; - result[5] = -term1; - return; - } - - result[5] = result[3] = 0; - - if (discriminant == 0) { - r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0))); - result[0] = -term1 + 2.0 * r13; - result[4] = result[2] = -(r13 + term1); - return; - } - - q = -q; - dum1 = q * q * q; - dum1 = Math.acos(r / Math.sqrt(dum1)); - r13 = 2.0 * Math.sqrt(q); - result[0] = -term1 + r13 * Math.cos(dum1 / 3.0); - result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0); - result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0); - - return; - }; - - $$.math.sqDistanceToQuadraticBezier = function( - x, y, x1, y1, x2, y2, x3, y3) { - - // Find minimum distance by using the minimum of the distance - // function between the given point and the curve - - // This gives the coefficients of the resulting cubic equation - // whose roots tell us where a possible minimum is - // (Coefficients are divided by 4) - - var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3 - + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3; - - var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3 - + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3; - - var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x - + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y; - - var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x - + y1*y2 - y1*y1 + y1*y - y2*y; - - // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a); - - var roots = []; - - // Use the cubic solving algorithm - this.solveCubic(a, b, c, d, roots); - - var zeroThreshold = 0.0000001; - - var params = []; - - for (var index = 0; index < 6; index += 2) { - if (Math.abs(roots[index + 1]) < zeroThreshold - && roots[index] >= 0 - && roots[index] <= 1.0) { - params.push(roots[index]); - } - } - - params.push(1.0); - params.push(0.0); - - var minDistanceSquared = -1; - var closestParam; - - var curX, curY, distSquared; - for (var i = 0; i < params.length; i++) { - curX = Math.pow(1.0 - params[i], 2.0) * x1 - + 2.0 * (1 - params[i]) * params[i] * x2 - + params[i] * params[i] * x3; - - curY = Math.pow(1 - params[i], 2.0) * y1 - + 2 * (1.0 - params[i]) * params[i] * y2 - + params[i] * params[i] * y3; - - distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2); - // debug("distance for param " + params[i] + ": " + Math.sqrt(distSquared)); - if (minDistanceSquared >= 0) { - if (distSquared < minDistanceSquared) { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } else { - minDistanceSquared = distSquared; - closestParam = params[i]; - } - } - - /* - debugStats.clickX = x; - debugStats.clickY = y; - - debugStats.closestX = Math.pow(1.0 - closestParam, 2.0) * x1 - + 2.0 * (1.0 - closestParam) * closestParam * x2 - + closestParam * closestParam * x3; - - debugStats.closestY = Math.pow(1.0 - closestParam, 2.0) * y1 - + 2.0 * (1.0 - closestParam) * closestParam * y2 - + closestParam * closestParam * y3; - */ - - // debug("given: " - // + "( " + x + ", " + y + "), " - // + "( " + x1 + ", " + y1 + "), " - // + "( " + x2 + ", " + y2 + "), " - // + "( " + x3 + ", " + y3 + ")"); - - - // debug("roots: " + roots); - // debug("params: " + params); - // debug("closest param: " + closestParam); - return minDistanceSquared; - }; - - $$.math.sqDistanceToFiniteLine = function(x, y, x1, y1, x2, y2) { - var offset = [x - x1, y - y1]; - var line = [x2 - x1, y2 - y1]; - - var lineSq = line[0] * line[0] + line[1] * line[1]; - var hypSq = offset[0] * offset[0] + offset[1] * offset[1]; - - var dotProduct = offset[0] * line[0] + offset[1] * line[1]; - var adjSq = dotProduct * dotProduct / lineSq; - - if (dotProduct < 0) { - return hypSq; - } - - if (adjSq > lineSq) { - return (x - x2) * (x - x2) + (y - y2) * (y - y2); - } - - return (hypSq - adjSq) - }; - - $$.math.pointInsidePolygon = function( - x, y, basePoints, centerX, centerY, width, height, direction, padding) { - - //var direction = arguments[6]; - var transformedPoints = new Array(basePoints.length) - - // Gives negative angle - var angle = Math.asin(direction[1] / (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - if (direction[0] < 0) { - angle = angle + Math.PI / 2; - } else { - angle = -angle - Math.PI / 2; - } - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - -// console.log("base: " + basePoints); - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = - width / 2 * (basePoints[i * 2] * cos - - basePoints[i * 2 + 1] * sin); - - transformedPoints[i * 2 + 1] = - height / 2 * (basePoints[i * 2 + 1] * cos - + basePoints[i * 2] * sin); - - transformedPoints[i * 2] += centerX; - transformedPoints[i * 2 + 1] += centerY; - } - - var points; - - if (padding > 0) { - var expandedLineSet = this.expandPolygon( - transformedPoints, - -padding); - - points = this.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - var x1, y1, x2, y2; - var y3; - - // Intersect with vertical line through (x, y) - var up = 0; - var down = 0; - for (var i = 0; i < points.length / 2; i++) { - - x1 = points[i * 2]; - y1 = points[i * 2 + 1]; - - if (i + 1 < points.length / 2) { - x2 = points[(i + 1) * 2]; - y2 = points[(i + 1) * 2 + 1]; - } else { - x2 = points[(i + 1 - points.length / 2) * 2]; - y2 = points[(i + 1 - points.length / 2) * 2 + 1]; - } - -//* console.log("line from (" + x1 + ", " + y1 + ") to (" + x2 + ", " + y2 + ")"); - -//& console.log(x1, x, x2); - - if (x1 == x && x2 == x) { - - } else if ((x1 >= x && x >= x2) - || (x1 <= x && x <= x2)) { - - y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1; - - if (y3 > y) { - up++; - } - - if (y3 < y) { - down++; - } - -//* console.log(y3, y); - - } else { -//* console.log("22"); - continue; - } - - } - -//* console.log("up: " + up + ", down: " + down); - - if (up % 2 == 0) { - return false; - } else { - return true; - } - }; - - $$.math.joinLines = function(lineSet) { - - var vertices = new Array(lineSet.length / 2); - - var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY; - var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY; - - for (var i = 0; i < lineSet.length / 4; i++) { - currentLineStartX = lineSet[i * 4]; - currentLineStartY = lineSet[i * 4 + 1]; - currentLineEndX = lineSet[i * 4 + 2]; - currentLineEndY = lineSet[i * 4 + 3]; - - if (i < lineSet.length / 4 - 1) { - nextLineStartX = lineSet[(i + 1) * 4]; - nextLineStartY = lineSet[(i + 1) * 4 + 1]; - nextLineEndX = lineSet[(i + 1) * 4 + 2]; - nextLineEndY = lineSet[(i + 1) * 4 + 3]; - } else { - nextLineStartX = lineSet[0]; - nextLineStartY = lineSet[1]; - nextLineEndX = lineSet[2]; - nextLineEndY = lineSet[3]; - } - - var intersection = this.finiteLinesIntersect( - currentLineStartX, currentLineStartY, - currentLineEndX, currentLineEndY, - nextLineStartX, nextLineStartY, - nextLineEndX, nextLineEndY, - true); - - vertices[i * 2] = intersection[0]; - vertices[i * 2 + 1] = intersection[1]; - } - - return vertices; - }; - - $$.math.expandPolygon = function(points, pad) { - - var expandedLineSet = new Array(points.length * 2); - - var currentPointX, currentPointY, nextPointX, nextPointY; - - for (var i = 0; i < points.length / 2; i++) { - currentPointX = points[i * 2]; - currentPointY = points[i * 2 + 1]; - - if (i < points.length / 2 - 1) { - nextPointX = points[(i + 1) * 2]; - nextPointY = points[(i + 1) * 2 + 1]; - } else { - nextPointX = points[0]; - nextPointY = points[1]; - } - - // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY] - - // Assume CCW polygon winding - - var offsetX = (nextPointY - currentPointY); - var offsetY = -(nextPointX - currentPointX); - - // Normalize - var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY); - var normalizedOffsetX = offsetX / offsetLength; - var normalizedOffsetY = offsetY / offsetLength; - - expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad; - expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad; - expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad; - expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad; - } - - return expandedLineSet; - }; - - $$.math.intersectLineEllipse = function( - x, y, centerX, centerY, ellipseWradius, ellipseHradius) { - - var dispX = centerX - x; - var dispY = centerY - y; - - dispX /= ellipseWradius; - dispY /= ellipseHradius; - - var len = Math.sqrt(dispX * dispX + dispY * dispY); - - var newLength = len - 1; - - if (newLength < 0) { - return []; - } - - var lenProportion = newLength / len; - - return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y]; - }; - - $$.math.dotProduct = function( - vec1, vec2) { - - if (vec1.length != 2 || vec2.length != 2) { - throw 'dot product: arguments are not vectors'; - } - - return (vec1[0] * vec2[0] + vec1[1] * vec2[1]); - }; - - // Returns intersections of increasing distance from line's start point - $$.math.intersectLineCircle = function( - x1, y1, x2, y2, centerX, centerY, radius) { - - // Calculate d, direction vector of line - var d = [x2 - x1, y2 - y1]; // Direction vector of line - var s = [x1, y1]; // Start of line - var c = [centerX, centerY]; // Center of circle - var f = [x1 - centerX, y1 - centerY] - - var a = d[0] * d[0] + d[1] * d[1]; - var b = 2 * (f[0] * d[0] + f[1] * d[1]); - var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ; - - /* - var a = this.dotProduct(d, d); - var b = 2 * this.dotProduct(s, d) - this.dotProduct(d, c); - var c = this.dotProduct(s, s) - 2 * this.dotProduct(s, c) + this.dotProduct(c, c) - radius * radius ; - */ - - var discriminant = b*b-4*a*c; - - if (discriminant < 0) { - return []; - } - - var t1 = (-b + Math.sqrt(discriminant)) / (2 * a); - var t2 = (-b - Math.sqrt(discriminant)) / (2 * a); - - var tMin = Math.min(t1, t2); - var tMax = Math.max(t1, t2); - var inRangeParams = []; - - if (tMin >= 0 && tMin <= 1) { - inRangeParams.push(tMin); - } - - if (tMax >= 0 && tMax <= 1) { - inRangeParams.push(tMax); - } - - if (inRangeParams.length == 0) { - return []; - } - - var nearIntersectionX = inRangeParams[0] * d[0] + x1; - var nearIntersectionY = inRangeParams[0] * d[1] + y1; - - if (inRangeParams.length > 1) { - - if (inRangeParams[0] == inRangeParams[1]) { - return [nearIntersectionX, nearIntersectionY]; - } else { - - var farIntersectionX = inRangeParams[1] * d[0] + x1; - var farIntersectionY = inRangeParams[1] * d[1] + y1; - - return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY]; - } - - } else { - return [nearIntersectionX, nearIntersectionY] - } - - }; - - $$.math.findCircleNearPoint = function(centerX, centerY, - radius, farX, farY) { - - var displacementX = farX - centerX; - var displacementY = farY - centerY; - var distance = Math.sqrt(displacementX * displacementX - + displacementY * displacementY); - - var unitDisplacementX = displacementX / distance; - var unitDisplacementY = displacementY / distance; - - return [centerX + unitDisplacementX * radius, - centerY + unitDisplacementY * radius]; - }; - - $$.math.findMaxSqDistanceToOrigin = function(points) { - var maxSqDistance = 0.000001; - var sqDistance; - - for (var i = 0; i < points.length / 2; i++) { - - sqDistance = points[i * 2] * points[i * 2] - + points[i * 2 + 1] * points[i * 2 + 1]; - - if (sqDistance > maxSqDistance) { - maxSqDistance = sqDistance; - } - } - - return maxSqDistance; - }; - - $$.math.finiteLinesIntersect = function( - x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { - - var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); - var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); - var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); - - if (u_b != 0) { - var ua = ua_t / u_b; - var ub = ub_t / u_b; - - if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - - } else { - if (!infiniteLines) { - return []; - } else { - return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; - } - } - } else { - if (ua_t == 0 || ub_t == 0) { - - // Parallel, coincident lines. Check if overlap - - // Check endpoint of second line - if ([x1, x2, x4].sort()[1] == x4) { - return [x4, y4]; - } - - // Check start point of second line - if ([x1, x2, x3].sort()[1] == x3) { - return [x3, y3]; - } - - // Endpoint of first line - if ([x3, x4, x2].sort()[1] == x2) { - return [x2, y2]; - } - - return []; - } else { - - // Parallel, non-coincident - return []; - } - } - }; - - // (boxMinX, boxMinY, boxMaxX, boxMaxY, padding, - // cornerRadius * 2, cornerRadius * 2, vBoxTopLeftX + padding, hBoxTopLeftY + padding)) { - - $$.math.boxIntersectEllipse = function( - x1, y1, x2, y2, padding, width, height, centerX, centerY) { - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - // 4 ortho extreme points - var west = [centerX - width / 2 - padding, centerY]; - var east = [centerX + width / 2 + padding, centerY]; - var north = [centerX, centerY - height / 2 - padding]; - var south = [centerX, centerY + height / 2 + padding]; - - // out of bounds: return false - if (x2 < west[0]) { - return false; - } - - if (x1 > east[0]) { - return false; - } - - if (y1 > south[1]) { - return false; - } - - if (y2 < north[1]) { - return false; - } - - // 1 of 4 ortho extreme points in box: return true - if (x1 <= east[0] && east[0] <= x2 - && y1 <= east[1] && east[1] <= y2) { - return true; - } - - if (x1 <= west[0] && west[0] <= x2 - && y1 <= west[1] && west[1] <= y2) { - return true; - } - - if (x1 <= north[0] && north[0] <= x2 - && y1 <= north[1] && north[1] <= y2) { - return true; - } - - if (x1 <= south[0] && south[0] <= x2 - && y1 <= south[1] && south[1] <= y2) { - return true; - } - - // box corner in ellipse: return true - x1 = (x1 - centerX) / (width / 2 + padding); - x2 = (x2 - centerX) / (width / 2 + padding); - - y1 = (y1 - centerY) / (height / 2 + padding); - y2 = (y2 - centerY) / (height / 2 + padding); - - if (x1 * x1 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y1 * y1 <= 1) { - return true; - } - - if (x2 * x2 + y2 * y2 <= 1) { - return true; - } - - if (x1 * x1 + y2 * y2 <= 1) { - return true; - } - - return false; - }; - - $$.math.boxIntersectPolygon = function( - x1, y1, x2, y2, basePoints, width, height, centerX, centerY, direction, padding) { - -// console.log(arguments); - - if (x2 < x1) { - var oldX1 = x1; - x1 = x2; - x2 = oldX1; - } - - if (y2 < y1) { - var oldY1 = y1; - y1 = y2; - y2 = oldY1; - } - - var transformedPoints = new Array(basePoints.length) - - // Gives negative of angle - var angle = Math.asin(direction[1] / (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - if (direction[0] < 0) { - angle = angle + Math.PI / 2; - } else { - angle = -angle - Math.PI / 2; - } - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = - width / 2 * (basePoints[i * 2] * cos - - basePoints[i * 2 + 1] * sin); - - transformedPoints[i * 2 + 1] = - height / 2 * (basePoints[i * 2 + 1] * cos - + basePoints[i * 2] * sin); - - transformedPoints[i * 2] += centerX; - transformedPoints[i * 2 + 1] += centerY; - } - - // Assume transformedPoints.length > 0, and check if intersection is possible - var minTransformedX = transformedPoints[0]; - var maxTransformedX = transformedPoints[0]; - var minTransformedY = transformedPoints[1]; - var maxTransformedY = transformedPoints[1]; - - for (var i = 1; i < transformedPoints.length / 2; i++) { - if (transformedPoints[i * 2] > maxTransformedX) { - maxTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2] < minTransformedX) { - minTransformedX = transformedPoints[i * 2]; - } - - if (transformedPoints[i * 2 + 1] > maxTransformedY) { - maxTransformedY = transformedPoints[i * 2 + 1]; - } - - if (transformedPoints[i * 2 + 1] < minTransformedY) { - minTransformedY = transformedPoints[i * 2 + 1]; - } - } - - if (x2 < minTransformedX - padding) { - return false; - } - - if (x1 > maxTransformedX + padding) { - return false; - } - - if (y2 < minTransformedY - padding) { - return false; - } - - if (y1 > maxTransformedY + padding) { - return false; - } - - // Continue checking with padding-corrected points - var points; - - if (padding > 0) { - var expandedLineSet = $$.math.expandPolygon( - transformedPoints, - -padding); - - points = $$.math.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - - // Check if a point is in box - for (var i = 0; i < transformedPoints.length / 2; i++) { - if (x1 <= transformedPoints[i * 2] - && transformedPoints[i * 2] <= x2) { - - if (y1 <= transformedPoints[i * 2 + 1] - && transformedPoints[i * 2 + 1] <= y2) { - - return true; - } - } - } - - - // Check for intersections with the selection box - for (var i = 0; i < points.length / 2; i++) { - - var currentX = points[i * 2]; - var currentY = points[i * 2 + 1]; - var nextX; - var nextY; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1] - } else { - nextX = points[0]; - nextY = points[1]; - } - - // Intersection with top of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x2, y1, false).length > 0) { - return true; - } - - // Intersection with bottom of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y2, x2, y2, false).length > 0) { - return true; - } - - // Intersection with left side of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x1, y1, x1, y2, false).length > 0) { - return true; - } - - // Intersection with right side of selection box - if ($$.math.finiteLinesIntersect(currentX, currentY, nextX, nextY, x2, y1, x2, y2, false).length > 0) { - return true; - } - } - - /* - // Check if box corner in the polygon - if ($$.math.pointInsidePolygon( - x1, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x1, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x2, y2, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } else if ($$.math.pointInsidePolygon( - x2, y1, points, 0, 0, 1, 1, 0, direction)) { - - return true; - } - */ - return false; - }; - - $$.math.polygonIntersectLine = function( - x, y, basePoints, centerX, centerY, width, height, padding) { - - var intersections = []; - var intersection; - - var transformedPoints = new Array(basePoints.length); - - for (var i = 0; i < transformedPoints.length / 2; i++) { - transformedPoints[i * 2] = basePoints[i * 2] * width + centerX; - transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY; - } - - var points; - - if (padding > 0) { - var expandedLineSet = $$.math.expandPolygon( - transformedPoints, - -padding); - - points = $$.math.joinLines(expandedLineSet); - } else { - points = transformedPoints; - } - // var points = transformedPoints; - - var currentX, currentY, nextX, nextY; - - for (var i = 0; i < points.length / 2; i++) { - - currentX = points[i * 2]; - currentY = points[i * 2 + 1]; - - if (i < points.length / 2 - 1) { - nextX = points[(i + 1) * 2]; - nextY = points[(i + 1) * 2 + 1]; - } else { - nextX = points[0]; - nextY = points[1]; - } - - intersection = this.finiteLinesIntersect( - x, y, centerX, centerY, - currentX, currentY, - nextX, nextY); - - if (intersection.length != 0) { - intersections.push(intersection[0], intersection[1]); - } - } - - return intersections; - }; - - $$.math.shortenIntersection = function( - intersection, offset, amount) { - - var disp = [intersection[0] - offset[0], intersection[1] - offset[1]]; - - var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]); - - var lenRatio = (length - amount) / length; - - if (lenRatio < 0) { - lenRatio = 0.00001; - } - - return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]]; - }; - - $$.math.generateUnitNgonPointsFitToSquare = function(sides, rotationRadians) { - var points = $$.math.generateUnitNgonPoints(sides, rotationRadians); - points = $$.math.fitPolygonToSquare(points); - - return points; - }; - - $$.math.fitPolygonToSquare = function(points){ - var x, y; - var sides = points.length/2; - var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity; - - for (var i = 0; i < sides; i++) { - x = points[2 * i]; - y = points[2 * i + 1]; - - minX = Math.min( minX, x ); - maxX = Math.max( maxX, x ); - minY = Math.min( minY, y ); - maxY = Math.max( maxY, y ); - } - - // stretch factors - var sx = 2 / (maxX - minX); - var sy = 2 / (maxY - minY); - - for (var i = 0; i < sides; i++){ - x = points[2 * i] = points[2 * i] * sx; - y = points[2 * i + 1] = points[2 * i + 1] * sy; - - minX = Math.min( minX, x ); - maxX = Math.max( maxX, x ); - minY = Math.min( minY, y ); - maxY = Math.max( maxY, y ); - } - - if( minY < -1 ){ - for (var i = 0; i < sides; i++){ - y = points[2 * i + 1] = points[2 * i + 1] + (-1 -minY); - } - } - - return points; - }; - - $$.math.generateUnitNgonPoints = function(sides, rotationRadians) { - - var increment = 1.0 / sides * 2 * Math.PI; - var startAngle = sides % 2 == 0 ? - Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0; -// console.log(nodeShapes["square"]); - startAngle += rotationRadians; - - var points = new Array(sides * 2); - - var currentAngle, x, y; - for (var i = 0; i < sides; i++) { - currentAngle = i * increment + startAngle; - - x = points[2 * i] = Math.cos(currentAngle);// * (1 + i/2); - y = points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2); - } - - return points; - }; - - $$.math.getRoundRectangleRadius = function(width, height) { - - // Set the default radius, unless half of width or height is smaller than default - return Math.min(width / 2, height / 2, 10); - }; - -})( cytoscape ); - -// type testing utility functions - -;(function($$){ "use strict"; - - // list of ids with other metadata assoc'd with it - $$.instances = []; - $$.instanceCounter = 0; - $$.lastInstanceTime; - - $$.registerInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - // if we have an old reg that is empty (no cy), then - var oldReg = $$.getRegistrationForInstance(instance, domElement); - if( oldReg ){ - if( !oldReg.cy ){ - oldReg.cy = instance; - oldReg.domElement = domElement; - } else { - $$.util.error('Tried to register on a pre-existing registration'); - } - - return oldReg; - - // otherwise, just make a new registration - } else { - var time = +new Date; - var suffix; - - // add a suffix in case instances collide on the same time - if( !$$.lastInstanceTime || $$.lastInstanceTime === time ){ - $$.instanceCounter = 0; - } else { - ++$$.instanceCounter; - } - $$.lastInstanceTime = time; - suffix = $$.instanceCounter; - - var id = "cy-" + time + "-" + suffix; - - // create the registration object - var registration = { - id: id, - cy: cy, - domElement: domElement, - readies: [] // list of bound ready functions before calling init - }; - - // put the registration object in the pool - $$.instances.push( registration ); - $$.instances[ id ] = registration; - - return registration; - } - }; - - $$.removeRegistrationForInstance = function(instance, domElement){ - var cy; - - if( $$.is.core(instance) ){ - cy = instance; - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - delete $$.instances[ id ]; - $$.instances.splice(id, 1); - - } else if( $$.is.domElement(domElement) ){ - for( var i = 0; i < $$.instances.length; i++ ){ - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - delete $$.instances[ reg.id ]; - $$.instances.splice(i, 1); - i--; - } - } - } - } - - $$.getRegistrationForInstance = function( instance, domElement ){ - var cy; - - if( $$.is.core(instance) ){ - if( instance.registered() ){ // only want it if it's registered b/c if not it has no reg'd id - cy = instance; - } - } else if( $$.is.domElement(instance) ){ - domElement = instance; - } - - if( $$.is.core(cy) ){ - var id = cy._private.instanceId; - return $$.instances[ id ]; - - } else if( $$.is.domElement(domElement) ){ - for( var i = $$.instances.length - 1; i >= 0; i-- ){ // look backwards, since most recent is the one we want - var reg = $$.instances[i]; - - if( reg.domElement === domElement ){ - return reg; - } - } - } - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - // registered extensions to cytoscape, indexed by name - var extensions = {}; - $$.extensions = extensions; - - // registered modules for extensions, indexed by name - var modules = {}; - $$.modules = modules; - - function setExtension(type, name, registrant){ - var impl = {}; - impl[name] = registrant; - - switch( type ){ - case "core": - case "collection": - $$.fn[type]( impl ); - } - - return $$.util.setMap({ - map: extensions, - keys: [ type, name ], - value: registrant - }); - } - - function getExtension(type, name){ - return $$.util.getMap({ - map: extensions, - keys: [ type, name ] - }); - } - - function setModule(type, name, moduleType, moduleName, registrant){ - return $$.util.setMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ], - value: registrant - }); - } - - function getModule(type, name, moduleType, moduleName){ - return $$.util.getMap({ - map: modules, - keys: [ type, name, moduleType, moduleName ] - }); - } - - $$.extension = function(){ - // e.g. $$.extension("renderer", "svg") - if( arguments.length == 2 ){ - return getExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", { ... }) - else if( arguments.length == 3 ){ - return setExtension.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse") - else if( arguments.length == 4 ){ - return getModule.apply(this, arguments); - } - - // e.g. $$.extension("renderer", "svg", "nodeShape", "ellipse", { ... }) - else if( arguments.length == 5 ){ - return setModule.apply(this, arguments); - } - - else { - $.error("Invalid extension access syntax"); - } - - }; - -})( cytoscape ); - -;(function($, $$){ "use strict"; - - if( !$ ){ return } // no jquery => don't need this - - // allow calls on a jQuery selector by proxying calls to $.cytoscape - // e.g. $("#foo").cytoscape(options) => $.cytoscape(options) on #foo - $.fn.cytoscape = function(opts){ - var $this = $(this); - - // get object - if( opts === "get" ){ - var reg = $$.getRegistrationForInstance( $this[0] ); - return reg.cy; - } - - // bind to ready - else if( $$.is.fn(opts) ){ - //debugger; - - var ready = opts; - var domEle = $this[0]; - var reg = $$.getRegistrationForInstance( domEle ); - - if( !reg ){ - reg = $$.registerInstance( domEle ); - } - - if( reg && reg.cy && reg.cy.ready() ){ - // already ready so just trigger now - reg.cy.trigger("ready", [], ready); - - } else { - // not yet ready, so add to readies list - - reg.readies.push( ready ); - } - - } - - // proxy to create instance - else if( $$.is.plainObject(opts) ){ - return $this.each(function(){ - var options = $.extend({}, opts, { - container: $(this)[0] - }); - - cytoscape(options); - }); - } - - // proxy a function call - else { - var domEle = $this[0]; - var rets = []; - var args = []; - for(var i = 1; i < arguments.length; i++){ - args[i - 1] = arguments[i]; - } - - $this.each(function(){ - var reg = $$.getRegistrationForInstance( domEle ); - var cy = reg.cy; - var fnName = opts; - - if( cy && $$.is.fn( cy[fnName] ) ){ - var ret = cy[fnName].apply(cy, args); - rets.push(ret); - } - }); - - // if only one instance, don't need to return array - if( rets.length === 1 ){ - rets = rets[0]; - } else if( rets.length == 0 ){ - rets = $(this); - } - - return rets; - } - - }; - - // allow access to the global cytoscape object under jquery for legacy reasons - $.cytoscape = cytoscape; - - // use short alias (cy) if not already defined - if( $.fn.cy == null && $.cy == null ){ - $.fn.cy = $.fn.cytoscape; - $.cy = $.cytoscape; - } - -})(typeof jQuery !== 'undefined' ? jQuery : null , cytoscape); - -;(function($$){ "use strict"; - - // shamelessly taken from jQuery - // https://github.com/jquery/jquery/blob/master/src/event.js - - $$.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof $$.Event) ) { - return new $$.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = ( src.defaultPrevented || - src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - $$.util.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || +new Date; - }; - - function returnFalse() { - return false; - } - function returnTrue() { - return true; - } - - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding - // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html - $$.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - - // if preventDefault exists run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - } - }, - stopPropagation: function() { - this.isPropagationStopped = returnTrue; - - var e = this.originalEvent; - if ( !e ) { - return; - } - // if stopPropagation exists run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - }, - stopImmediatePropagation: function() { - this.isImmediatePropagationStopped = returnTrue; - this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - // metaprogramming makes me happy - - // use this module to cherry pick functions into your prototype - // (useful for functions shared between the core and collections, for example) - - // e.g. - // $$.fn.collection({ - // foo: $$.define.foo({ /* params... */ }) - // }); - - $$.define = { - - // access data field - data: function( params ){ - var defaults = { - field: "data", - bindingEvent: "data", - allowBinding: false, - allowSetting: false, - allowGetting: false, - settingEvent: "data", - settingTriggersEvent: false, - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false, - onSet: function( self ){}, - canSet: function( self ){ return true } - }; - params = $$.util.extend({}, defaults, params); - - return function( name, value ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .data("foo", ...) - if( $$.is.string(name) ){ // set or get property - - // .data("foo") - if( p.allowGetting && value === undefined ){ // get - - var ret; - if( single ){ - ret = single._private[ p.field ][ name ]; - } - return ret; - - // .data("foo", "bar") - } else if( p.allowSetting && value !== undefined ) { // set - var valid = !p.immutableKeys[name]; - if( valid ){ - for( var i = 0, l = all.length; i < l; i++ ){ - if( p.canSet( all[i] ) ){ - all[i]._private[ p.field ][ name ] = value; - } - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - // call onSet callback - p.onSet( self ); - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - } - } - - // .data({ "foo": "bar" }) - } else if( p.allowSetting && $$.is.plainObject(name) ){ // extend - var obj = name; - var k, v; - - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - for( var i = 0, l = all.length; i < l; i++ ){ - if( p.canSet( all[i] ) ){ - all[i]._private[ p.field ][ k ] = v; - } - } - } - } - - // update mappers if asked - if( p.updateMappers ){ self.updateMappers(); } - - // call onSet callback - p.onSet( self ); - - if( p.settingTriggersEvent ){ - self[ p.triggerFnName ]( p.settingEvent ); - } - - // .data(function(){ ... }) - } else if( p.allowBinding && $$.is.fn(name) ){ // bind to event - var fn = name; - self.bind( p.bindingEvent, fn ); - - // .data() - } else if( p.allowGetting && name === undefined ){ // get whole object - var ret; - if( single ){ - ret = single._private[ p.field ]; - } - return ret; - } - - return self; // maintain chainability - }; // function - }, // data - - batchData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: {}, // key => true if immutable - updateMappers: false - }; - var p = params = $$.util.extend({}, defaults, params); - - return function( map ){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var eles = selfIsArrayLike ? self : self._private.elements; - - if( eles.length === 0 ){ return self; } - var cy = selfIsArrayLike ? eles[0]._private.cy : self; // NB must have at least 1 ele to get cy - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - var mapData = map[id]; - - if( mapData !== undefined && mapData !== null ){ - var obj = mapData; - var k, v; - - // set the (k, v) pairs from the map - for( k in obj ){ - v = obj[ k ]; - - var valid = !p.immutableKeys[k]; - if( valid ){ - ele._private[ p.field ][ k ] = v; - } - } - } // if - } // for - - // update mappers if asked - var coln = new $$.Collection(cy, eles); - if( p.updateMappers ){ coln.updateMappers(); } - - coln[ p.triggerFnName ]( p.event ); - - return self; // chaining - }; - }, - - // remove data field - removeData: function( params ){ - var defaults = { - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: false, - immutableKeys: {} // key => true if immutable - }; - params = $$.util.extend({}, defaults, params); - - return function( names ){ - var p = params; - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - - // .removeData("foo bar") - if( $$.is.string(names) ){ // then get the list of keys, and delete them - var keys = names.split(/\s+/); - var l = keys.length; - - for( var i = 0; i < l; i++ ){ // delete each non-empty key - var key = keys[i]; - if( $$.is.emptyString(key) ){ continue; } - - var valid = !p.immutableKeys[ key ]; // not valid if immutable - if( valid ){ - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - delete all[ i_a ]._private[ p.field ][ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - - // .removeData() - } else if( names === undefined ){ // then delete all keys - - for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){ - var _privateFields = all[ i_a ]._private[ p.field ]; - - for( var key in _privateFields ){ - var validKeyToDelete = !p.immutableKeys[ key ]; - - if( validKeyToDelete ){ - delete _privateFields[ key ]; - } - } - } - - if( p.triggerEvent ){ - self[ p.triggerFnName ]( p.event ); - } - } - - return self; // maintain chaining - }; // function - }, // removeData - - // event function reusable stuff - event: { - regex: /(\w+)(\.\w+)?/, // regex for matching event strings (e.g. "click.namespace") - optionalTypeRegex: /(\w+)?(\.\w+)?/, - falseCallback: function(){ return false; } - }, - - // event binding - on: function( params ){ - var defaults = { - unbindSelfOnTrigger: false, - unbindAllBindersOnTrigger: false - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, data, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( $$.is.plainObject(selector) ){ // selector is actually data - callback = data; - data = selector; - selector = undefined; - } else if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - data = undefined; - selector = undefined; - } - - if( $$.is.fn(data) || data === false ){ // data is actually callback - callback = data; - data = undefined; - } - - // if there isn't a callback, we can't really do anything - // (can't speak for mapped events arg version) - if( !($$.is.fn(callback) || callback === false) && eventsIsString ){ - return self; // maintain chaining - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - if( !$$.is.fn(callback) ){ continue; } - - evts = evts.split(/\s+/); - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - - if( match ){ - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - var listener = { - callback: callback, // callback to run - data: data, // extra data in eventObj.data - delegated: selector ? true : false, // whether the evt is delegated - selector: selector, // the selector to match for delegated events - type: type, // the event type (e.g. "click") - namespace: namespace, // the event namespace (e.g. ".foo") - unbindSelfOnTrigger: p.unbindSelfOnTrigger, - unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger, - binders: all // who bound together - }; - - for( var j = 0; j < all.length; j++ ){ - all[j]._private.listeners.push( listener ); - } - } - } // for events array - } // for events map - - return self; // maintain chaining - }; // function - }, // on - - off: function( params ){ - var defaults = { - }; - params = $$.util.extend({}, defaults, params); - - return function(events, selector, callback){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var p = params; - - if( arguments.length === 0 ){ // then unbind all - - for( var i = 0; i < all.length; i++ ){ - all[i]._private.listeners = []; - } - - return self; // maintain chaining - } - - if( $$.is.fn(selector) || selector === false ){ // selector is actually callback - callback = selector; - selector = undefined; - } - - if( eventsIsString ){ // then convert to map - var map = {}; - map[ events ] = callback; - events = map; - } - - for( var evts in events ){ - callback = events[evts]; - - if( callback === false ){ - callback = $$.define.event.falseCallback; - } - - evts = evts.split(/\s+/); - for( var h = 0; h < evts.length; h++ ){ - var evt = evts[h]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.optionalTypeRegex ); // [type][.namespace] - if( match ){ - var type = match[1] ? match[1] : undefined; - var namespace = match[2] ? match[2] : undefined; - - for( var i = 0; i < all.length; i++ ){ // - var listeners = all[i]._private.listeners; - - for( var j = 0; j < listeners.length; j++ ){ - var listener = listeners[j]; - var nsMatches = !namespace || namespace === listener.namespace; - var typeMatches = !type || listener.type === type; - var cbMatches = !callback || callback === listener.callback; - var listenerMatches = nsMatches && typeMatches && cbMatches; - - // delete listener if it matches - if( listenerMatches ){ - listeners.splice(j, 1); - j--; - } - } // for listeners - } // for all - } // if match - } // for events array - - } // for events map - - return self; // maintain chaining - }; // function - }, // off - - trigger: function( params ){ - var defaults = {}; - params = $$.util.extend({}, defaults, params); - - return function(events, extraParams, fnToTrigger){ - var self = this; - var selfIsArrayLike = self.length !== undefined; - var all = selfIsArrayLike ? self : [self]; // put in array if not array-like - var single = selfIsArrayLike ? self[0] : self; - var eventsIsString = $$.is.string(events); - var eventsIsObject = $$.is.plainObject(events); - var eventsIsEvent = $$.is.event(events); - var p = params; - var cy = this._private.cy || this; - - if( eventsIsString ){ // then make a plain event object for each event name - var evts = events.split(/\s+/); - events = []; - - for( var i = 0; i < evts.length; i++ ){ - var evt = evts[i]; - if( $$.is.emptyString(evt) ){ continue; } - - var match = evt.match( $$.define.event.regex ); // type[.namespace] - var type = match[1]; - var namespace = match[2] ? match[2] : undefined; - - events.push( { - type: type, - namespace: namespace - } ); - } - } else if( eventsIsObject ){ // put in length 1 array - var eventArgObj = events; - - events = [ eventArgObj ]; - } - - if( extraParams ){ - if( !$$.is.array(extraParams) ){ // make sure extra params are in an array if specified - extraParams = [ extraParams ]; - } - } else { // otherwise, we've got nothing - extraParams = []; - } - - for( var i = 0; i < events.length; i++ ){ // trigger each event in order - var evtObj = events[i]; - - for( var j = 0; j < all.length; j++ ){ // for each - var triggerer = all[j]; - var listeners = triggerer._private.listeners; - var triggererIsElement = $$.is.element(triggerer); - var bubbleUp = triggererIsElement; - - // create the event for this element from the event object - var evt; - - if( eventsIsEvent ){ // then just get the object - evt = evtObj; - - evt.cyTarget = evt.cyTarget || triggerer; - evt.cy = evt.cy || cy; - evt.namespace = evt.namespace || evtObj.namespace; - - } else { // then we have to make one - evt = new $$.Event( evtObj, { - cyTarget: triggerer, - cy: cy, - namespace: evtObj.namespace - } ); - } - - // Create a rendered position based on the passed position - if( evt.cyPosition ){ - var pos = evt.cyPosition; - var zoom = cy.zoom(); - var pan = cy.pan(); - - evt.cyRenderedPosition = { - x: pos.x * zoom + pan.x, - y: pos.y * zoom + pan.y - }; - } - - if( fnToTrigger ){ // then override the listeners list with just the one we specified - listeners = [{ - namespace: evt.namespace, - type: evt.type, - callback: fnToTrigger - }]; - } - - for( var k = 0; k < listeners.length; k++ ){ // check each listener - var lis = listeners[k]; - var nsMatches = !lis.namespace || lis.namespace === evt.namespace; - var typeMatches = lis.type === evt.type; - var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && $$.is.element(evt.cyTarget) && evt.cyTarget.is(lis.selector) ) : (true); // we're not going to validate the hierarchy; that's too expensive - var listenerMatches = nsMatches && typeMatches && targetMatches; - - if( listenerMatches ){ // then trigger it - var args = [ evt ]; - args = args.concat( extraParams ); // add extra params to args list - - if( lis.data ){ // add on data plugged into binding - evt.data = lis.data; - } else { // or clear it in case the event obj is reused - evt.data = undefined; - } - - if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener - listeners.splice(k, 1); - k--; - } - - if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders - var binders = lis.binders; - for( var l = 0; l < binders.length; l++ ){ - var binder = binders[l]; - if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it - - var binderListeners = binder._private.listeners; - for( var m = 0; m < binderListeners.length; m++ ){ - var binderListener = binderListeners[m]; - - if( binderListener === lis ){ // delete listener from list - binderListeners.splice(m, 1); - m--; - } - } - } - } - - // run the callback - var context = lis.delegated ? evt.cyTarget : triggerer; - var ret = lis.callback.apply( context, args ); - - if( ret === false || evt.isPropagationStopped() ){ - // then don't bubble - bubbleUp = false; - - if( ret === false ){ - // returning false is a shorthand for stopping propagation and preventing the def. action - evt.stopPropagation(); - evt.preventDefault(); - } - } - } // if listener matches - } // for each listener - - // bubble up event for elements - if( bubbleUp ){ - var parent = triggerer.parent(); - var hasParent = parent.length !== 0; - - if( hasParent ){ // then bubble up to parent - parent = parent[0]; - parent.trigger(evt); - } else { // otherwise, bubble up to the core - cy.trigger(evt); - } - } - - } // for each of all - } // for each event - - return self; // maintain chaining - }; // function - } // trigger - - }; // define - - -})( cytoscape ); - -;(function($$){ "use strict"; - - - $$.fn.selector = function(map, options){ - for( var name in map ){ - var fn = map[name]; - $$.Selector.prototype[ name ] = fn; - } - }; - - $$.Selector = function(onlyThisGroup, selector){ - - if( !(this instanceof $$.Selector) ){ - return new $$.Selector(onlyThisGroup, selector); - } - - if( selector === undefined && onlyThisGroup !== undefined ){ - selector = onlyThisGroup; - onlyThisGroup = undefined; - } - - var self = this; - - self._private = { - selectorText: null, - invalid: true - } - - // storage for parsed queries - // when you add something here, also add to Selector.toString() - var newQuery = function(){ - return { - classes: [], - colonSelectors: [], - data: [], - group: null, - ids: [], - meta: [], - - // fake selectors - collection: null, // a collection to match against - filter: null, // filter function - - // these are defined in the upward direction rather than down (e.g. child) - // because we need to go up in Selector.filter() - parent: null, // parent query obj - ancestor: null, // ancestor query obj - subject: null, // defines subject in compound query (subject query obj; points to self if subject) - - // use these only when subject has been defined - child: null, - descendant: null - }; - } - - if( !selector || ( $$.is.string(selector) && selector.match(/^\s*$/) ) ){ - - if( onlyThisGroup == null ){ - // ignore - self.length = 0; - } else { - self[0] = newQuery(); - self[0].group = onlyThisGroup; - self.length = 1; - } - - } else if( $$.is.element( selector ) ){ - var collection = new $$.Collection(self.cy(), [ selector ]); - - self[0] = newQuery(); - self[0].collection = collection; - self.length = 1; - - } else if( $$.is.collection( selector ) ){ - self[0] = newQuery(); - self[0].collection = selector; - self.length = 1; - - } else if( $$.is.fn( selector ) ) { - self[0] = newQuery(); - self[0].filter = selector; - self.length = 1; - - } else if( $$.is.string( selector ) ){ - - // these are the actual tokens in the query language - var metaChar = "[\\!\\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]"; // chars we need to escape in var names, etc - var variable = "(?:[\\w-]|(?:\\\\"+ metaChar +"))+"; // a variable name - var comparatorOp = "=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*="; // binary comparison op (used in data selectors) - var boolOp = "\\?|\\!|\\^"; // boolean (unary) operators (used in data selectors) - var string = '"(?:\\\\"|[^"])+"' + "|" + "'(?:\\\\'|[^'])+'"; // string literals (used in data selectors) -- doublequotes | singlequotes - var number = $$.util.regex.number; // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123 - var value = string + "|" + number; // a value literal, either a string or number - var meta = "degree|indegree|outdegree"; // allowed metadata fields (i.e. allowed functions to use from $$.Collection) - var separator = "\\s*,\\s*"; // queries are separated by commas; e.g. edge[foo = "bar"], node.someClass - var className = variable; // a class name (follows variable conventions) - var descendant = "\\s+"; - var child = "\\s+>\\s+"; - var subject = "\\$"; - var id = variable; // an element id (follows variable conventions) - - // when a token like a variable has escaped meta characters, we need to clean the backslashes out - // so that values get compared properly in Selector.filter() - var cleanMetaChars = function(str){ - return str.replace(new RegExp("\\\\(" + metaChar + ")", "g"), function(match, $1, offset, original){ - return $1; - }); - }; - - // add @ variants to comparatorOp - var ops = comparatorOp.split("|"); - for( var i = 0; i < ops.length; i++ ){ - var op = ops[i]; - comparatorOp += "|@" + op; - } - - // the current subject in the query - var currentSubject = null; - - // NOTE: add new expression syntax here to have it recognised by the parser; - // a query contains all adjacent (i.e. no separator in between) expressions; - // the current query is stored in self[i] --- you can use the reference to `this` in the populate function; - // you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward - var exprs = { - group: { - query: true, - regex: "(node|edge|\\*)", - populate: function( group ){ - this.group = group == "*" ? group : group + "s"; - } - }, - - state: { - query: true, - regex: "(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:parent|:child|:active|:inactive|:touch)", - populate: function( state ){ - this.colonSelectors.push( state ); - } - }, - - id: { - query: true, - regex: "\\#("+ id +")", - populate: function( id ){ - this.ids.push( cleanMetaChars(id) ); - } - }, - - className: { - query: true, - regex: "\\.("+ className +")", - populate: function( className ){ - this.classes.push( cleanMetaChars(className) ); - } - }, - - dataExists: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*\\]", - populate: function( variable ){ - this.data.push({ - field: cleanMetaChars(variable) - }); - } - }, - - dataCompare: { - query: true, - regex: "\\[\\s*("+ variable +")\\s*("+ comparatorOp +")\\s*("+ value +")\\s*\\]", - populate: function( variable, comparatorOp, value ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: comparatorOp, - value: value - }); - } - }, - - dataBool: { - query: true, - regex: "\\[\\s*("+ boolOp +")\\s*("+ variable +")\\s*\\]", - populate: function( boolOp, variable ){ - this.data.push({ - field: cleanMetaChars(variable), - operator: boolOp - }); - } - }, - - metaCompare: { - query: true, - regex: "\\[\\[\\s*("+ meta +")\\s*("+ comparatorOp +")\\s*("+ number +")\\s*\\]\\]", - populate: function( meta, comparatorOp, number ){ - this.meta.push({ - field: cleanMetaChars(meta), - operator: comparatorOp, - value: number - }); - } - }, - - nextQuery: { - separator: true, - regex: separator, - populate: function(){ - // go on to next query - self[++i] = newQuery(); - currentSubject = null; - } - }, - - child: { - separator: true, - regex: child, - populate: function(){ - // this query is the parent of the following query - var childQuery = newQuery(); - childQuery.parent = this; - childQuery.subject = currentSubject; - - // we're now populating the child query with expressions that follow - self[i] = childQuery; - } - }, - - descendant: { - separator: true, - regex: descendant, - populate: function(){ - // this query is the ancestor of the following query - var descendantQuery = newQuery(); - descendantQuery.ancestor = this; - descendantQuery.subject = currentSubject; - - // we're now populating the descendant query with expressions that follow - self[i] = descendantQuery; - } - }, - - subject: { - modifier: true, - regex: subject, - populate: function(){ - if( currentSubject != null && this.subject != this ){ - $$.util.error("Redefinition of subject in selector `" + selector + "`"); - return false; - } - - currentSubject = this; - this.subject = this; - }, - - } - }; - - var j = 0; - for( var name in exprs ){ - exprs[j] = exprs[name]; - exprs[j].name = name; - - j++; - } - exprs.length = j; - - self._private.selectorText = selector; - var remaining = selector; - var i = 0; - - // of all the expressions, find the first match in the remaining text - var consumeExpr = function( expectation ){ - var expr; - var match; - var name; - - for( var j = 0; j < exprs.length; j++ ){ - var e = exprs[j]; - var n = e.name; - - // ignore this expression if it doesn't meet the expectation function - if( $$.is.fn( expectation ) && !expectation(n, e) ){ continue } - - var m = remaining.match(new RegExp( "^" + e.regex )); - - if( m != null ){ - match = m; - expr = e; - name = n; - - var consumed = m[0]; - remaining = remaining.substring( consumed.length ); - - break; // we've consumed one expr, so we can return now - } - } - - return { - expr: expr, - match: match, - name: name - }; - }; - - // consume all leading whitespace - var consumeWhitespace = function(){ - var match = remaining.match(/^\s+/); - - if( match ){ - var consumed = match[0]; - remaining = remaining.substring( consumed.length ); - } - }; - - self[0] = newQuery(); // get started - - consumeWhitespace(); // get rid of leading whitespace - for(;;){ - var check = consumeExpr(); - - if( check.expr == null ){ - $$.util.error("The selector `"+ selector +"`is invalid"); - return; - } else { - var args = []; - for(var j = 1; j < check.match.length; j++){ - args.push( check.match[j] ); - } - - // let the token populate the selector object (i.e. in self[i]) - var ret = check.expr.populate.apply( self[i], args ); - - if( ret === false ){ return } // exit if population failed - } - - // we're done when there's nothing left to parse - if( remaining.match(/^\s*$/) ){ - break; - } - } - - self.length = i + 1; - - // adjust references for subject - for(j = 0; j < self.length; j++){ - var query = self[j]; - - if( query.subject != null ){ - // go up the tree until we reach the subject - for(;;){ - if( query.subject == query ){ break } // done if subject is self - - if( query.parent != null ){ // swap parent/child reference - var parent = query.parent; - var child = query; - - child.parent = null; - parent.child = child; - - query = parent; // go up the tree - } else if( query.ancestor != null ){ // swap ancestor/descendant - var ancestor = query.ancestor; - var descendant = query; - - descendant.ancestor = null; - ancestor.descendant = descendant; - - query = ancestor; // go up the tree - } else { - $$.util.error("When adjusting references for the selector `"+ query +"`, neither parent nor ancestor was found"); - break; - } - } // for - - self[j] = query.subject; // subject should be the root query - } // if - } // for - - // make sure for each query that the subject group matches the implicit group if any - if( onlyThisGroup != null ){ - for(var j = 0; j < self.length; j++){ - if( self[j].group != null && self[j].group != onlyThisGroup ){ - $$.util.error("Group `"+ self[j].group +"` conflicts with implicit group `"+ onlyThisGroup +"` in selector `"+ selector +"`"); - return; - } - - self[j].group = onlyThisGroup; // set to implicit group - } - } - - } else { - $$.util.error("A selector must be created from a string; found " + selector); - return; - } - - self._private.invalid = false; - - }; - - $$.selfn = $$.Selector.prototype; - - $$.selfn.size = function(){ - return this.length; - }; - - $$.selfn.eq = function(i){ - return this[i]; - }; - - // get elements from the core and then filter them - $$.selfn.find = function(){ - // TODO impl if we decide to use a DB for storing elements - }; - - // filter an existing collection - $$.selfn.filter = function(collection, addLiveFunction){ - var self = this; - var cy = collection.cy(); - - // don't bother trying if it's invalid - if( self._private.invalid ){ - return new $$.Collection( cy ); - } - - var queryMatches = function(query, element){ - // check group - if( query.group != null && query.group != "*" && query.group != element._private.group ){ - return false; - } - - // check colon selectors - var allColonSelectorsMatch = true; - for(var k = 0; k < query.colonSelectors.length; k++){ - var sel = query.colonSelectors[k]; - var renderer = cy.renderer(); // TODO remove reference after refactoring - - switch(sel){ - case ":selected": - allColonSelectorsMatch = element.selected(); - break; - case ":unselected": - allColonSelectorsMatch = !element.selected(); - break; - case ":selectable": - allColonSelectorsMatch = element.selectable(); - break; - case ":unselectable": - allColonSelectorsMatch = !element.selectable(); - break; - case ":locked": - allColonSelectorsMatch = element.locked(); - break; - case ":unlocked": - allColonSelectorsMatch = !element.locked(); - break; - case ":visible": - allColonSelectorsMatch = element.visible(); - break; - case ":hidden": - allColonSelectorsMatch = !element.visible(); - break; - case ":transparent": - allColonSelectorsMatch = !element.transparent(); - break; - case ":grabbed": - allColonSelectorsMatch = element.grabbed(); - break; - case ":free": - allColonSelectorsMatch = !element.grabbed(); - break; - case ":removed": - allColonSelectorsMatch = element.removed(); - break; - case ":inside": - allColonSelectorsMatch = !element.removed(); - break; - case ":grabbable": - allColonSelectorsMatch = element.grabbable(); - break; - case ":ungrabbable": - allColonSelectorsMatch = !element.grabbable(); - break; - case ":animated": - allColonSelectorsMatch = element.animated(); - break; - case ":unanimated": - allColonSelectorsMatch = !element.animated(); - break; - case ":parent": - allColonSelectorsMatch = element.children().nonempty(); - break; - case ":child": - allColonSelectorsMatch = element.parent().nonempty(); - break; - case ":active": - allColonSelectorsMatch = element.active(); - break; - case ":inactive": - allColonSelectorsMatch = !element.active(); - break; - case ":touch": - allColonSelectorsMatch = window && document && (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch); - break; - } - - if( !allColonSelectorsMatch ) break; - } - if( !allColonSelectorsMatch ) return false; - - // check id - var allIdsMatch = true; - for(var k = 0; k < query.ids.length; k++){ - var id = query.ids[k]; - var actualId = element._private.data.id; - - allIdsMatch = allIdsMatch && (id == actualId); - - if( !allIdsMatch ) break; - } - if( !allIdsMatch ) return false; - - // check classes - var allClassesMatch = true; - for(var k = 0; k < query.classes.length; k++){ - var cls = query.classes[k]; - - allClassesMatch = allClassesMatch && element.hasClass(cls); - - if( !allClassesMatch ) break; - } - if( !allClassesMatch ) return false; - - // generic checking for data/metadata - var operandsMatch = function(params){ - var allDataMatches = true; - for(var k = 0; k < query[params.name].length; k++){ - var data = query[params.name][k]; - var operator = data.operator; - var value = data.value; - var field = data.field; - var matches; - - if( operator != null && value != null ){ - - var fieldStr = "" + params.fieldValue(field); - var valStr = "" + eval(value); - - var caseInsensitive = false; - if( operator.charAt(0) == "@" ){ - fieldStr = fieldStr.toLowerCase(); - valStr = valStr.toLowerCase(); - - operator = operator.substring(1); - caseInsensitive = true; - } - - if( operator == "=" ){ - operator = "=="; - } - - switch(operator){ - case "*=": - matches = fieldStr.search(valStr) >= 0; - break; - case "$=": - matches = new RegExp(valStr + "$").exec(fieldStr) != null; - break; - case "^=": - matches = new RegExp("^" + valStr).exec(fieldStr) != null; - break; - default: - // if we're doing a case insensitive comparison, then we're using a STRING comparison - // even if we're comparing numbers - if( caseInsensitive ){ - // eval with lower case strings - var expr = "fieldStr " + operator + " valStr"; - matches = eval(expr); - } else { - // just eval as normal - var expr = params.fieldRef(field) + " " + operator + " " + value; - matches = eval(expr); - } - - } - } else if( operator != null ){ - switch(operator){ - case "?": - matches = params.fieldTruthy(field); - break; - case "!": - matches = !params.fieldTruthy(field); - break; - case "^": - matches = params.fieldUndefined(field); - break; - } - } else { - matches = !params.fieldUndefined(field); - } - - if( !matches ){ - allDataMatches = false; - break; - } - } // for - - return allDataMatches; - }; // operandsMatch - - // check data matches - var allDataMatches = operandsMatch({ - name: "data", - fieldValue: function(field){ - return element._private.data[field]; - }, - fieldRef: function(field){ - return "element._private.data." + field; - }, - fieldUndefined: function(field){ - return element._private.data[field] === undefined; - }, - fieldTruthy: function(field){ - if( element._private.data[field] ){ - return true; - } - return false; - } - }); - - if( !allDataMatches ){ - return false; - } - - // check metadata matches - var allMetaMatches = operandsMatch({ - name: "meta", - fieldValue: function(field){ - return element[field](); - }, - fieldRef: function(field){ - return "element." + field + "()"; - }, - fieldUndefined: function(field){ - return element[field]() == undefined; - }, - fieldTruthy: function(field){ - if( element[field]() ){ - return true; - } - return false; - } - }); - - if( !allMetaMatches ){ - return false; - } - - // check collection - if( query.collection != null ){ - var matchesAny = query.collection._private.ids[ element.id() ] != null; - - if( !matchesAny ){ - return false; - } - } - - // check filter function - if( query.filter != null && element.collection().filter( query.filter ).size() == 0 ){ - return false; - } - - - // check parent/child relations - var confirmRelations = function( query, elements ){ - if( query != null ){ - var matches = false; - elements = elements(); // make elements functional so we save cycles if query == null - - // query must match for at least one element (may be recursive) - for(var i = 0; i < elements.size(); i++){ - if( queryMatches( query, elements.eq(i) ) ){ - matches = true; - break; - } - } - - return matches; - } else { - return true; - } - }; - - if (! confirmRelations(query.parent, function(){ - return element.parent() - }) ){ return false } - - if (! confirmRelations(query.ancestor, function(){ - return element.parents() - }) ){ return false } - - if (! confirmRelations(query.child, function(){ - return element.children() - }) ){ return false } - - if (! confirmRelations(query.descendant, function(){ - return element.descendants() - }) ){ return false } - - // we've reached the end, so we've matched everything for this query - return true; - }; // queryMatches - - var selectorFunction = function(i, element){ - for(var j = 0; j < self.length; j++){ - var query = self[j]; - - if( queryMatches(query, element) ){ - return true; - } - } - - return false; - }; - - if( self._private.selectorText == null ){ - selectorFunction = function(){ return true; }; - } - - var filteredCollection = collection.filter( selectorFunction ); - - return filteredCollection; - }; // filter - - // ith query to string - $$.selfn.toString = $$.selfn.selector = function(){ - - var str = ""; - - var clean = function(obj){ - if( $$.is.string(obj) ){ - return obj; - } - return ""; - }; - - var queryToString = function(query){ - var str = ""; - - var group = clean(query.group); - str += group.substring(0, group.length - 1); - - for(var j = 0; j < query.data.length; j++){ - var data = query.data[j]; - str += "[" + data.field + clean(data.operator) + clean(data.value) + "]" - } - - for(var j = 0; j < query.meta.length; j++){ - var meta = query.meta[j]; - str += "{" + meta.field + clean(meta.operator) + clean(meta.value) + "}" - } - - for(var j = 0; j < query.colonSelectors.length; j++){ - var sel = query.colonSelectors[i]; - str += sel; - } - - for(var j = 0; j < query.ids.length; j++){ - var sel = "#" + query.ids[i]; - str += sel; - } - - for(var j = 0; j < query.classes.length; j++){ - var sel = "." + query.classes[i]; - str += sel; - } - - if( query.parent != null ){ - str = queryToString( query.parent ) + " > " + str; - } - - if( query.ancestor != null ){ - str = queryToString( query.ancestor ) + " " + str; - } - - if( query.child != null ){ - str += " > " + queryToString( query.child ); - } - - if( query.descendant != null ){ - str += " " + queryToString( query.descendant ); - } - - return str; - }; - - for(var i = 0; i < this.length; i++){ - var query = this[i]; - - str += queryToString( query ); - - if( this.length > 1 && i < this.length - 1 ){ - str += ", "; - } - } - - return str; - }; - -})( cytoscape ); - -;(function($$, window){ "use strict"; - - var isTouch = $$.is.touch(); - - $$.Style = function( cy ){ - - if( !(this instanceof $$.Style) ){ - return new $$.Style(cy); - } - - if( !$$.is.core(cy) ){ - $$.util.error("A style must have a core reference"); - return; - } - - this._private = { - cy: cy, - coreStyle: {} - }; - - this.length = 0; - - this.addDefaultStylesheet(); - }; - - // nice-to-have aliases - $$.style = $$.Style; - $$.styfn = $$.Style.prototype; - - // define functions in the Style prototype - $$.fn.style = function( fnMap, options ){ - for( var fnName in fnMap ){ - var fn = fnMap[ fnName ]; - $$.Style.prototype = fn; - } - }; - - // a dummy stylesheet object that doesn't need a reference to the core - $$.stylesheet = $$.Stylesheet = function(){ - if( !(this instanceof $$.Stylesheet) ){ - return new $$.Stylesheet(); - } - - this.length = 0; - }; - - // just store the selector to be parsed later - $$.Stylesheet.prototype.selector = function( selector ){ - var i = this.length++; - - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // just store the property to be parsed later - $$.Stylesheet.prototype.css = function( name, value ){ - var i = this.length - 1; - - if( $$.is.string(name) ){ - this[i].properties.push({ - name: name, - value: value - }); - } else if( $$.is.plainObject(name) ){ - var map = name; - - for( var j = 0; j < $$.style.properties.length; j++ ){ - var prop = $$.style.properties[j]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ // also try camel case name - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - var name = prop.name; - var value = mapVal; - - this[i].properties.push({ - name: name, - value: value - }); - } - } - } - - return this; // chaining - }; - - $$.style.applyFromString = function( style, string ){ - var remaining = "" + string; - var selAndBlockStr; - var blockRem; - var propAndValStr; - - // remove comments from the style string - remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, ""); - - function removeSelAndBlockFromRemaining(){ - // remove the parsed selector and block from the remaining text to parse - if( remaining.length > selAndBlockStr.length ){ - remaining = remaining.substr( selAndBlockStr.length ); - } else { - remaining = ""; - } - } - - function removePropAndValFromRem(){ - // remove the parsed property and value from the remaining block text to parse - if( blockRem.length > propAndValStr.length ){ - blockRem = blockRem.substr( propAndValStr.length ); - } else { - blockRem = ""; - } - } - - while(true){ - var nothingLeftToParse = remaining.match(/^\s*$/); - if( nothingLeftToParse ){ break; } - - var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); - - if( !selAndBlock ){ - $$.util.error("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: " + remaining); - break; - } - - selAndBlockStr = selAndBlock[0]; - - // parse the selector - var selectorStr = selAndBlock[1]; - var selector = new $$.Selector( selectorStr ); - if( selector._private.invalid ){ - $$.util.error("Skipping parsing of block: Invalid selector found in string stylesheet: " + selectorStr); - - // skip this selector and block - removeSelAndBlockFromRemaining(); - continue; - } - - // parse the block of properties and values - var blockStr = selAndBlock[2]; - var invalidBlock = false; - blockRem = blockStr; - var props = []; - - while(true){ - var nothingLeftToParse = blockRem.match(/^\s*$/); - if( nothingLeftToParse ){ break; } - - var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/); - - if( !propAndVal ){ - $$.util.error("Skipping parsing of block: Invalid formatting of style property and value definitions found in:" + blockStr); - invalidBlock = true; - break; - } - - propAndValStr = propAndVal[0]; - var propStr = propAndVal[1]; - var valStr = propAndVal[2]; - - var prop = $$.style.properties[ propStr ]; - if( !prop ){ - $$.util.error("Skipping property: Invalid property name in: " + propAndValStr); - - // skip this property in the block - removePropAndValFromRem(); - continue; - } - - var parsedProp = style.parse( propStr, valStr ); - - if( !parsedProp ){ - $$.util.error("Skipping property: Invalid property definition in: " + propAndValStr); - - // skip this property in the block - removePropAndValFromRem(); - continue; - } - - props.push({ - name: propStr, - val: valStr - }); - removePropAndValFromRem(); - } - - if( invalidBlock ){ - removeSelAndBlockFromRemaining(); - break; - } - - // put the parsed block in the style - style.selector( selectorStr ); - for( var i = 0; i < props.length; i++ ){ - var prop = props[i]; - style.css( prop.name, prop.val ); - } - - removeSelAndBlockFromRemaining(); - } - - return style; - }; - - $$.style.fromString = function( cy, string ){ - var style = new $$.Style(cy); - - $$.style.applyFromString( style, string ); - - return style; - }; - - $$.styfn.fromString = function( string ){ - var style = this; - - style.resetToDefault(); - - $$.style.applyFromString( style, string ); - - return style; - }; - - $$.style.applyFromJson = function( style, json ){ - for( var i = 0; i < json.length; i++ ){ - var context = json[i]; - var selector = context.selector; - var props = context.css; - - style.selector(selector); // apply selector - - for( var name in props ){ - var value = props[name]; - - style.css( name, value ); // apply property - } - } - - return style; - }; - - // static function - $$.style.fromJson = function( cy, json ){ - var style = new $$.Style(cy); - - $$.style.applyFromJson( style, json ); - - return style; - }; - - $$.styfn.fromJson = function( json ){ - var style = this; - - style.resetToDefault(); - - $$.style.applyFromJson( style, json ); - - return style; - }; - - // get json from style api - $$.styfn.json = function(){ - var json = []; - - for( var i = 0; i < this.length; i++ ){ - var cxt = this[i]; - var selector = cxt.selector; - var props = cxt.properties; - var css = {}; - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - css[ prop.name ] = prop.strValue; - } - - json.push({ - selector: !selector ? "core" : selector.toString(), - css: css - }); - } - - return json; - }; - - // generate a real style object from the dummy stylesheet - $$.Stylesheet.prototype.generateStyle = function( cy ){ - var style = new $$.Style(cy); - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - - return style; - }; - - $$.Stylesheet.prototype.assignToStyle = function( style, addDefaultStylesheet ){ - style.clear(); - - if( addDefaultStylesheet || addDefaultStylesheet === undefined ){ - style.addDefaultStylesheet(); - } - - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var selector = context.selector; - var props = context.properties; - - style.selector(selector); // apply selector - - for( var j = 0; j < props.length; j++ ){ - var prop = props[j]; - - style.css( prop.name, prop.value ); // apply property - } - } - }; - - (function(){ - var number = $$.util.regex.number; - var rgba = $$.util.regex.rgbaNoBackRefs; - var hsla = $$.util.regex.hslaNoBackRefs; - var hex3 = $$.util.regex.hex3; - var hex6 = $$.util.regex.hex6; - var data = function( prefix ){ return "^" + prefix + "\\s*\\(\\s*([\\w\\.]+)\\s*\\)$" }; - var mapData = function( prefix ){ return "^" + prefix + "\\s*\\(([\\w\\.]+)\\s*\\,\\s*(" + number + ")\\s*\\,\\s*(" + number + ")\\s*,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\s*\\,\\s*(" + number + "|\\w+|" + rgba + "|" + hsla + "|" + hex3 + "|" + hex6 + ")\\)$" }; - - // each visual style property has a type and needs to be validated according to it - $$.style.types = { - percent: { number: true, min: 0, max: 100, units: "%" }, - zeroOneNumber: { number: true, min: 0, max: 1, unitless: true }, - nonNegativeInt: { number: true, min: 0, integer: true, unitless: true }, - size: { number: true, min: 0, enums: ["auto"] }, - bgSize: { number: true, min: 0, allowPercent: true }, - color: { color: true }, - lineStyle: { enums: ["solid", "dotted", "dashed"] }, - curveStyle: { enums: ["bundled", "bezier"] }, - fontFamily: { regex: "^([\\w- ]+(?:\\s*,\\s*[\\w- ]+)*)$" }, - fontVariant: { enums: ["small-caps", "normal"] }, - fontStyle: { enums: ["italic", "normal", "oblique"] }, - fontWeight: { enums: ["normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "800", "900", 100, 200, 300, 400, 500, 600, 700, 800, 900] }, - textDecoration: { enums: ["none", "underline", "overline", "line-through"] }, - textTransform: { enums: ["none", "capitalize", "uppercase", "lowercase"] }, - nodeShape: { enums: ["rectangle", "roundrectangle", "ellipse", "triangle", - "square", "pentagon", "hexagon", "heptagon", "octagon", "star"] }, - arrowShape: { enums: ["tee", "triangle", "square", "circle", "diamond", "none"] }, - display: { enums: ["element", "none"] }, - visibility: { enums: ["hidden", "visible"] }, - valign: { enums: ["top", "center", "bottom"] }, - halign: { enums: ["left", "center", "right"] }, - positionx: { enums: ["left", "center", "right"], number: true, allowPercent: true }, - positiony: { enums: ["top", "center", "bottom"], number: true, allowPercent: true }, - bgRepeat: { enums: ["repeat", "repeat-x", "repeat-y", "no-repeat"] }, - cursor: { enums: ["auto", "crosshair", "default", "e-resize", "n-resize", "ne-resize", "nw-resize", "pointer", "progress", "s-resize", "sw-resize", "text", "w-resize", "wait", "grab", "grabbing"] }, - text: { string: true }, - data: { mapping: true, regex: data("data") }, - layoutData: { mapping: true, regex: data("layoutData") }, - mapData: { mapping: true, regex: mapData("mapData") }, - mapLayoutData: { mapping: true, regex: mapData("mapLayoutData") }, - url: { regex: "^url\\s*\\(\\s*([^\\s]+)\\s*\\s*\\)|none|(.+)$" } - }; - - // define visual style properties - var t = $$.style.types; - $$.style.properties = [ - // these are for elements - { name: "cursor", type: t.cursor }, - { name: "text-valign", type: t.valign }, - { name: "text-halign", type: t.halign }, - { name: "color", type: t.color }, - { name: "content", type: t.text }, - { name: "text-outline-color", type: t.color }, - { name: "text-outline-width", type: t.size }, - { name: "text-outline-opacity", type: t.zeroOneNumber }, - { name: "text-opacity", type: t.zeroOneNumber }, - { name: "text-decoration", type: t.textDecoration }, - { name: "text-transform", type: t.textTransform }, - { name: "font-family", type: t.fontFamily }, - { name: "font-style", type: t.fontStyle }, - { name: "font-variant", type: t.fontVariant }, - { name: "font-weight", type: t.fontWeight }, - { name: "font-size", type: t.size }, - { name: "min-zoomed-font-size", type: t.size }, - { name: "display", type: t.display }, - { name: "visibility", type: t.visibility }, - { name: "opacity", type: t.zeroOneNumber }, - { name: "z-index", type: t.nonNegativeInt }, - { name: "overlay-padding", type: t.size }, - { name: "overlay-color", type: t.color }, - { name: "overlay-opacity", type: t.zeroOneNumber }, - - // these are just for nodes - { name: "background-color", type: t.color }, - { name: "background-opacity", type: t.zeroOneNumber }, - { name: "background-image", type: t.url }, - { name: "background-position-x", type: t.positionx }, - { name: "background-position-y", type: t.positiony }, - { name: "background-repeat", type: t.bgRepeat }, - { name: "background-size-x", type: t.bgSize }, - { name: "background-size-y", type: t.bgSize }, - { name: "pie-1-background-color", type: t.color }, - { name: "pie-2-background-color", type: t.color }, - { name: "pie-3-background-color", type: t.color }, - { name: "pie-4-background-color", type: t.color }, - { name: "pie-5-background-color", type: t.color }, - { name: "pie-6-background-color", type: t.color }, - { name: "pie-7-background-color", type: t.color }, - { name: "pie-8-background-color", type: t.color }, - { name: "pie-9-background-color", type: t.color }, - { name: "pie-10-background-color", type: t.color }, - { name: "pie-11-background-color", type: t.color }, - { name: "pie-12-background-color", type: t.color }, - { name: "pie-13-background-color", type: t.color }, - { name: "pie-14-background-color", type: t.color }, - { name: "pie-15-background-color", type: t.color }, - { name: "pie-16-background-color", type: t.color }, - { name: "pie-1-background-size", type: t.percent }, - { name: "pie-2-background-size", type: t.percent }, - { name: "pie-3-background-size", type: t.percent }, - { name: "pie-4-background-size", type: t.percent }, - { name: "pie-5-background-size", type: t.percent }, - { name: "pie-6-background-size", type: t.percent }, - { name: "pie-7-background-size", type: t.percent }, - { name: "pie-8-background-size", type: t.percent }, - { name: "pie-9-background-size", type: t.percent }, - { name: "pie-10-background-size", type: t.percent }, - { name: "pie-11-background-size", type: t.percent }, - { name: "pie-12-background-size", type: t.percent }, - { name: "pie-13-background-size", type: t.percent }, - { name: "pie-14-background-size", type: t.percent }, - { name: "pie-15-background-size", type: t.percent }, - { name: "pie-16-background-size", type: t.percent }, - { name: "border-color", type: t.color }, - { name: "border-opacity", type: t.zeroOneNumber }, - { name: "border-width", type: t.size }, - { name: "border-style", type: t.lineStyle }, - { name: "height", type: t.size }, - { name: "width", type: t.size }, - { name: "padding-left", type: t.size }, - { name: "padding-right", type: t.size }, - { name: "padding-top", type: t.size }, - { name: "padding-bottom", type: t.size }, - { name: "shape", type: t.nodeShape }, - - // these are just for edges - { name: "source-arrow-shape", type: t.arrowShape }, - { name: "target-arrow-shape", type: t.arrowShape }, - { name: "source-arrow-color", type: t.color }, - { name: "target-arrow-color", type: t.color }, - { name: "line-style", type: t.lineStyle }, - { name: "line-color", type: t.color }, - { name: "control-point-step-size", type: t.size }, - { name: "curve-style", type: t.curveStyle }, - - // these are just for the core - { name: "selection-box-color", type: t.color }, - { name: "selection-box-opacity", type: t.zeroOneNumber }, - { name: "selection-box-border-color", type: t.color }, - { name: "selection-box-border-width", type: t.size }, - { name: "panning-cursor", type: t.cursor }, - { name: "active-bg-color", type: t.color }, - { name: "active-bg-opacity", type: t.zeroOneNumber }, - { name: "active-bg-size", type: t.size } - ]; - - // allow access of properties by name ( e.g. $$.style.properties.height ) - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var prop = props[i]; - - props[ prop.name ] = prop; // allow lookup by name - } - - // because the pie properties are numbered, give access to a constant N (for renderer use) - $$.style.pieBackgroundN = 16; - })(); - - // adds the default stylesheet to the current style - $$.styfn.addDefaultStylesheet = function(){ - // to be nice, we build font related style properties from the core container - // so that cytoscape matches the style of its container by default - // - // unfortunately, this doesn't seem work consistently and can grab the default stylesheet values - // instead of the developer's values so let's just make it explicit for the dev for now - // - // delaying the read of these val's is not an opt'n: that would delay init'l load time - var fontFamily = "Helvetica" || this.containerPropertyAsString("font-family") || "sans-serif"; - var fontStyle = "normal" || this.containerPropertyAsString("font-style") || "normal"; - var fontVariant = "normal" || this.containerPropertyAsString("font-variant") || "normal"; - var fontWeight = "normal" || this.containerPropertyAsString("font-weight") || "normal"; - var color = "#000" || this.containerPropertyAsString("color") || "#000"; - var textTransform = "none" || this.containerPropertyAsString("text-transform") || "none"; - var textDecoration = "none" || this.containerPropertyAsString("text-decoration") || "none"; - var fontSize = 16 || this.containerPropertyAsString("font-size") || 16; - - // fill the style with the default stylesheet - this - .selector("node, edge") // common properties - .css({ - "cursor": "default", - "text-valign": "top", - "text-halign": "center", - "color": color, - "text-outline-color": "#000", - "text-outline-width": 0, - "text-outline-opacity": 1, - "text-opacity": 1, - "text-decoration": "none", - "text-transform": textTransform, - "font-family": fontFamily, - "font-style": fontStyle, - "font-variant": fontVariant, - "font-weight": fontWeight, - "font-size": fontSize, - "min-zoomed-font-size": 0, - "visibility": "visible", - "display": "element", - "opacity": 1, - "z-index": 0, - "content": "", - "overlay-opacity": 0, - "overlay-color": "#000", - "overlay-padding": 10, - - // node props - "background-color": "#888", - "background-opacity": 1, - "background-image": "none", - "border-color": "#000", - "border-opacity": 1, - "border-width": 0, - "border-style": "solid", - "height": 30, - "width": 30, - "padding-top": 0, - "padding-bottom": 0, - "padding-left": 0, - "padding-right": 0, - "shape": "ellipse", - "pie-1-background-color": "black", - "pie-1-background-size": "0%", - "pie-2-background-color": "black", - "pie-2-background-size": "0%", - "pie-3-background-color": "black", - "pie-3-background-size": "0%", - "pie-4-background-color": "black", - "pie-4-background-size": "0%", - "pie-5-background-color": "black", - "pie-5-background-size": "0%", - "pie-6-background-color": "black", - "pie-6-background-size": "0%", - "pie-7-background-color": "black", - "pie-7-background-size": "0%", - "pie-8-background-color": "black", - "pie-8-background-size": "0%", - "pie-9-background-color": "black", - "pie-9-background-size": "0%", - "pie-10-background-color": "black", - "pie-10-background-size": "0%", - "pie-11-background-color": "black", - "pie-11-background-size": "0%", - "pie-12-background-color": "black", - "pie-12-background-size": "0%", - "pie-13-background-color": "black", - "pie-13-background-size": "0%", - "pie-14-background-color": "black", - "pie-14-background-size": "0%", - "pie-15-background-color": "black", - "pie-15-background-size": "0%", - "pie-16-background-color": "black", - "pie-16-background-size": "0%", - - // edge props - "source-arrow-shape": "none", - "target-arrow-shape": "none", - "source-arrow-color": "#bbb", - "target-arrow-color": "#bbb", - "line-style": "solid", - "line-color": "#bbb", - "control-point-step-size": 40, - "curve-style": "bezier" - }) - .selector("$node > node") // compound (parent) node properties - .css({ - "width": "auto", - "height": "auto", - "shape": "rectangle", - "background-opacity": 0.5, - "padding-top": 10, - "padding-right": 10, - "padding-left": 10, - "padding-bottom": 10 - }) - .selector("edge") // just edge properties - .css({ - "width": 1, - }) - .selector(":active") - .css({ - "overlay-color": "black", - "overlay-padding": 10, - "overlay-opacity": 0.25 - }) - .selector("core") // just core properties - .css({ - "selection-box-color": "#ddd", - "selection-box-opacity": 0.65, - "selection-box-border-color": "#aaa", - "selection-box-border-width": 1, - "panning-cursor": "grabbing", - "active-bg-color": "black", - "active-bg-opacity": 0.15, - "active-bg-size": isTouch ? 40 : 15 - }) - ; - }; - - // remove all contexts - $$.styfn.clear = function(){ - this._private.newStyle = true; - - for( var i = 0; i < this.length; i++ ){ - delete this[i]; - } - this.length = 0; - - return this; // chaining - }; - - $$.styfn.resetToDefault = function(){ - this.clear(); - this.addDefaultStylesheet(); - - return this; - }; - - // builds a style object for the "core" selector - $$.styfn.core = function(){ - return this._private.coreStyle; - }; - - // parse a property; return null on invalid; return parsed property otherwise - // fields : - // - name : the name of the property - // - value : the parsed, native-typed value of the property - // - strValue : a string value that represents the property value in valid css - // - bypass : true iff the property is a bypass property - $$.styfn.parse = function( name, value, propIsBypass ){ - - name = $$.util.camel2dash( name ); // make sure the property name is in dash form (e.g. "property-name" not "propertyName") - var property = $$.style.properties[ name ]; - var passedValue = value; - - if( !property ){ return null; } // return null on property of unknown name - if( value === undefined || value === null ){ return null; } // can't assign null - - var valueIsString = $$.is.string(value); - if( valueIsString ){ // trim the value to make parsing easier - value = $$.util.trim( value ); - } - - var type = property.type; - if( !type ){ return null; } // no type, no luck - - // check if bypass is null or empty string (i.e. indication to delete bypass property) - if( propIsBypass && (value === "" || value === null) ){ - return { - name: name, - value: value, - bypass: true, - deleteBypass: true - }; - } - - // check if value is mapped - var data, mapData, layoutData, mapLayoutData; - if( !valueIsString ){ - // then don't bother to do the expensive regex checks - - } else if( - ( data = new RegExp( $$.style.types.data.regex ).exec( value ) ) || - ( layoutData = new RegExp( $$.style.types.layoutData.regex ).exec( value ) ) - ){ - var isLayout = layoutData !== undefined; - data = data || layoutData; - - return { - name: name, - value: data, - strValue: value, - mapped: isLayout ? $$.style.types.layoutData : $$.style.types.data, - field: data[1], - bypass: propIsBypass - }; - - } else if( - ( mapData = new RegExp( $$.style.types.mapData.regex ).exec( value ) ) || - ( mapLayoutData = new RegExp( $$.style.types.mapLayoutData.regex ).exec( value ) ) - ){ - var isLayout = mapLayoutData !== undefined; - mapData = mapData || mapLayoutData; - - // we can map only if the type is a colour or a number - if( !(type.color || type.number) ){ return false; } - - var valueMin = this.parse( name, mapData[4]); // parse to validate - if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped - - var valueMax = this.parse( name, mapData[5]); // parse to validate - if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped - - // check if valueMin and valueMax are the same - if( valueMin.value === valueMax.value ){ - return false; // can't make much of a mapper without a range - - } else if( type.color ){ - var c1 = valueMin.value; - var c2 = valueMax.value; - - var same = c1[0] === c2[0] // red - && c1[1] === c2[1] // green - && c1[2] === c2[2] // blue - && ( // optional alpha - c1[3] === c2[3] // same alpha outright - || ( - (c1[3] == null || c1[3] === 1) // full opacity for colour 1? - && - (c2[3] == null || c2[3] === 1) // full opacity for colour 2? - ) - ) - ; - - if( same ){ return false; } // can't make a mapper without a range - } - - return { - name: name, - value: mapData, - strValue: value, - mapped: isLayout ? $$.style.types.mapLayoutData : $$.style.types.mapData, - field: mapData[1], - fieldMin: parseFloat( mapData[2] ), // min & max are numeric - fieldMax: parseFloat( mapData[3] ), - valueMin: valueMin.value, - valueMax: valueMax.value, - bypass: propIsBypass - }; - } - - // check the type and return the appropriate object - if( type.number ){ - var units; - var implicitUnit = "px"; // not set => px - - if( type.units ){ // use specified units if set - units = type.units; - } - - if( !type.unitless ){ - if( valueIsString ){ - var unitsRegex = "px|em" + (type.allowPercent ? "|\\%" : ""); - if( units ){ unitsRegex = units; } // only allow explicit units if so set - var match = value.match( "^(" + $$.util.regex.number + ")(" + unitsRegex + ")?" + "$" ); - - if( match ){ - value = match[1]; - units = match[2] || implicitUnit; - } - - } else if( !units ) { - units = implicitUnit; // implicitly px if unspecified - } - } - - value = parseFloat( value ); - - // if not a number and enums not allowed, then the value is invalid - if( isNaN(value) && type.enums === undefined ){ - return null; - } - - // check if this number type also accepts special keywords in place of numbers - // (i.e. `left`, `auto`, etc) - if( isNaN(value) && type.enums !== undefined ){ - value = passedValue; - - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - return null; // failed on enum after failing on number - } - - // check if value must be an integer - if( type.integer && !$$.is.integer(value) ){ - return null; - } - - // check value is within range - if( (type.min !== undefined && value < type.min) - || (type.max !== undefined && value > type.max) - ){ - return null; - } - - var ret = { - name: name, - value: value, - strValue: "" + value + (units ? units : ""), - units: units, - bypass: propIsBypass, - pxValue: type.unitless || units === "%" ? - undefined - : - ( units === "px" || !units ? (value) : (this.getEmSizeInPixels() * value) ) - }; - - return ret; - - } else if( type.color ){ - var tuple = $$.util.color2tuple( value ); - - return { - name: name, - value: tuple, - strValue: value, - bypass: propIsBypass - }; - - } else if( type.enums ){ - for( var i = 0; i < type.enums.length; i++ ){ - var en = type.enums[i]; - - if( en === value ){ - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - } - } - - } else if( type.regex ){ - var regex = new RegExp( type.regex ); // make a regex from the type - var m = regex.exec( value ); - - if( m ){ // regex matches - return { - name: name, - value: m, - strValue: value, - bypass: propIsBypass - }; - } else { // regex doesn't match - return null; // didn't match the regex so the value is bogus - } - - } else if( type.string ){ - // just return - return { - name: name, - value: value, - strValue: value, - bypass: propIsBypass - }; - - } else { - return null; // not a type we can handle - } - - }; - - // gets what an em size corresponds to in pixels relative to a dom element - $$.styfn.getEmSizeInPixels = function(){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement && window.getComputedStyle ){ - var pxAsStr = window.getComputedStyle(domElement).getPropertyValue("font-size"); - var px = parseFloat( pxAsStr ); - return px; - } else { - return 1; // in case we're running outside of the browser - } - }; - - // gets css property from the core container - $$.styfn.containerCss = function( propName ){ - var cy = this._private.cy; - var domElement = cy.container(); - - if( window && domElement && window.getComputedStyle ){ - return window.getComputedStyle(domElement).getPropertyValue( propName ); - } - }; - - $$.styfn.containerProperty = function( propName ){ - var propStr = this.containerCss( propName ); - var prop = this.parse( propName, propStr ); - return prop; - }; - - $$.styfn.containerPropertyAsString = function( propName ){ - var prop = this.containerProperty( propName ); - - if( prop ){ - return prop.strValue; - } - }; - - // create a new context from the specified selector string and switch to that context - $$.styfn.selector = function( selectorStr ){ - // "core" is a special case and does not need a selector - var selector = selectorStr === "core" ? null : new $$.Selector( selectorStr ); - - var i = this.length++; // new context means new index - this[i] = { - selector: selector, - properties: [] - }; - - return this; // chaining - }; - - // add one or many css rules to the current context - $$.styfn.css = function(){ - var args = arguments; - - switch( args.length ){ - case 1: - var map = args[0]; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var mapVal = map[ prop.name ]; - - if( mapVal === undefined ){ - mapVal = map[ $$.util.dash2camel(prop.name) ]; - } - - if( mapVal !== undefined ){ - this.cssRule( prop.name, mapVal ); - } - } - - break; - - case 2: - this.cssRule( args[0], args[1] ); - break; - - default: - break; // do nothing if args are invalid - } - - return this; // chaining - }; - - // add a single css rule to the current context - $$.styfn.cssRule = function( name, value ){ - // name-value pair - var property = this.parse( name, value ); - - // add property to current context if valid - if( property ){ - var i = this.length - 1; - this[i].properties.push( property ); - - // add to core style if necessary - var currentSelectorIsCore = !this[i].selector; - if( currentSelectorIsCore ){ - this._private.coreStyle[ property.name ] = property; - } - } - - return this; // chaining - }; - - // apply a property to the style (for internal use) - // returns whether application was successful - // - // now, this function flattens the property, and here's how: - // - // for parsedProp:{ bypass: true, deleteBypass: true } - // no property is generated, instead the bypass property in the - // element's style is replaced by what's pointed to by the `bypassed` - // field in the bypass property (i.e. restoring the property the - // bypass was overriding) - // - // for parsedProp:{ mapped: truthy } - // the generated flattenedProp:{ mapping: prop } - // - // for parsedProp:{ bypass: true } - // the generated flattenedProp:{ bypassed: parsedProp } - $$.styfn.applyParsedProperty = function( ele, parsedProp, context ){ - parsedProp = $$.util.clone( parsedProp ); // copy b/c the same parsedProp may be applied to many elements, BUT - // the instances put in each element should be unique to avoid overwriting other the lists of other elements - - var prop = parsedProp; - var style = ele._private.style; - var fieldVal, flatProp; - var type = $$.style.properties[ prop.name ].type; - var propIsBypass = prop.bypass; - var origProp = style[ prop.name ]; - var origPropIsBypass = origProp && origProp.bypass; - - // can't apply auto to width or height unless it's a parent node - if( (parsedProp.name === "height" || parsedProp.name === "width") && parsedProp.value === "auto" && ele.isNode() && !ele.isParent() ){ - return false; - } - - // check if we need to delete the current bypass - if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete - var currentProp = style[ prop.name ]; - - // can only delete if the current prop is a bypass and it points to the property it was overriding - if( !currentProp ){ - return true; // property is already not defined - } else if( currentProp.bypass && currentProp.bypassed ){ // then replace the bypass property with the original - - // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary) - style[ prop.name ] = currentProp.bypassed; - return true; - - } else { - return false; // we're unsuccessful deleting the bypass - } - } - - // put the property in the style objects - switch( prop.mapped ){ // flatten the property if mapped - case $$.style.types.mapData: - case $$.style.types.mapLayoutData: - - var isLayout = prop.mapped === $$.style.types.mapLayoutData; - - // flatten the field (e.g. data.foo.bar) - var fields = prop.field.split("."); - var fieldVal = isLayout ? ele._private.layoutData : ele._private.data; - for( var i = 0; i < fields.length && fieldVal; i++ ){ - var field = fields[i]; - fieldVal = fieldVal[ field ]; - } - - if( !$$.is.number(fieldVal) ){ return false; } // it had better be a number - - var percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin); - - if( type.color ){ - var r1 = prop.valueMin[0]; - var r2 = prop.valueMax[0]; - var g1 = prop.valueMin[1]; - var g2 = prop.valueMax[1]; - var b1 = prop.valueMin[2]; - var b2 = prop.valueMax[2]; - var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3]; - var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3]; - - var clr = [ - Math.round( r1 + (r2 - r1)*percent ), - Math.round( g1 + (g2 - g1)*percent ), - Math.round( b1 + (b2 - b1)*percent ), - Math.round( a1 + (a2 - a1)*percent ) - ]; - - flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing - bypass: prop.bypass, // we're a bypass if the mapping property is a bypass - name: prop.name, - value: clr, - strValue: [ "rgba(", clr[0], ", ", clr[1], ", ", clr[2], ", ", clr[3] , ")" ].join("") // fake it til you make it - }; - - } else if( type.number ){ - var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent; - flatProp = this.parse( prop.name, calcValue, prop.bypass ); - - } else { - return false; // can only map to colours and numbers - } - - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - - break; - - // direct mapping - case $$.style.types.data: - case $$.style.types.layoutData: - - var isLayout = prop.mapped === $$.style.types.layoutData; - - // flatten the field (e.g. data.foo.bar) - var fields = prop.field.split("."); - var fieldVal = isLayout ? ele._private.layoutData : ele._private.data; - for( var i = 0; i < fields.length && fieldVal; i++ ){ - var field = fields[i]; - fieldVal = fieldVal[ field ]; - } - - flatProp = this.parse( prop.name, fieldVal, prop.bypass ); - if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself - flatProp = this.parse( prop.name, origProp.strValue, prop.bypass); - } - - flatProp.mapping = prop; // keep a reference to the mapping - prop = flatProp; // the flattened (mapped) property is the one we want - break; - - case undefined: - break; // just set the property - - default: - return false; // not a valid mapping - } - - // if the property is a bypass property, then link the resultant property to the original one - if( propIsBypass ){ - if( origPropIsBypass ){ // then this bypass overrides the existing one - prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass - } else { // then link the orig prop to the new bypass - prop.bypassed = origProp; - } - - style[ prop.name ] = prop; // and set - - } else { // prop is not bypass - var prevProp; - - if( origPropIsBypass ){ // then keep the orig prop (since it's a bypass) and link to the new prop - prevProp = origProp.bypassed; - - origProp.bypassed = prop; - } else { // then just replace the old prop with the new one - prevProp = style[ prop.name ]; - - style[ prop.name ] = prop; - } - - if( prevProp && prevProp.mapping && prop.mapping && prevProp.context === context ){ - prevProp = prevProp.prev; - } - - if( prevProp && prevProp !== prop ){ - prop.prev = prevProp; - } - } - - prop.context = context; - - return true; - }; - - $$.styfn.rollBackContext = function( ele, context ){ - for( var j = 0; j < context.properties.length; j++ ){ // for each prop - var prop = context.properties[j]; - var eleProp = ele._private.style[ prop.name ]; - - // because bypasses do not store prevs, look at the bypassed property - if( eleProp.bypassed ){ - eleProp = eleProp.bypassed; - } - - var first = true; - var lastEleProp; - var l = 0; - while( eleProp.prev ){ - var prev = eleProp.prev; - - if( eleProp.context === context ){ - - if( first ){ - ele._private.style[ prop.name ] = prev; - } else if( lastEleProp ){ - lastEleProp.prev = prev; - } - - } - - lastEleProp = eleProp; - eleProp = prev; - first = false; - l++; - - // in case we have a problematic prev list - // if( l >= 100 ){ - // debugger; - // } - } - } - }; - - - // (potentially expensive calculation) - // apply the style to the element based on - // - its bypass - // - what selectors match it - $$.styfn.apply = function( eles ){ - var self = this; - - for( var ie = 0; ie < eles.length; ie++ ){ - var ele = eles[ie]; - - if( self._private.newStyle ){ - ele._private.styleCxts = []; - ele._private.style = {}; - } - - // console.log('APPLYING STYLESHEET\n--\n'); - - // apply the styles - for( var i = 0; i < this.length; i++ ){ - var context = this[i]; - var contextSelectorMatches = context.selector && context.selector.filter( ele ).length > 0; // NB: context.selector may be null for "core" - var props = context.properties; - - // console.log(i + ' : looking at selector: ' + context.selector); - - if( contextSelectorMatches ){ // then apply its properties - - // apply the properties in the context - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - var newCxt = !ele._private.styleCxts[i]; - var currentEleProp = ele._private.style[prop.name]; - var propIsFirstInEle = currentEleProp && currentEleProp.context === context; - var needToUpdateCxtMapping = prop.mapped && propIsFirstInEle; - - //if(prop.mapped) debugger; - - if( newCxt || needToUpdateCxtMapping ){ - // console.log(i + ' + MATCH: applying property: ' + prop.name); - this.applyParsedProperty( ele, prop, context ); - } - } - - // keep a note that this context matches - ele._private.styleCxts[i] = context; - } else { - - // roll back style cxts that don't match now - if( ele._private.styleCxts[i] ){ - // console.log(i + ' x MISS: rolling back context'); - this.rollBackContext( ele, context ); - } - - delete ele._private.styleCxts[i]; - } - } // for context - - } // for elements - - self._private.newStyle = false; - }; - - // updates the visual style for all elements (useful for manual style modification after init) - $$.styfn.update = function(){ - var cy = this._private.cy; - var eles = cy.elements(); - - eles.updateStyle(); - }; - - // gets the rendered style for an element - $$.styfn.getRenderedStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - var cy = this._private.cy; - var zoom = cy.zoom(); - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - var val = styleProp.unitless ? styleProp.strValue : (styleProp.pxValue * zoom) + "px"; - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - - return rstyle; - } - }; - - // gets the raw style for an element - $$.styfn.getRawStyle = function( ele ){ - var ele = ele[0]; // insure it's an element - - if( ele ){ - var rstyle = {}; - var style = ele._private.style; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ]; - - if( styleProp ){ - rstyle[ prop.name ] = styleProp.strValue; - rstyle[ $$.util.dash2camel(prop.name) ] = styleProp.strValue; - } - } - - return rstyle; - } - }; - - // gets the value style for an element (useful for things like animations) - $$.styfn.getValueStyle = function( ele ){ - var rstyle, style; - - if( $$.is.element(ele) ){ - rstyle = {}; - style = ele._private.style; - } else { - rstyle = {}; - style = ele; // just passed the style itself - } - - if( style ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var styleProp = style[ prop.name ] || style[ $$.util.dash2camel(prop.name) ]; - - if( styleProp !== undefined && !$$.is.plainObject( styleProp ) ){ // then make a prop of it - styleProp = this.parse(prop.name, styleProp); - } - - if( styleProp ){ - var val = styleProp.value === undefined ? styleProp : styleProp.value; - - rstyle[ prop.name ] = val; - rstyle[ $$.util.dash2camel(prop.name) ] = val; - } - } - } - - return rstyle; - }; - - // just update the functional properties (i.e. mappings) in the elements' - // styles (less expensive than recalculation) - $$.styfn.updateMappers = function( eles ){ - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - var style = ele._private.style; - - for( var j = 0; j < $$.style.properties.length; j++ ){ // for each prop - var prop = $$.style.properties[j]; - var propInStyle = style[ prop.name ]; - - if( propInStyle && propInStyle.mapping ){ - var mapping = propInStyle.mapping; - this.applyParsedProperty( ele, mapping ); // reapply the mapping property - } - } - } - }; - - // bypasses are applied to an existing style on an element, and just tacked on temporarily - // returns true iff application was successful for at least 1 specified property - $$.styfn.applyBypass = function( eles, name, value ){ - var props = []; - - // put all the properties (can specify one or many) in an array after parsing them - if( name === "*" || name === "**" ){ // apply to all property names - - if( value !== undefined ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - - } else if( $$.is.string(name) ){ // then parse the single property - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } else if( $$.is.plainObject(name) ){ // then parse each property - var specifiedProps = name; - - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = specifiedProps[ name ]; - - if( value === undefined ){ // try camel case name too - value = specifiedProps[ $$.util.dash2camel(name) ]; - } - - if( value !== undefined ){ - var parsedProp = this.parse(name, value, true); - - if( parsedProp ){ - props.push( parsedProp ); - } - } - } - } else { // can't do anything without well defined properties - return false; - } - - // we've failed if there are no valid properties - if( props.length === 0 ){ return false; } - - // now, apply the bypass properties on the elements - var ret = false; // return true if at least one succesful bypass applied - for( var i = 0; i < eles.length; i++ ){ // for each ele - var ele = eles[i]; - - for( var j = 0; j < props.length; j++ ){ // for each prop - var prop = props[j]; - - ret = this.applyParsedProperty( ele, prop ) || ret; - } - } - - return ret; - }; - - $$.styfn.removeAllBypasses = function( eles ){ - for( var i = 0; i < $$.style.properties.length; i++ ){ - var prop = $$.style.properties[i]; - var name = prop.name; - var value = ""; // empty => remove bypass - - var parsedProp = this.parse(name, value, true); - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - this.applyParsedProperty(ele, parsedProp); - } - } - }; - - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$, window){ "use strict"; - - var isTouch = $$.is.touch(); - - var defaults = { - hideEdgesOnViewport: false - }; - - var origDefaults = $$.util.copy( defaults ); - - $$.defaults = function( opts ){ - defaults = $$.util.extend({}, origDefaults, opts); - }; - - $$.fn.core = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - $$.Core.prototype[ name ] = fn; - } - }; - - $$.Core = function( opts ){ - if( !(this instanceof $$.Core) ){ - return new $$.Core(opts); - } - var cy = this; - - opts = $$.util.extend({}, defaults, opts); - - var container = opts.container; - var reg = $$.getRegistrationForInstance(cy, container); - if( reg && reg.cy ){ - reg.domElement.innerHTML = ''; - reg.cy.notify({ type: 'destroy' }); // destroy the renderer - - $$.removeRegistrationForInstance(reg.cy, reg.domElement); - } - - reg = $$.registerInstance( cy, container ); - var readies = reg.readies; - - var options = opts; - options.layout = $$.util.extend( { name: window && container ? "grid" : "null" }, options.layout ); - options.renderer = $$.util.extend( { name: window && container ? "canvas" : "null" }, options.renderer ); - - // TODO determine whether we need a check like this even though we allow running headless now - // - // if( !$$.is.domElement(options.container) ){ - // $$.util.error("Cytoscape.js must be called on an element"); - // return; - // } - - var _p = this._private = { - ready: false, // whether ready has been triggered - initrender: false, // has initrender has been triggered - instanceId: reg.id, // the registered instance id - options: options, // cached options - elements: [], // array of elements - id2index: {}, // element id => index in elements array - listeners: [], // list of listeners - aniEles: [], // array of elements being animated - scratch: {}, // scratch object for core - layout: null, - renderer: null, - notificationsEnabled: true, // whether notifications are sent to the renderer - minZoom: 1e-50, - maxZoom: 1e50, - zoomingEnabled: options.zoomingEnabled === undefined ? true : options.zoomingEnabled, - userZoomingEnabled: options.userZoomingEnabled === undefined ? true : options.userZoomingEnabled, - panningEnabled: options.panningEnabled === undefined ? true : options.panningEnabled, - userPanningEnabled: options.userPanningEnabled === undefined ? true : options.userPanningEnabled, - boxSelectionEnabled: options.boxSelectionEnabled === undefined ? true : options.boxSelectionEnabled, - zoom: $$.is.number(options.zoom) ? options.zoom : 1, - pan: { - x: $$.is.plainObject(options.pan) && $$.is.number(options.pan.x) ? options.pan.x : 0, - y: $$.is.plainObject(options.pan) && $$.is.number(options.pan.y) ? options.pan.y : 0, - }, - hasCompoundNodes: false - }; - - // set selection type - var selType = options.selectionType; - if( selType === undefined || (selType !== "additive" && selType !== "single") ){ - // then set default - - if( isTouch ){ - _p.selectionType = "additive"; - } else { - _p.selectionType = "single"; - } - } else { - _p.selectionType = selType; - } - - // init zoom bounds - if( $$.is.number(options.minZoom) && $$.is.number(options.maxZoom) && options.minZoom < options.maxZoom ){ - _p.minZoom = options.minZoom; - _p.maxZoom = options.maxZoom; - } else if( $$.is.number(options.minZoom) && options.maxZoom === undefined ){ - _p.minZoom = options.minZoom; - } else if( $$.is.number(options.maxZoom) && options.minZoom === undefined ){ - _p.maxZoom = options.maxZoom; - } - - // init style - - if( $$.is.stylesheet(options.style) ){ - _p.style = options.style.generateStyle(this); - } else if( $$.is.array(options.style) ) { - _p.style = $$.style.fromJson(this, options.style); - } else if( $$.is.string(options.style) ){ - _p.style = $$.style.fromString(this, options.style); - } else { - _p.style = new $$.Style( cy ); - } - - // create the renderer - cy.initRenderer( $$.util.extend({ - hideEdgesOnViewport: options.hideEdgesOnViewport - }, options.renderer) ); - - // trigger the passed function for the `initrender` event - if( options.initrender ){ - cy.on('initrender', options.initrender); - cy.on('initrender', function(){ - cy._private.initrender = true; - }); - } - - // initial load - cy.load(options.elements, function(){ // onready - cy.startAnimationLoop(); - cy._private.ready = true; - - // if a ready callback is specified as an option, the bind it - if( $$.is.fn( options.ready ) ){ - cy.bind("ready", options.ready); - } - - // bind all the ready handlers registered before creating this instance - for( var i = 0; i < readies.length; i++ ){ - var fn = readies[i]; - cy.bind("ready", fn); - } - reg.readies = []; // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc - - cy.trigger("ready"); - }, options.done); - }; - - $$.corefn = $$.Core.prototype; // short alias - - - $$.fn.core({ - ready: function(){ - return this._private.ready; - }, - - initrender: function(){ - return this._private.initrender; - }, - - registered: function(){ - if( this._private && this._private.instanceId != null ){ - return true; - } else { - return false; - } - }, - - registeredId: function(){ - return this._private.instanceId; - }, - - getElementById: function( id ){ - var index = this._private.id2index[ id ]; - if( index !== undefined ){ - return this._private.elements[ index ]; - } - - // worst case, return an empty collection - return new $$.Collection( this ); - }, - - selectionType: function(){ - return this._private.selectionType; - }, - - hasCompoundNodes: function(){ - return this._private.hasCompoundNodes; - }, - - addToPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var alreadyInPool = index !== undefined; - - if( !alreadyInPool ){ - index = elements.length; - elements.push( ele ) - id2index[ id ] = index; - ele._private.index = index; - } - } - - return this; // chaining - }, - - removeFromPool: function( eles ){ - var elements = this._private.elements; - var id2index = this._private.id2index; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - var id = ele._private.data.id; - var index = id2index[ id ]; - var inPool = index !== undefined; - - if( inPool ){ - delete this._private.id2index[ id ]; - elements.splice(index, 1); - - // adjust the index of all elements past this index - for( var j = index; j < elements.length; j++ ){ - var jid = elements[j]._private.data.id; - id2index[ jid ]--; - } - } - } - }, - - container: function(){ - return this._private.options.container; - }, - - options: function(){ - return $$.util.copy( this._private.options ); - }, - - json: function(params){ - var json = {}; - var cy = this; - - json.elements = {}; - cy.elements().each(function(i, ele){ - var group = ele.group(); - - if( !json.elements[group] ){ - json.elements[group] = []; - } - - json.elements[group].push( ele.json() ); - }); - - json.style = cy.style().json(); - json.scratch = cy.scratch(); - json.zoomingEnabled = cy._private.zoomingEnabled; - json.userZoomingEnabled = cy._private.userZoomingEnabled; - json.zoom = cy._private.zoom; - json.minZoom = cy._private.minZoom; - json.maxZoom = cy._private.maxZoom; - json.panningEnabled = cy._private.panningEnabled; - json.userPanningEnabled = cy._private.userPanningEnabled; - json.pan = cy._private.pan; - json.boxSelectionEnabled = cy._private.boxSelectionEnabled; - json.layout = cy._private.options.layout; - json.renderer = cy._private.options.renderer; - json.hideEdgesOnViewport = cy._private.options.hideEdgesOnViewport; - - return json; - } - - }); - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -(function($$, window){ "use strict"; - - function ready(f) { - var fn = ( document && (document.readyState === 'interactive' || document.readyState === 'complete') ) ? f : ready; - - setTimeout(fn, 9, f); - } - - $$.fn.core({ - add: function(opts){ - - var elements; - var cy = this; - - // add the elements - if( $$.is.elementOrCollection(opts) ){ - var eles = opts; - - if( eles._private.cy === cy ){ // same instance => just restore - elements = eles.restore(); - - } else { // otherwise, copy from json - var jsons = []; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - jsons.push( ele.json() ); - } - - elements = new $$.Collection( cy, jsons ); - } - } - - // specify an array of options - else if( $$.is.array(opts) ){ - var jsons = opts; - - elements = new $$.Collection(cy, jsons); - } - - // specify via opts.nodes and opts.edges - else if( $$.is.plainObject(opts) && ($$.is.array(opts.nodes) || $$.is.array(opts.edges)) ){ - var elesByGroup = opts; - var jsons = []; - - var grs = ["nodes", "edges"]; - for( var i = 0, il = grs.length; i < il; i++ ){ - var group = grs[i]; - var elesArray = elesByGroup[group]; - - if( $$.is.array(elesArray) ){ - - for( var j = 0, jl = elesArray.length; j < jl; j++ ){ - var json = elesArray[j]; - - var mjson = $$.util.extend({}, json, { group: group }); - jsons.push( mjson ); - } - } - } - - elements = new $$.Collection(cy, jsons); - } - - // specify options for one element - else { - var json = opts; - elements = (new $$.Element( cy, json )).collection(); - } - - return elements; - }, - - remove: function(collection){ - if( $$.is.elementOrCollection(collection) ){ - collection = collection; - } else if( $$.is.string(collection) ){ - var selector = collection; - collection = this.$( selector ); - } - - return collection.remove(); - }, - - load: function(elements, onload, ondone){ - var cy = this; - - // remove old elements - var oldEles = cy.elements(); - if( oldEles.length > 0 ){ - oldEles.remove(); - } - - cy.notifications(false); - - if( elements != null ){ - if( $$.is.plainObject(elements) || $$.is.array(elements) ){ - cy.add( elements ); - } - } - - function callback(){ - cy.one("layoutready", function(e){ - cy.notifications(true); - cy.trigger(e); // we missed this event by turning notifications off, so pass it on - - cy.notify({ - type: "load", - collection: cy.elements() - }); - - cy.one("load", onload); - cy.trigger("load"); - }).one("layoutstop", function(){ - cy.one("done", ondone); - cy.trigger("done"); - }); - - cy.layout( cy._private.options.layout ); - - } - - if( window ){ - ready( callback ); - } else { - callback(); - } - - return this; - } - }); - -})( cytoscape, typeof window === 'undefined' ? null : window ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - addToAnimationPool: function( eles ){ - var cy = this; - var aniEles = cy._private.aniEles; - var aniElesHas = []; - - for( var i = 0; i < aniEles.length; i++ ){ - var id = aniEles[i]._private.data.id; - aniElesHas[ id ] = true; - } - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var id = ele._private.data.id; - - if( !aniElesHas[id] ){ - aniEles.push( ele ); - } - } - }, - - startAnimationLoop: function(){ - var cy = this; - var stepDelay = 1000/60; - var useTimeout = false; - var useRequestAnimationFrame = true; - - // initialise the list - cy._private.aniEles = []; - - // TODO change this when standardised - var requestAnimationFrame = typeof window === 'undefined' ? function(){} : ( window.requestAnimationFrame || window.mozRequestAnimationFrame || - window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ); - - if( requestAnimationFrame == null || !useRequestAnimationFrame ){ - requestAnimationFrame = function(fn){ - window.setTimeout(function(){ - fn(+new Date); - }, stepDelay); - }; - } - - var containerDom = cy.container(); - - function globalAnimationStep(){ - function exec(){ - requestAnimationFrame(function(now){ - handleElements(now); - globalAnimationStep(); - }, containerDom); - } - - if( useTimeout ){ - setTimeout(function(){ - exec(); - }, stepDelay); - } else { - exec(); - } - } - - globalAnimationStep(); // first call - - function handleElements(now){ - now = +new Date; - - var eles = cy._private.aniEles; - for( var e = 0; e < eles.length; e++ ){ - var ele = eles[e]; - - // we might have errors if we edit animation.queue and animation.current - // for ele (i.e. by stopping) - // try{ - - var current = ele._private.animation.current; - var queue = ele._private.animation.queue; - - // if nothing currently animating, get something from the queue - if( current.length === 0 ){ - var q = queue; - var next = q.length > 0 ? q.shift() : null; - - if( next != null ){ - next.callTime = +new Date; // was queued, so update call time - current.push( next ); - } - } - - // step and remove if done - var completes = []; - for(var i = 0; i < current.length; i++){ - var ani = current[i]; - step( ele, ani, now ); - - if( current[i].done ){ - completes.push( ani ); - - // remove current[i] - current.splice(i, 1); - i--; - } - } - - // call complete callbacks - for( var i = 0; i < completes.length; i++ ){ - var ani = completes[i]; - var complete = ani.params.complete; - - if( $$.is.fn(complete) ){ - complete.apply( ele, [ now ] ); - } - } - - // } catch(e){ - // // do nothing - // } - - } // each element - - - // notify renderer - if( eles.length > 0 ){ - cy.notify({ - type: "draw", - collection: eles - }); - } - - // remove elements from list of currently animating if its queues are empty - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var queue = ele._private.animation.queue; - var current = ele._private.animation.current; - var keepEle = current.length > 0 || queue.length > 0; - - if( !keepEle ){ // then remove from the array - eles.splice(i, 1); - i--; - } - } - - } // handleElements - - function step( self, animation, now ){ - var style = cy._private.style; - var properties = animation.properties; - var params = animation.params; - var startTime = animation.callTime; - var percent; - - if( animation.duration === 0 ){ - percent = 1; - } else { - percent = Math.min(1, (now - startTime)/animation.duration); - } - - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( properties.delay == null ){ // then update the position - var startPos = animation.startPosition; - var endPos = properties.position; - var pos = self._private.position; - if( endPos ){ - if( valid( startPos.x, endPos.x ) ){ - pos.x = ease( startPos.x, endPos.x, percent ); - } - - if( valid( startPos.y, endPos.y ) ){ - pos.y = ease( startPos.y, endPos.y, percent ); - } - } - - if( properties.css ){ - var props = $$.style.properties; - for( var i = 0; i < props.length; i++ ){ - var name = props[i].name; - var end = properties.css[ name ]; - - if( end !== undefined ){ - var start = animation.startStyle[ name ]; - var easedVal = ease( start, end, percent ); - - style.applyBypass( self, name, easedVal ); - } - } // for props - } // if - } - - if( $$.is.fn(params.step) ){ - params.step.apply( self, [ now ] ); - } - - if( percent >= 1 ){ - animation.done = true; - } - - return percent; - } - - function valid(start, end){ - if( start == null || end == null ){ - return false; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return true; - } else if( (start) && (end) ){ - return true; - } - - return false; - } - - function ease(start, end, percent){ - if( percent < 0 ){ - percent = 0; - } else if( percent > 1 ){ - percent = 1; - } - - if( $$.is.number(start) && $$.is.number(end) ){ - return start + (end - start) * percent; - - } else if( $$.is.number(start[0]) && $$.is.number(end[0]) ){ // then assume a colour - var c1 = start; - var c2 = end; - - var ch = function(ch1, ch2){ - var diff = ch2 - ch1; - var min = ch1; - return Math.round( percent * diff + min ); - }; - - var r = ch( c1[0], c2[0] ); - var g = ch( c1[1], c2[1] ); - var b = ch( c1[2], c2[2] ); - - return 'rgb(' + r + ', ' + g + ', ' + b + ')'; - } - - return undefined; - } - - } - - }); - -})( cytoscape ); - - - - - -;(function($$){ "use strict"; - - $$.fn.core({ - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - }); - - // aliases for those folks who like old stuff: - $$.corefn.bind = $$.corefn.on; - $$.corefn.unbind = $$.corefn.off; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - png: function( options ){ - var cy = this; - var renderer = this._private.renderer; - options = options || {}; - - return renderer.png( options ); - } - - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - layout: function( params ){ - var cy = this; - - if( this._private.layoutRunning ){ // don't run another layout if one's already going - return this; - } - - // if no params, use the previous ones - if( params == null ){ - params = this._private.options.layout; - } - - this.initLayout( params ); - - cy.trigger("layoutstart"); - - this._private.layoutRunning = true; - this.one('layoutstop', function(){ - cy._private.layoutRunning = false; - }); - - this._private.layout.run(); - - return this; - - }, - - initLayout: function( options ){ - if( options == null ){ - $$.util.error("Layout options must be specified to run a layout"); - return; - } - - if( options.name == null ){ - $$.util.error("A `name` must be specified to run a layout"); - return; - } - - var name = options.name; - var layoutProto = $$.extension("layout", name); - - if( layoutProto == null ){ - $$.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?", name); - return; - } - - this._private.layout = new layoutProto( $$.util.extend({}, options, { - renderer: this._private.renderer, - cy: this - }) ); - this._private.options.layout = options; // save options - } - - }); - -})( cytoscape ); - -(function($$){ "use strict"; - - $$.fn.core({ - notify: function( params ){ - if( !this._private.notificationsEnabled ){ return; } // exit on disabled - - var renderer = this.renderer(); - var cy = this; - - // normalise params.collection - if( $$.is.element(params.collection) ){ // make collection from element - var element = params.collection; - params.collection = new $$.Collection(cy, [ element ]); - - } else if( $$.is.array(params.collection) ){ // make collection from elements array - var elements = params.collection; - params.collection = new $$.Collection(cy, elements); - } - - renderer.notify(params); - }, - - notifications: function( bool ){ - var p = this._private; - - if( bool === undefined ){ - return p.notificationsEnabled; - } else { - p.notificationsEnabled = bool ? true : false; - } - }, - - noNotifications: function( callback ){ - this.notifications(false); - callback(); - this.notifications(true); - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - renderTo: function( context, zoom, pan ){ - var r = this._private.renderer; - - r.renderTo( context, zoom, pan ); - return this; - }, - - renderer: function(){ - return this._private.renderer; - }, - - forceRender: function(){ - this.notify({ - type: "draw" - }); - - return this; - }, - - initRenderer: function( options ){ - var cy = this; - - var rendererProto = $$.extension("renderer", options.name); - if( rendererProto == null ){ - $$.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?", options.name); - return; - } - - this._private.renderer = new rendererProto( - $$.util.extend({}, options, { - cy: cy, - style: cy._private.style - }) - ); - - - }, - - recalculateRenderedStyle: function(){ - var renderer = this.renderer(); - - if( renderer.recalculateRenderedStyle ){ - renderer.recalculateRenderedStyle(); - } - } - - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - // get a collection - // - empty collection on no args - // - collection of elements in the graph on selector arg - // - guarantee a returned collection when elements or collection specified - collection: function( eles ){ - - if( $$.is.string(eles) ){ - return this.$( eles ); - } else if( $$.is.elementOrCollection(eles) ){ - return eles.collection(); - } - - return new $$.Collection( this ); - }, - - nodes: function( selector ){ - var nodes = this.$("node"); - - if( selector ){ - return nodes.filter( selector ); - } - - return nodes; - }, - - edges: function( selector ){ - var edges = this.$("edge"); - - if( selector ){ - return edges.filter( selector ); - } - - return edges; - }, - - // search the graph like jQuery - $: function( selector ){ - var eles = new $$.Collection( this, this._private.elements ); - - if( selector ){ - return eles.filter( selector ); - } - - return eles; - } - - }); - - // aliases - $$.corefn.elements = $$.corefn.filter = $$.corefn.$; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.core({ - - style: function(val){ - return this._private.style; - } - }); - -})( cytoscape ); - - -;(function($$){ "use strict"; - - $$.fn.core({ - - panningEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.panningEnabled = bool ? true : false; - } else { - return this._private.panningEnabled; - } - - return this; // chaining - }, - - userPanningEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.userPanningEnabled = bool ? true : false; - } else { - return this._private.userPanningEnabled; - } - - return this; // chaining - }, - - zoomingEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.zoomingEnabled = bool ? true : false; - } else { - return this._private.zoomingEnabled; - } - - return this; // chaining - }, - - userZoomingEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.userZoomingEnabled = bool ? true : false; - } else { - return this._private.userZoomingEnabled; - } - - return this; // chaining - }, - - boxSelectionEnabled: function( bool ){ - if( bool !== undefined ){ - this._private.boxSelectionEnabled = bool ? true : false; - } else { - return this._private.boxSelectionEnabled; - } - - return this; // chaining - }, - - pan: function(){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - switch( args.length ){ - case 0: // .pan() - return pan; - - case 1: - - if( !this._private.panningEnabled ){ - return this; - - } else if( $$.is.string( args[0] ) ){ // .pan("x") - dim = args[0]; - return pan[ dim ]; - - } else if( $$.is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x = x; - } - - if( $$.is.number(y) ){ - pan.y = y; - } - - this.trigger("pan"); - } - break; - - case 2: // .pan("x", 100) - if( !this._private.panningEnabled ){ - return this; - } - - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] = val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - panBy: function(params){ - var args = arguments; - var pan = this._private.pan; - var dim, val, dims, x, y; - - if( !this._private.panningEnabled ){ - return this; - } - - switch( args.length ){ - case 1: - - if( $$.is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 }) - dims = args[0]; - x = dims.x; - y = dims.y; - - if( $$.is.number(x) ){ - pan.x += x; - } - - if( $$.is.number(y) ){ - pan.y += y; - } - - this.trigger("pan"); - } - break; - - case 2: // .panBy("x", 100) - dim = args[0]; - val = args[1]; - - if( (dim === "x" || dim === "y") && $$.is.number(val) ){ - pan[dim] += val; - } - - this.trigger("pan"); - break; - - default: - break; // invalid - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - fit: function( elements, padding ){ - if( $$.is.number(elements) && padding === undefined ){ // elements is optional - padding = elements; - elements = undefined; - } - - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var sel = elements; - elements = this.$( sel ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = this.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom; - padding = $$.is.number(padding) ? padding : 0; - - if( !isNaN(w) && !isNaN(h) && elements.length > 0 ){ - zoom = this._private.zoom = Math.min( (w - 2*padding)/bb.w, (h - 2*padding)/bb.h ); - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - this._private.pan = { // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }; - - this.trigger("pan zoom"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - } - - return this; // chaining - }, - - minZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.minZoom; - } else if( $$.is.number(zoom) ){ - this._private.minZoom = zoom; - } - - return this; - }, - - maxZoom: function( zoom ){ - if( zoom === undefined ){ - return this._private.maxZoom; - } else if( $$.is.number(zoom) ){ - this._private.maxZoom = zoom; - } - - return this; - }, - - zoom: function( params ){ - var pos; // in rendered px - var zoom; - - if( params === undefined ){ // then get the zoom - return this._private.zoom; - - } else if( $$.is.number(params) ){ // then set the zoom - zoom = params; - - } else if( $$.is.plainObject(params) ){ // then zoom about a point - zoom = params.level; - - if( params.position ){ - var p = params.position; - var pan = this._private.pan; - var z = this._private.zoom; - - pos = { // convert to rendered px - x: p.x * z + pan.x, - y: p.y * z + pan.y - }; - } else if( params.renderedPosition ){ - pos = params.renderedPosition; - } - - if( pos && !this._private.panningEnabled ){ - return this; // panning disabled - } - } - - if( !this._private.zoomingEnabled ){ - return this; // zooming disabled - } - - if( !$$.is.number(zoom) || ( pos && (!$$.is.number(pos.x) || !$$.is.number(pos.y)) ) ){ - return this; // can't zoom with invalid params - } - - // crop zoom - zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; - zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; - - if( pos ){ // set zoom about position - var pan1 = this._private.pan; - var zoom1 = this._private.zoom; - var zoom2 = zoom; - - var pan2 = { - x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x, - y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y - }; - - this._private.zoom = zoom; - this._private.pan = pan2; - - var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y; - this.trigger("zoom" + (posChanged ? " pan" : "") ); - - } else { // just set the zoom - this._private.zoom = zoom; - this.trigger("zoom"); - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( selector ){ - var eles = this.$( selector ); - - return eles.boundingBox(); - }, - - renderedBoundingBox: function( selector ){ - var eles = this.$( selector ); - - return eles.renderedBoundingBox(); - }, - - center: function(elements){ - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - if( $$.is.string(elements) ){ - var selector = elements; - elements = cy.elements( selector ); - } else if( !$$.is.elementOrCollection(elements) ){ - elements = cy.elements(); - } - - var bb = elements.boundingBox(); - var style = this.style(); - var w = parseFloat( style.containerCss("width") ); - var h = parseFloat( style.containerCss("height") ); - var zoom = this._private.zoom; - - this.pan({ // now pan to middle - x: (w - zoom*( bb.x1 + bb.x2 ))/2, - y: (h - zoom*( bb.y1 + bb.y2 ))/2 - }); - - this.trigger("pan"); - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - }, - - reset: function(){ - if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ - return this; - } - - this.pan({ x: 0, y: 0 }); - - if( this._private.maxZoom > 1 && this._private.minZoom < 1 ){ - this.zoom(1); - } - - this.notify({ // notify the renderer that the viewport changed - type: "viewport" - }); - - return this; // chaining - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Use this interface to define functions for collections/elements. - // This interface is good, because it forces you to think in terms - // of the collections case (more than 1 element), so we don't need - // notification blocking nonsense everywhere. - // - // Other collection-*.js files depend on this being defined first. - // It's a trade off: It simplifies the code for Collection and - // Element integration so much that it's worth it to create the - // JS dependency. - // - // Having this integration guarantees that we can call any - // collection function on an element and vice versa. - - // e.g. $$.fn.collection({ someFunc: function(){ /* ... */ } }) - $$.fn.collection = $$.fn.eles = function( fnMap, options ){ - for( var name in fnMap ){ - var fn = fnMap[name]; - - $$.Collection.prototype[ name ] = fn; - } - }; - - // factory for generating edge ids when no id is specified for a new element - var idFactory = { - prefix: { - nodes: "n", - edges: "e" - }, - id: { - nodes: 0, - edges: 0 - }, - generate: function(cy, element, tryThisId){ - var json = $$.is.element( element ) ? element._private : element; - var group = json.group; - var id = tryThisId != null ? tryThisId : this.prefix[group] + this.id[group]; - - if( cy.getElementById(id).empty() ){ - this.id[group]++; // we've used the current id, so move it up - } else { // otherwise keep trying successive unused ids - while( !cy.getElementById(id).empty() ){ - id = this.prefix[group] + ( ++this.id[group] ); - } - } - - return id; - } - }; - - // Element - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a node or an edge - $$.Element = function(cy, params, restore){ - if( !(this instanceof $$.Element) ){ - return new $$.Element(cy, params, restore); - } - - var self = this; - restore = (restore === undefined || restore ? true : false); - - if( cy === undefined || params === undefined || !$$.is.core(cy) ){ - $$.util.error("An element must have a core reference and parameters set"); - return; - } - - // validate group - if( params.group !== "nodes" && params.group !== "edges" ){ - $$.util.error("An element must be of type `nodes` or `edges`; you specified `" + params.group + "`"); - return; - } - - // make the element array-like, just like a collection - this.length = 1; - this[0] = this; - - // NOTE: when something is added here, add also to ele.json() - this._private = { - cy: cy, - single: true, // indicates this is an element - data: params.data || {}, // data object - layoutData: {}, // place for layouts to put calculated stats etc for mappers - position: params.position || {}, // fields x, y, etc (could be 3d or radial coords; renderer decides) - autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special "auto" value - autoHeight: undefined, - listeners: [], // array of bound listeners - group: params.group, // string; "nodes" or "edges" - style: {}, // properties as set by the style - rstyle: {}, // properties for style sent from the renderer to the core - styleCxts: [], // applied style contexts from the styler - removed: true, // whether it's inside the vis; true if removed (set true here since we call restore) - selected: params.selected ? true : false, // whether it's selected - selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable - locked: params.locked ? true : false, // whether the element is locked (cannot be moved) - grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately - grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed - active: false, // whether the element is active from user interaction - classes: {}, // map ( className => true ) - animation: { // object for currently-running animations - current: [], - queue: [] - }, - rscratch: {}, // object in which the renderer can store information - scratch: {}, // scratch objects - edges: [], // array of connected edges - children: [] // array of children - }; - - // renderedPosition overrides if specified - if( params.renderedPosition ){ - var rpos = params.renderedPosition; - var pan = cy.pan(); - var zoom = cy.zoom(); - - this._private.position = { - x: (rpos.x - pan.x)/zoom, - y: (rpos.y - pan.y)/zoom - }; - } - - if( $$.is.string(params.classes) ){ - var classes = params.classes.split(/\s+/); - for( var i = 0, l = classes.length; i < l; i++ ){ - var cls = classes[i]; - if( !cls || cls === "" ){ continue; } - - self._private.classes[cls] = true; - } - } - - if( params.css ){ - cy.style().applyBypass( this, params.css ); - } - - if( restore === undefined || restore ){ - this.restore(); - } - - }; - - - // Collection - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // represents a set of nodes, edges, or both together - $$.Collection = function(cy, elements){ - if( !(this instanceof $$.Collection) ){ - return new $$.Collection(cy, elements); - } - - if( cy === undefined || !$$.is.core(cy) ){ - $$.util.error("A collection must have a reference to the core"); - return; - } - - var ids = {}; - var uniqueElements = []; - var createdElements = false; - - if( !elements ){ - elements = []; - } else if( elements.length > 0 && $$.is.plainObject( elements[0] ) && !$$.is.element( elements[0] ) ){ - createdElements = true; - - // make elements from json and restore all at once later - var eles = []; - var elesIds = {}; - - for( var i = 0, l = elements.length; i < l; i++ ){ - var json = elements[i]; - - if( json.data == null ){ - json.data = {}; - } - - var data = json.data; - - // make sure newly created elements have valid ids - if( data.id == null ){ - data.id = idFactory.generate( cy, json ); - } else if( cy.getElementById( data.id ).length != 0 || elesIds[ data.id ] ){ - continue; // can't create element if prior id already exists - } - - var ele = new $$.Element( cy, json, false ); - eles.push( ele ); - elesIds[ data.id ] = true; - } - - elements = eles; - } - - for( var i = 0, l = elements.length; i < l; i++ ){ - var element = elements[i]; - if( !element ){ continue; } - - var id = element._private.data.id; - - if( !ids[ id ] ){ - ids[ id ] = element; - uniqueElements.push( element ); - } - } - - for(var i = 0, l = uniqueElements.length; i < l; i++){ - this[i] = uniqueElements[i]; - } - this.length = uniqueElements.length; - - this._private = { - cy: cy, - ids: ids - }; - - // restore the elements if we created them from json - if( createdElements ){ - this.restore(); - } - }; - - - // Functions - //////////////////////////////////////////////////////////////////////////////////////////////////// - - // keep the prototypes in sync (an element has the same functions as a collection) - // and use $$.elefn and $$.elesfn as shorthands to the prototypes - $$.elefn = $$.elesfn = $$.Element.prototype = $$.Collection.prototype; - - $$.elesfn.cy = function(){ - return this._private.cy; - }; - - $$.elesfn.element = function(){ - return this[0]; - }; - - $$.elesfn.collection = function(){ - if( $$.is.collection(this) ){ - return this; - } else { // an element - return new $$.Collection( this._private.cy, [this] ); - } - }; - - $$.elesfn.json = function(){ - var ele = this.element(); - if( ele == null ){ return undefined } - - var p = ele._private; - - var json = $$.util.copy({ - data: p.data, - position: p.position, - group: p.group, - bypass: p.bypass, - removed: p.removed, - selected: p.selected, - selectable: p.selectable, - locked: p.locked, - grabbed: p.grabbed, - grabbable: p.grabbable, - classes: "" - }); - - var classes = []; - for( var cls in p.classes ){ - classes.push(cls); - } - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - json.classes += cls + ( i < classes.length - 1 ? " " : "" ); - } - - return json; - }; - - $$.elesfn.jsons = function(){ - var jsons = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - var json = ele.json(); - - jsons.push( json ); - } - - return jsons; - }; - - $$.elesfn.restore = function( notifyRenderer ){ - var self = this; - var restored = []; - var cy = self.cy(); - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // create arrays of nodes and edges, since we need to - // restore the nodes first - var elements = []; - var nodes = [], edges = []; - var numNodes = 0; - var numEdges = 0; - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - // keep nodes first in the array and edges after - if( ele.isNode() ){ // put to front of array if node - nodes.push( ele ); - numNodes++; - } else { // put to end of array if edge - edges.push( ele ); - numEdges++; - } - } - - elements = nodes.concat( edges ); - - // now, restore each element - for( var i = 0, l = elements.length; i < l; i++ ){ - var ele = elements[i]; - - if( !ele.removed() ){ - // don't need to do anything - continue; - } - - var _private = ele._private; - var data = _private.data; - - // set id and validate - if( data.id === undefined ){ - data.id = idFactory.generate( cy, ele ); - } else if( $$.is.emptyString(data.id) || !$$.is.string(data.id) ){ - $$.util.error("Can not create element with invalid string ID `" + data.id + "`"); - - // can't create element if it has empty string as id or non-string id - continue; - } else if( cy.getElementById( data.id ).length != 0 ){ - $$.util.error("Can not create second element with ID `" + data.id + "`"); - - // can't create element if one already has that id - continue; - } - - var id = data.id; // id is finalised, now let's keep a ref - - if( ele.isEdge() ){ // extra checks for edges - - var edge = ele; - var fields = ["source", "target"]; - var fieldsLength = fields.length; - var badSourceOrTarget = false; - for(var j = 0; j < fieldsLength; j++){ - - var field = fields[j]; - var val = data[field]; - - if( val == null || val === "" ){ - // can't create if source or target is not defined properly - $$.util.error("Can not create edge `" + data.id + "` with unspecified " + field); - badSourceOrTarget = true; - } else if( cy.getElementById(val).empty() ){ - // can't create edge if one of its nodes doesn't exist - $$.util.error("Can not create edge `" + data.id + "` with nonexistant " + field + " `" + val + "`"); - badSourceOrTarget = true; - } - } - - if( badSourceOrTarget ){ continue; } // can't create this - - var src = cy.getElementById( data.source ); - var tgt = cy.getElementById( data.target ); - - src._private.edges.push( edge ); - tgt._private.edges.push( edge ); - - } // if is edge - - // create mock ids map for element so it can be used like collections - _private.ids = {}; - _private.ids[ data.id ] = ele; - - _private.removed = false; - cy.addToPool( ele ); - - restored.push( ele ); - } // for each element - - // do compound node sanity checks - for( var i = 0; i < numNodes; i++ ){ // each node - var node = elements[i]; - var data = node._private.data; - var id = data.id; - - var parentId = node._private.data.parent; - var specifiedParent = parentId != null; - - if( specifiedParent ){ - var parent = cy.getElementById( parentId ); - - if( parent.empty() ){ - // non-existant parent; just remove it - delete data.parent; - } else { - var selfAsParent = false; - var ancestor = parent; - while( !ancestor.empty() ){ - if( node.same(ancestor) ){ - // mark self as parent and remove from data - selfAsParent = true; - delete data.parent; // remove parent reference - - // exit or we loop forever - break; - } - - ancestor = ancestor.parent(); - } - - if( !selfAsParent ){ - // connect with children - parent[0]._private.children.push( node ); - - // let the core know we have a compound graph - cy._private.hasCompoundNodes = true; - } - } // else - } // if specified parent - } // for each node - - restored = new $$.Collection( cy, restored ); - if( restored.length > 0 ){ - - var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() ); - toUpdateStyle.updateStyle( notifyRenderer ); - - if( notifyRenderer ){ - restored.rtrigger("add"); - } else { - restored.trigger("add"); - } - } - - return self; // chainability - }; - - $$.elesfn.removed = function(){ - var ele = this[0]; - return ele && ele._private.removed; - }; - - $$.elesfn.inside = function(){ - var ele = this[0]; - return ele && !ele._private.removed; - }; - - $$.elesfn.remove = function( notifyRenderer ){ - var self = this; - var removed = []; - var elesToRemove = []; - var elesToRemoveIds = {}; - var cy = self._private.cy; - - if( notifyRenderer === undefined ){ - notifyRenderer = true; - } - - // add connected edges - function addConnectedEdges(node){ - var edges = node._private.edges; - for( var i = 0; i < edges.length; i++ ){ - add( edges[i] ); - } - } - - - // add descendant nodes - function addChildren(node){ - var children = node._private.children; - - for( var i = 0; i < children.length; i++ ){ - add( children[i] ); - } - } - - function add( ele ){ - var alreadyAdded = elesToRemoveIds[ ele.id() ]; - if( alreadyAdded ){ - return; - } else { - elesToRemoveIds[ ele.id() ] = true; - } - - if( ele.isNode() ){ - elesToRemove.push( ele ); // nodes are removed last - - addConnectedEdges( ele ); - addChildren( ele ); - } else { - elesToRemove.unshift( ele ); // edges are removed first - } - } - - // make the list of elements to remove - // (may be removing more than specified due to connected edges etc) - - for( var i = 0, l = self.length; i < l; i++ ){ - var ele = self[i]; - - add( ele ); - } - - function removeEdgeRef(node, edge){ - var connectedEdges = node._private.edges; - for( var j = 0; j < connectedEdges.length; j++ ){ - var connectedEdge = connectedEdges[j]; - - if( edge === connectedEdge ){ - connectedEdges.splice( j, 1 ); - break; - } - } - } - - function removeChildRef(parent, ele){ - ele = ele[0]; - parent = parent[0]; - var children = parent._private.children; - - for( var j = 0; j < children.length; j++ ){ - if( children[j][0] === ele[0] ){ - children.splice(j, 1); - break; - } - } - } - - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - - // mark as removed - ele._private.removed = true; - - // remove from core pool - cy.removeFromPool( ele ); - - // add to list of removed elements - removed.push( ele ); - - if( ele.isEdge() ){ // remove references to this edge in its connected nodes - var src = ele.source()[0]; - var tgt = ele.target()[0]; - - removeEdgeRef( src, ele ); - removeEdgeRef( tgt, ele ); - - } else { // remove reference to parent - var parent = ele.parent(); - - if( parent.length !== 0 ){ - removeChildRef(parent, ele); - } - } - } - - // check to see if we have a compound graph or not - var elesStillInside = cy._private.elements; - cy._private.hasCompoundNodes = false; - for( var i = 0; i < elesStillInside.length; i++ ){ - var ele = elesStillInside[i]; - - if( ele.isParent() ){ - cy._private.hasCompoundNodes = true; - break; - } - } - - var removedElements = new $$.Collection( this.cy(), removed ); - if( removedElements.size() > 0 ){ - // must manually notify since trigger won't do this automatically once removed - - if( notifyRenderer ){ - this.cy().notify({ - type: "remove", - collection: removedElements - }); - } - - removedElements.trigger("remove"); - } - - // check for empty remaining parent nodes - var checkedParentId = {}; - for( var i = 0; i < elesToRemove.length; i++ ){ - var ele = elesToRemove[i]; - var isNode = ele._private.group === "nodes"; - var parentId = ele._private.data.parent; - - if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){ - checkedParentId[ parentId ] = true; - var parent = cy.getElementById( parentId ); - - if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){ - parent.updateStyle(); - } - } - } - - return this; - }; - -})( cytoscape ); - - -;(function( $$ ){ "use strict"; - - $$.fn.eles({ - animated: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.animation.current.length > 0; - } - }, - - clearQueue: function(){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - ele._private.animation.queue = []; - } - - return this; - }, - - delay: function( time, complete ){ - this.animate({ - delay: time - }, { - duration: time, - complete: complete - }); - - return this; - }, - - animate: function( properties, params ){ - var callTime = +new Date; - var cy = this._private.cy; - var style = cy.style(); - var q; - - if( params === undefined ){ - params = {}; - } - - if( params.duration === undefined ){ - params.duration = 400; - } - - switch( params.duration ){ - case "slow": - params.duration = 600; - break; - case "fast": - params.duration = 200; - break; - } - - if( properties == null || (properties.position == null && properties.renderedPosition == null && properties.css == null && properties.delay == null) ){ - return this; // nothing to animate - } - - if( properties.css ){ - properties.css = style.getValueStyle( properties.css ); - } - - if( properties.renderedPosition ){ - var rpos = properties.renderedPosition; - var pan = cy.pan(); - var zoom = cy.zoom(); - - properties.position = { - x: ( rpos.x - pan.x ) /zoom, - y: ( rpos.y - pan.y ) /zoom - }; - } - - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - - var pos = self._private.position; - var startPosition = { - x: pos.x, - y: pos.y - }; - var startStyle = style.getValueStyle( self ); - - if( self.animated() && (params.queue === undefined || params.queue) ){ - q = self._private.animation.queue; - } else { - q = self._private.animation.current; - } - - q.push({ - properties: properties, - duration: params.duration, - params: params, - callTime: callTime, - startPosition: startPosition, - startStyle: startStyle - }); - } - - cy.addToAnimationPool( this ); - - return this; // chaining - }, // animate - - stop: function(clearQueue, jumpToEnd){ - for( var i = 0; i < this.length; i++ ){ - var self = this[i]; - var anis = self._private.animation.current; - - for( var j = 0; j < anis.length; j++ ){ - var animation = anis[j]; - if( jumpToEnd ){ - // next iteration of the animation loop, the animation - // will go straight to the end and be removed - animation.duration = 0; - } - } - - // clear the queue of future animations - if( clearQueue ){ - self._private.animation.queue = []; - } - } - - // we have to notify (the animation loop doesn't do it for us on `stop`) - this.cy().notify({ - collection: this, - type: "draw" - }); - - return this; - } - }); - -})( cytoscape ); - -;(function( $$ ){ "use strict"; - - $$.fn.eles({ - addClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < classes.length; i++ ){ - var cls = classes[i]; - if( $$.is.emptyString(cls) ){ continue; } - - for( var j = 0; j < self.length; j++ ){ - var ele = self[j]; - var hasClass = ele._private.classes[cls]; - ele._private.classes[cls] = true; - - if( !hasClass ){ // if didn't already have, add to list of changed - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - hasClass: function(className){ - var ele = this[0]; - return ( ele != null && ele._private.classes[className] ) ? true : false; - }, - - toggleClass: function(classesStr, toggle){ - var classes = classesStr.split(/\s+/); - var self = this; - var changed = []; // eles who had classes changed - - for( var i = 0, il = self.length; i < il; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - - if( $$.is.emptyString(cls) ){ continue; } - - var hasClass = ele._private.classes[cls]; - var shouldAdd = toggle || (toggle === undefined && !hasClass); - - if( shouldAdd ){ - ele._private.classes[cls] = true; - - if( !hasClass ){ changed.push(ele); } - } else { // then remove - ele._private.classes[cls] = false; - - if( hasClass ){ changed.push(ele); } - } - - } // for j classes - } // for i eles - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(this._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - }, - - removeClass: function(classes){ - classes = classes.split(/\s+/); - var self = this; - var changed = []; - - for( var i = 0; i < self.length; i++ ){ - var ele = self[i]; - - for( var j = 0; j < classes.length; j++ ){ - var cls = classes[j]; - if( !cls || cls === "" ){ continue; } - - var hasClass = ele._private.classes[cls]; - delete ele._private.classes[cls]; - - if( hasClass ){ // then we changed its set of classes - changed.push( ele ); - } - } - } - - // trigger update style on those eles that had class changes - if( changed.length > 0 ){ - new $$.Collection(self._private.cy, changed).updateStyle(); - } - - self.trigger("class"); - return self; - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - allAre: function(selector){ - return this.filter(selector).length === this.length; - }, - - is: function(selector){ - return this.filter(selector).length > 0; - }, - - same: function( collection ){ - collection = this.cy().collection( collection ); - - // cheap extra check - if( this.length !== collection.length ){ - return false; - } - - return this.intersect( collection ).length === this.length; - }, - - anySame: function(collection){ - collection = this.cy().collection( collection ); - - return this.intersect( collection ).length > 0; - }, - - allAreNeighbors: function(collection){ - collection = this.cy().collection( collection ); - - return this.neighborhood().intersect( collection ).length === collection.length; - } - }); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var borderWidthMultiplier = 2 * 0.5; - var borderWidthAdjustment = 0; - - $$.fn.eles({ - - data: $$.define.data({ - field: "data", - bindingEvent: "data", - allowBinding: true, - allowSetting: true, - settingEvent: "data", - settingTriggersEvent: true, - triggerFnName: "trigger", - allowGetting: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - removeData: $$.define.removeData({ - field: "data", - event: "data", - triggerFnName: "trigger", - triggerEvent: true, - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - batchData: $$.define.batchData({ - field: "data", - event: "data", - triggerFnName: "trigger", - immutableKeys: { - "id": true, - "source": true, - "target": true, - "parent": true - }, - updateMappers: true - }), - - scratch: $$.define.data({ - field: "scratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeScratch: $$.define.removeData({ - field: "scratch", - triggerEvent: false - }), - - rscratch: $$.define.data({ - field: "rscratch", - allowBinding: false, - allowSetting: true, - settingTriggersEvent: false, - allowGetting: true - }), - - removeRscratch: $$.define.removeData({ - field: "rscratch", - triggerEvent: false - }), - - id: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.id; - } - }, - - position: $$.define.data({ - field: "position", - bindingEvent: "position", - allowBinding: true, - allowSetting: true, - settingEvent: "position", - settingTriggersEvent: true, - triggerFnName: "rtrigger", - allowGetting: true, - validKeys: ["x", "y"], - onSet: function( eles ){ - var updatedEles = eles.updateCompoundBounds(); - updatedEles.rtrigger("position"); - }, - canSet: function( ele ){ - return !ele.locked(); - } - }), - - // position but no notification to renderer - silentPosition: $$.define.data({ - field: "position", - bindingEvent: "position", - allowBinding: false, - allowSetting: true, - settingEvent: "position", - settingTriggersEvent: false, - triggerFnName: "trigger", - allowGetting: true, - validKeys: ["x", "y"], - onSet: function( eles ){ - eles.updateCompoundBounds(); - }, - canSet: function( ele ){ - return !ele.locked(); - } - }), - - positions: function( pos ){ - if( $$.is.plainObject(pos) ){ - this.position(pos); - - } else if( $$.is.fn(pos) ){ - var fn = pos; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - var pos = fn.apply(ele, [i, ele]); - - if( pos && !ele.locked() ){ - var elePos = ele._private.position; - elePos.x = pos.x; - elePos.y = pos.y; - } - } - - var updatedEles = this.updateCompoundBounds(); - - this.add( updatedEles ).rtrigger("position"); - } - - return this; // chaining - }, - - updateCompoundBounds: function(){ - var cy = this.cy(); - - if( !cy.hasCompoundNodes() ){ return cy.collection(); } // save cycles for non compound graphs - - var updated = []; - - function update( parent ){ - var children = parent.children(); - var style = parent._private.style; - var bb = children.boundingBox({ includeLabels: false, includeEdges: false }); - var padding = { - top: style["padding-top"].pxValue, - bottom: style["padding-bottom"].pxValue, - left: style["padding-left"].pxValue, - right: style["padding-right"].pxValue - }; - var pos = parent._private.position; - var didUpdate = false; - - if( style["width"].value === "auto" ){ - parent._private.autoWidth = bb.w + padding.left + padding.right; - pos.x = (bb.x1 + bb.x2 - padding.left + padding.right)/2; - didUpdate = true; - } - - if( style["height"].value === "auto" ){ - parent._private.autoHeight = bb.h + padding.top + padding.bottom; - pos.y = (bb.y1 + bb.y2 - padding.top + padding.bottom)/2; - didUpdate = true; - } - - if( didUpdate ){ - updated.push( parent ); - } - } - - // go up, level by level - var eles = this.parent(); - while( eles.nonempty() ){ - - // update each parent node in this level - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - update( ele ); - } - - // next level - eles = eles.parent(); - } - - // return changed - return new $$.Collection( cy, updated ); - }, - - // get/set the rendered (i.e. on screen) positon of the element - renderedPosition: function( dim, val ){ - var ele = this[0]; - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - var rpos = $$.is.plainObject( dim ) ? dim : undefined; - var setting = rpos !== undefined || ( val !== undefined && $$.is.string(dim) ); - - if( ele && ele.isNode() ){ // must have an element and must be a node to return position - if( setting ){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( val !== undefined ){ // set one dimension - ele._private.position[dim] = ( val - pan[dim] )/zoom; - } else if( rpos !== undefined ){ // set whole position - ele._private.position = { - x: ( rpos.x - pan.x ) /zoom, - y: ( rpos.y - pan.y ) /zoom - }; - } - } - - this.rtrigger("position"); - } else { // getting - var pos = ele._private.position; - rpos = { - x: pos.x * zoom + pan.x, - y: pos.y * zoom + pan.y - }; - - if( dim === undefined ){ // then return the whole rendered position - return rpos; - } else { // then return the specified dimension - return rpos[ dim ]; - } - } - } else if( !setting ){ - return undefined; // for empty collection case - } - - return this; // chaining - }, - - // convenience function to get a numerical value for the width of the node/edge - width: function(){ - var ele = this[0]; - - if( ele ){ - var w = ele._private.style.width; - return w.strValue === "auto" ? ele._private.autoWidth : w.pxValue; - } - }, - - outerWidth: function(){ - var ele = this[0]; - - if( ele ){ - var style = ele._private.style; - var width = style.width.strValue === "auto" ? ele._private.autoWidth : style.width.pxValue;; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return width + border; - } - }, - - renderedWidth: function(){ - var ele = this[0]; - - if( ele ){ - var width = ele.width(); - return width * this.cy().zoom(); - } - }, - - renderedOuterWidth: function(){ - var ele = this[0]; - - if( ele ){ - var owidth = ele.outerWidth(); - return owidth * this.cy().zoom(); - } - }, - - // convenience function to get a numerical value for the height of the node - height: function(){ - var ele = this[0]; - - if( ele && ele.isNode() ){ - var h = ele._private.style.height; - return h.strValue === "auto" ? ele._private.autoHeight : h.pxValue; - } - }, - - outerHeight: function(){ - var ele = this[0]; - - if( ele ){ - var style = ele._private.style; - var height = style.height.strValue === "auto" ? ele._private.autoHeight : style.height.pxValue; - var border = style["border-width"] ? style["border-width"].pxValue * borderWidthMultiplier + borderWidthAdjustment : 0; - - return height + border; - } - }, - - renderedHeight: function(){ - var ele = this[0]; - - if( ele ){ - var height = ele.height(); - return height * this.cy().zoom(); - } - }, - - renderedOuterHeight: function(){ - var ele = this[0]; - - if( ele ){ - var oheight = ele.outerHeight(); - return oheight * this.cy().zoom(); - } - }, - - renderedBoundingBox: function( options ){ - var bb = this.boundingBox( options ); - var cy = this.cy(); - var zoom = cy.zoom(); - var pan = cy.pan(); - - var x1 = bb.x1 * zoom + pan.x; - var x2 = bb.x2 * zoom + pan.x; - var y1 = bb.y1 * zoom + pan.y; - var y2 = bb.y2 * zoom + pan.y; - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2, - w: x2 - x1, - h: y2 - y1 - }; - }, - - // get the bounding box of the elements (in raw model position) - boundingBox: function( options ){ - var eles = this; - - options = $$.util.extend({ - includeNodes: true, - includeEdges: true, - includeLabels: true - }, options); - - // recalculate projections etc - this.cy().recalculateRenderedStyle(); - - var x1 = Infinity; - var x2 = -Infinity; - var y1 = Infinity; - var y2 = -Infinity; - - // find bounds of elements - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - var ex1, ex2, ey1, ey2, x, y; - var includedEle = false; - - if( ele.css("display") === "none" ){ continue; } // then ele doesn't take up space - - if( ele.isNode() && options.includeNodes ){ - includedEle = true; - - var pos = ele._private.position; - x = pos.x; - y = pos.y; - var w = ele.outerWidth(); - var halfW = w/2; - var h = ele.outerHeight(); - var halfH = h/2; - - // handle node dimensions - ///////////////////////// - - ex1 = x - halfW; - ex2 = x + halfW; - ey1 = y - halfH; - ey2 = y + halfH; - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - } else if( ele.isEdge() && options.includeEdges ){ - includedEle = true; - - var n1pos = ele.source()[0]._private.position; - var n2pos = ele.target()[0]._private.position; - - // handle edge dimensions (rough box estimate) - ////////////////////////////////////////////// - - var rstyle = ele._private.rstyle || {}; - - ex1 = n1pos.x; - ex2 = n2pos.x; - ey1 = n1pos.y; - ey2 = n2pos.y; - - if( ex1 > ex2 ){ - var temp = ex1; - ex1 = ex2; - ex2 = temp; - } - - if( ey1 > ey2 ){ - var temp = ey1; - ey1 = ey2; - ey2 = temp; - } - - x1 = ex1 < x1 ? ex1 : x1; - x2 = ex2 > x2 ? ex2 : x2; - y1 = ey1 < y1 ? ey1 : y1; - y2 = ey2 > y2 ? ey2 : y2; - - // handle points along edge (sanity check) - ////////////////////////////////////////// - - var bpts = rstyle.bezierPts || []; - var w = ele._private.style['width'].pxValue; - for( var j = 0; j < bpts.length; j++ ){ - var bpt = bpts[j]; - - x1 = bpt.x - w < x1 ? bpt.x - w : x1; - x2 = bpt.x + w > x2 ? bpt.x + w : x2; - y1 = bpt.y - w < y1 ? bpt.y - w : y1; - y2 = bpt.y + w > y2 ? bpt.y + w : y2; - } - - } - - // handle label dimensions - ////////////////////////// - - var style = ele._private.style; - var rstyle = ele._private.rstyle; - var label = style['content'].strValue; - var fontSize = style['font-size']; - var halign = style['text-halign']; - var valign = style['text-valign']; - var labelWidth = rstyle.labelWidth; - var labelHeight = rstyle.labelHeight || fontSize.pxValue; - var labelX = rstyle.labelX; - var labelY = rstyle.labelY; - - if( includedEle && options.includeLabels && label && fontSize && labelHeight != undefined && labelWidth != undefined && labelX != undefined && labelY != undefined && halign && valign ){ - var lh = labelHeight; - var lw = labelWidth; - var lx1, lx2, ly1, ly2; - - if( ele.isEdge() ){ - lx1 = labelX - lw/2; - lx2 = labelX + lw/2; - ly1 = labelY - lh/2; - ly2 = labelY + lh/2; - } else { - switch( halign.value ){ - case "left": - lx1 = labelX - lw; - lx2 = labelX; - break; - - case "center": - lx1 = labelX - lw/2; - lx2 = labelX + lw/2; - break; - - case "right": - lx1 = labelX; - lx2 = labelX + lw; - break; - } - - switch( valign.value ){ - case "top": - ly1 = labelY - lh; - ly2 = labelY; - break; - - case "center": - ly1 = labelY - lh/2; - ly2 = labelY + lh/2; - break; - - case "bottom": - ly1 = labelY; - ly2 = labelY + lh; - break; - } - } - - x1 = lx1 < x1 ? lx1 : x1; - x2 = lx2 > x2 ? lx2 : x2; - y1 = ly1 < y1 ? ly1 : y1; - y2 = ly2 > y2 ? ly2 : y2; - } - } // for - - return { - x1: x1, - x2: x2, - y1: y1, - y2: y2, - w: x2 - x1, - h: y2 - y1 - }; - } - }); - - -})( cytoscape ); - -;(function( $$ ){ "use strict"; - - // Regular degree functions (works on single element) - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeFunction(callback){ - return function(){ - var self = this; - - if( self.length === 0 ){ return; } - - if( self.isNode() && !self.removed() ){ - var degree = 0; - var node = self[0]; - var connectedEdges = node._private.edges; - - for( var i = 0; i < connectedEdges.length; i++ ){ - var edge = connectedEdges[i]; - degree += callback( node, edge ); - } - - return degree; - } else { - return; - } - }; - } - - $$.fn.eles({ - degree: defineDegreeFunction(function(node, edge){ - if( edge.source().same( edge.target() ) ){ - return 2; - } else { - return 1; - } - }), - - indegree: defineDegreeFunction(function(node, edge){ - if( edge.target().same(node) ){ - return 1; - } else { - return 0; - } - }), - - outdegree: defineDegreeFunction(function(node, edge){ - if( edge.source().same(node) ){ - return 1; - } else { - return 0; - } - }) - }); - - - // Collection degree stats - //////////////////////////////////////////////////////////////////////////////////////////////////// - - function defineDegreeBoundsFunction(degreeFn, callback){ - return function(){ - var ret = undefined; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - var degree = ele[degreeFn](); - if( degree !== undefined && (ret === undefined || callback(degree, ret)) ){ - ret = degree; - } - } - - return ret; - }; - } - - $$.fn.eles({ - minDegree: defineDegreeBoundsFunction("degree", function(degree, min){ - return degree < min; - }), - - maxDegree: defineDegreeBoundsFunction("degree", function(degree, max){ - return degree > max; - }), - - minIndegree: defineDegreeBoundsFunction("indegree", function(degree, min){ - return degree < min; - }), - - maxIndegree: defineDegreeBoundsFunction("indegree", function(degree, max){ - return degree > max; - }), - - minOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, min){ - return degree < min; - }), - - maxOutdegree: defineDegreeBoundsFunction("outdegree", function(degree, max){ - return degree > max; - }) - }); - - $$.fn.eles({ - totalDegree: function(){ - var total = 0; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - total += nodes[i].degree(); - } - - return total; - } - }); - -})( cytoscape ); - - - -;(function($$){ "use strict"; - - // Functions for binding & triggering events - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - on: $$.define.on(), // .on( events [, selector] [, data], handler) - one: $$.define.on({ unbindSelfOnTrigger: true }), - once: $$.define.on({ unbindAllBindersOnTrigger: true }), - off: $$.define.off(), // .off( events [, selector] [, handler] ) - trigger: $$.define.trigger(), // .trigger( events [, extraParams] ) - - rtrigger: function(event, extraParams){ // for internal use only - if( this.length === 0 ){ return; } // empty collections don't need to notify anything - - // notify renderer unless removed - this.cy().notify({ - type: event, - collection: this.filter(function(){ - return !this.removed(); - }) - }); - - this.trigger(event, extraParams); - return this; - } - }); - - // aliases for those folks who like old stuff: - $$.elesfn.bind = $$.elesfn.on; - $$.elesfn.unbind = $$.elesfn.off; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - isNode: function(){ - return this.group() === "nodes"; - }, - - isEdge: function(){ - return this.group() === "edges"; - }, - - isLoop: function(){ - return this.isEdge() && this.source().id() === this.target().id(); - }, - - group: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.group; - } - } - }); - - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Functions for iterating over collections - //////////////////////////////////////////////////////////////////////////////////////////////////// - - $$.fn.eles({ - each: function(fn){ - if( $$.is.fn(fn) ){ - for(var i = 0; i < this.length; i++){ - var ele = this[i]; - var ret = fn.apply( ele, [ i, ele ] ); - - if( ret === false ){ break; } // exit each early on return false - } - } - return this; - }, - - toArray: function(){ - var array = []; - - for(var i = 0; i < this.length; i++){ - array.push( this[i] ); - } - - return array; - }, - - slice: function(start, end){ - var array = []; - var thisSize = this.length; - - if( end == null ){ - end = thisSize; - } - - if( start == null ){ - start = 0; - } - - if( start < 0 ){ - start = thisSize + start; - } - - if( end < 0 ){ - end = thisSize + end; - } - - for(var i = start; i >= 0 && i < end && i < thisSize; i++){ - array.push( this[i] ); - } - - return new $$.Collection(this.cy(), array); - }, - - size: function(){ - return this.length; - }, - - eq: function(i){ - return this[i]; - }, - - empty: function(){ - return this.length === 0; - }, - - nonempty: function(){ - return !this.empty(); - }, - - sort: function( sortFn ){ - if( !$$.is.fn( sortFn ) ){ - return this; - } - - var cy = this.cy(); - var coln = new $$.Collection( cy ); - - var sorted = this.toArray().sort( sortFn ); - - return new $$.Collection(cy, sorted); - }, - - sortByZIndex: function(){ - return this.sort( $$.Collection.zIndexSort ); - } - }); - - - $$.Collection.zIndexSort = function(a, b) { - var elementDepth = function(ele) { - if (ele._private.group == "nodes") - { - return ele.parents().size(); - } - else if (ele._private.group == "edges") - { - return Math.max(ele.source()[0].parents().size(), - ele.target()[0].parents().size()); - } - else - { - return 0; - } - }; - - var result = a._private.style["z-index"].value - b._private.style["z-index"].value; - - var depthA = 0; - var depthB = 0; - - // no need to calculate element depth if there is no compound node - if ( a.cy().hasCompoundNodes() ) - { - depthA = elementDepth(a); - depthB = elementDepth(b); - } - - // if both elements has same depth, - // then edges should be drawn first - if (depthA - depthB === 0) - { - // "a" is a node, it should be drawn later - if (a._private.group === "nodes" - && b._private.group === "edges") - { - return 1; - } - - // "a" is an edge, it should be drawn first - else if (a._private.group === "edges" - && b._private.group === "nodes") - { - return -1; - } - - // both nodes or both edges - else - { - if( result === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top) - return a._private.index - b._private.index; - } else { - return result; - } - } - } - - // elements on different level - else - { - // deeper element should be drawn later - return depthA - depthB; - } - - // return zero if z-index values are not the same - return 0; - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var borderWidthMultiplier = 2 * 0.5; - var borderWidthAdjustment = 0; - - $$.fn.eles({ - - // fully updates (recalculates) the style for the elements - updateStyle: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - style.apply( this ); - - var updatedCompounds = this.updateCompoundBounds(); - - if( notifyRenderer ){ - this.add( updatedCompounds ).rtrigger("style"); // let renderer know we changed style - } else { - this.add( updatedCompounds ).trigger("style"); // just fire the event - } - return this; // chaining - }, - - // just update the mappers in the elements' styles; cheaper than eles.updateStyle() - updateMappers: function( notifyRenderer ){ - var cy = this._private.cy; - var style = cy.style(); - notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; - - style.updateMappers( this ); - - var updatedCompounds = this.updateCompoundBounds(); - - if( notifyRenderer ){ - this.add( updatedCompounds ).rtrigger("style"); // let renderer know we changed style - } else { - this.add( updatedCompounds ).trigger("style"); // just fire the event - } - return this; // chaining - }, - - // get the specified css property as a rendered value (i.e. on-screen value) - // or get the whole rendered style if no property specified (NB doesn't allow setting) - renderedCss: function( property ){ - var ele = this[0]; - - if( ele ){ - var renstyle = ele.cy().style().getRenderedStyle( ele ); - - if( property === undefined ){ - return renstyle; - } else { - return renstyle[ property ]; - } - } - }, - - // read the calculated css style of the element or override the style (via a bypass) - css: function( name, value ){ - var style = this.cy().style(); - - if( $$.is.plainObject(name) ){ // then extend the bypass - var props = name; - style.applyBypass( this, props ); - this.rtrigger("style"); // let the renderer know we've updated style - - } else if( $$.is.string(name) ){ - - if( value === undefined ){ // then get the property from the style - var ele = this[0]; - - if( ele ){ - return ele._private.style[ name ].strValue; - } else { // empty collection => can't get any value - return; - } - - } else { // then set the bypass with the property value - style.applyBypass( this, name, value ); - this.rtrigger("style"); // let the renderer know we've updated style - } - - } else if( name === undefined ){ - var ele = this[0]; - - if( ele ){ - return style.getRawStyle( ele ); - } else { // empty collection => can't get any value - return; - } - } - - return this; // chaining - }, - - removeCss: function(){ - var style = this.cy().style(); - var eles = this; - - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - style.removeAllBypasses( ele ); - } - - this.rtrigger('style'); - }, - - show: function(){ - this.css("display", "element"); - return this; // chaining - }, - - hide: function(){ - this.css("display", "none"); - return this; // chaining - }, - - visible: function(){ - var ele = this[0]; - - if( ele ){ - if( - ele.css("visibility") !== "visible" - || ele.css("display") !== "element" - // || parseFloat( ele.css("opacity") ) === 0 - ){ - return false; - } - - if( ele.isNode() ){ - var parents = ele.parents(); - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var pVis = parent.css("visibility"); - var pDis = parent.css("display"); - var pOpac = parseFloat( parent.css("opacity") ); - - if( pVis !== "visible" || pDis !== "element" ){ - return false; - } - } - - return true; - } else if( ele.isEdge() ){ - var src = ele.source(); - var tgt = ele.target(); - - return src.visible() && tgt.visible(); - } - - } - }, - - hidden: function(){ - var ele = this[0]; - - if( ele ){ - return !ele.visible(); - } - }, - - effectiveOpacity: function(){ - var ele = this[0]; - - if( ele ){ - var parentOpacity = ele._private.style.opacity.value; - var parents = ele.parents(); - - for( var i = 0; i < parents.length; i++ ){ - var parent = parents[i]; - var opacity = parent._private.style.opacity.value; - - parentOpacity = opacity * parentOpacity; - } - - return parentOpacity; - } - }, - - transparent: function(){ - var ele = this[0]; - - if( ele ){ - return ele.effectiveOpacity() === 0; - } - }, - - isFullAutoParent: function(){ - var ele = this[0]; - - if( ele ){ - var autoW = ele._private.style["width"].value === "auto"; - var autoH = ele._private.style["height"].value === "auto"; - - return ele.isParent() && autoW && autoH; - } - } - - }); - - - $$.elesfn.style = $$.elesfn.css; - $$.elesfn.renderedStyle = $$.elesfn.renderedCss; - $$.elesfn.removeStyle = $$.elesfn.removeCss; - -})( cytoscape ); - -;(function($$){ "use strict"; - - // Collection functions that toggle a boolean value - //////////////////////////////////////////////////////////////////////////////////////////////////// - - - function defineSwitchFunction(params){ - return function(){ - var args = arguments; - - // e.g. cy.nodes().select( data, handler ) - if( args.length === 2 ){ - var data = args[0]; - var handler = args[1]; - this.bind( params.event, data, handler ); - } - - // e.g. cy.nodes().select( handler ) - else if( args.length === 1 ){ - var handler = args[0]; - this.bind( params.event, handler ); - } - - // e.g. cy.nodes().select() - else if( args.length === 0 ){ - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( !params.ableField || ele._private[params.ableField] ){ - ele._private[params.field] = params.value; - } - } - this.updateStyle(); // change of state => possible change of style - this.trigger(params.event); - } - - return this; - }; - } - - function defineSwitchSet( params ){ - $$.elesfn[ params.field ] = function(){ - var ele = this[0]; - if( ele ){ - return ele._private[ params.field ]; - } - }; - - $$.elesfn[ params.on ] = defineSwitchFunction({ - event: params.on, - field: params.field, - ableField: params.ableField, - value: true - }); - - $$.elesfn[ params.off ] = defineSwitchFunction({ - event: params.off, - field: params.field, - ableField: params.ableField, - value: false - }); - } - - defineSwitchSet({ - field: "locked", - on: "lock", - off: "unlock" - }); - - defineSwitchSet({ - field: "grabbable", - on: "grabify", - off: "ungrabify" - }); - - defineSwitchSet({ - field: "selected", - ableField: "selectable", - on: "select", - off: "unselect" - }); - - defineSwitchSet({ - field: "selectable", - on: "selectify", - off: "unselectify" - }); - - $$.elesfn.grabbed = function(){ - var ele = this[0]; - if( ele ){ - return ele._private.grabbed; - } - }; - - defineSwitchSet({ - field: "active", - on: "activate", - off: "unactivate" - }); - - $$.elesfn.inactive = function(){ - var ele = this[0]; - if( ele ){ - return !ele._private.active; - } - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - $$.fn.eles({ - nodes: function(selector){ - return this.filter(function(i, element){ - return element.isNode(); - }).filter(selector); - }, - - edges: function(selector){ - return this.filter(function(i, element){ - return element.isEdge(); - }).filter(selector); - }, - - filter: function(filter){ - var cy = this._private.cy; - - if( $$.is.fn(filter) ){ - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - - if( filter.apply(ele, [i, ele]) ){ - elements.push(ele); - } - } - - return new $$.Collection(cy, elements); - - } else if( $$.is.string(filter) || $$.is.elementOrCollection(filter) ){ - return new $$.Selector(filter).filter(this); - - } else if( filter === undefined ){ - return this; - } - - return new $$.Collection( cy ); // if not handled by above, give 'em an empty collection - }, - - not: function(toRemove){ - var cy = this._private.cy; - - if( !toRemove ){ - return this; - } else { - - if( $$.is.string( toRemove ) ){ - toRemove = this.filter( toRemove ); - } - - var elements = []; - - for( var i = 0; i < this.length; i++ ){ - var element = this[i]; - - var remove = toRemove._private.ids[ element.id() ]; - if( !remove ){ - elements.push( element ); - } - } - - return new $$.Collection( cy, elements ); - } - - }, - - intersect: function( other ){ - var self = this; - var cy = this._private.cy; - - // if a selector is specified, then filter by it - if( $$.is.string(other) ){ - var selector = other; - return this.filter( selector ); - } - - var elements = []; - var col1 = this; - var col2 = other; - var col1Smaller = this.length < other.length; - var ids1 = col1Smaller ? col1._private.ids : col2._private.ids; - var ids2 = col1Smaller ? col2._private.ids : col1._private.ids; - - for( var id in ids1 ){ - var ele = ids2[ id ]; - - if( ele ){ - elements.push( ele ); - } - } - - return new $$.Collection( cy, elements ); - }, - - add: function(toAdd){ - var self = this; - var cy = this._private.cy; - - if( !toAdd ){ - return this; - } - - if( $$.is.string(toAdd) ){ - var selector = toAdd; - toAdd = cy.elements(selector); - } - - var elements = []; - var ids = {}; - - function add(element){ - if( !element ){ - return; - } - - if( !ids[ element.id() ] ){ - elements.push( element ); - ids[ element.id() ] = true; - } - } - - // add own - for( var i = 0; i < self.length; i++ ){ - var element = self[i]; - add(element); - } - - // add toAdd - for( var i = 0; i < toAdd.length; i++ ){ - var element = toAdd[i]; - add(element); - } - - return new $$.Collection(cy, elements); - } - }); - - $$.fn.eles({ - // do a breadth first search from the nodes in the collection - // from pseudocode on wikipedia - breadthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var Q = []; - var marked = {}; - var id2depth = {}; - var connectedFrom = {}; - var connectedEles = []; - - // enqueue v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - Q.unshift( v[i] ); - - // and mark v - marked[ v[i].id() ] = true; - - id2depth[ v[i].id() ] = 0; - - connectedEles.push( v[i] ); - } - } - - i = 0; - while( Q.length !== 0 ){ // while Q not empty - var t = Q.shift(); - var depth = 0; - - var fromNodeId = connectedFrom[ t.id() ]; - while( fromNodeId ){ - depth++; - fromNodeId = connectedFrom[ fromNodeId ]; - } - - id2depth[ t.id() ] = depth; - var ret = fn.call(t, i, depth); - i++; - - // on return true, return the result - if( ret === true ){ - return new $$.Collection( cy, [ t ] ); - } - - // on return false, stop iteration - else if( ret === false ){ - break; - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - - for( var j = 0; j < adjacentEdges.length; j++ ){ - var e = adjacentEdges[j]; - var u = e.connectedNodes('[id != "' + t.id() + '"]'); - - if( u.length !== 0 ){ - u = u[0]; - - if( !marked[ u.id() ] ){ - marked[ u.id() ] = true; // mark u - Q.unshift( u ); // enqueue u onto Q - - connectedFrom[ u.id() ] = t.id(); - - connectedEles.push( u ); - connectedEles.push( e ); - } - } - } - } - - return new $$.Collection( cy, connectedEles ); // return none - }, - - // do a depth first search on the nodes in the collection - // from pseudocode on wikipedia (iterative impl) - depthFirstSearch: function( fn, directed ){ - fn = fn || function(){}; - var cy = this._private.cy; - var v = this; - var S = []; - var discovered = []; - var forwardEdge = {}; - var backEdge = {}; - var crossEdge = {}; - var treeEdge = {}; - var explored = {}; - - function labelled(e){ - var id = e.id(); - return forwardEdge[id] || backEdge[id] || crossEdge[id] || treeEdge[id]; - } - - // push v - for( var i = 0; i < v.length; i++ ){ - if( v[i].isNode() ){ - S.push( v[i] ); - - // and mark discovered - discovered[ v[i].id() ] = true; - } - } - - while( S.length !== 0 ){ - var t = S[ S.length - 1 ]; - var ret = fn.call(t); - var breaked = false; - - if( ret === true ){ - return new $$.Collection( cy, [t] ); - } - - var adjacentEdges = t.connectedEdges(directed ? '[source = "' + t.id() + '"]' : undefined); - for( var i = 0; i < adjacentEdges.length; i++ ){ - var e = adjacentEdges[i]; - - if( labelled(e) ){ - continue; - } - - var w = e.connectedNodes('[id != "' + t.id() + '"]'); - if( w.length !== 0 ){ - w = w[0]; - var wid = w.id(); - - if( !discovered[wid] && !explored[wid] ){ - treeEdge[wid] = true; - discovered[wid] = true; - S.push(w); - breaked = true; - break; - } else if( discovered[wid] ){ - backEdge[wid] = true; - } else { - crossEdge[wid] = true; - } - } - } - - if( !breaked ){ - explored[ t.id() ] = true; - S.pop(); - } - } - }, - - // get the root nodes in the DAG - roots: function( selector ){ - var eles = this; - var roots = []; - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - if( !ele.isNode() ){ - continue; - } - - var hasEdgesPointingIn = ele.connectedEdges('[target = "' + ele.id() + '"][source != "' + ele.id() + '"]').length > 0; - - if( !hasEdgesPointingIn ){ - roots.push( ele ); - } - } - - return new $$.Collection( this._private.cy, roots ).filter( selector ); - }, - - // kruskal's algorithm (finds min spanning tree, assuming undirected graph) - // implemented from pseudocode from wikipedia - kruskal: function( weightFn ){ - weightFn = weightFn || function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - function findSet(ele){ - for( var i = 0; i < forest.length; i++ ){ - var eles = forest[i]; - - if( eles.anySame(ele) ){ - return { - eles: eles, - index: i - }; - } - } - } - - var A = new $$.Collection(this._private.cy, []); - var forest = []; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ - forest.push( nodes[i].collection() ); - } - - var edges = this.edges(); - var S = edges.toArray().sort(function(a, b){ - var weightA = weightFn.call(a); - var weightB = weightFn.call(b); - - return weightA - weightB; - }); - - for(var i = 0; i < S.length; i++){ - var edge = S[i]; - var u = edge.source()[0]; - var v = edge.target()[0]; - var setU = findSet(u); - var setV = findSet(v); - - if( setU.eles !== setV.eles ){ - A = A.add( edge ); - - forest[ setU.index ] = setU.eles.add( setV.eles ); - forest.splice( setV.index, 1 ); - } - } - - return nodes.add( A ); - - }, - - dijkstra: function( target, weightFn, directed ){ - var cy = this._private.cy; - directed = !$$.is.fn(weightFn) ? weightFn : directed; - directed = directed === undefined || directed; - weightFn = $$.is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1) - - if( this.length === 0 || !target || !$$.is.elementOrCollection(target) || target.length === 0 ){ - return new $$.Collection(cy, []); - } - - var source = this[0]; - target = target[0]; - var dist = {}; - var prev = {}; - - var nodes = cy.nodes(); - for( var i = 0; i < nodes.length; i++ ){ - dist[ nodes[i].id() ] = Infinity; - } - - dist[ source.id() ] = 0; - var Q = nodes; - - var smallestDist = function(Q){ - var smallest = Infinity; - var index; - for(var i in dist){ - if( dist[i] < smallest && Q.$('#' + i).length !== 0 ){ - smallest = dist[i]; - index = i; - } - } - - return index; - }; - - var distBetween = function(u, v){ - var edges = u.edgesWith(v); - var smallestDistance = Infinity; - var smallestEdge; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var weight = weightFn.call(edge); - - if( weight < smallestDistance ){ - smallestDistance = weight; - smallestEdge = edge; - } - } - - return { - edge: smallestEdge, - dist: smallestDistance - }; - }; - - while( Q.length !== 0 ){ - var uid = smallestDist(Q); - var u = Q.filter('#' + uid); - - if( u.length === 0 ){ - continue; - } - - //debugger; - - Q = Q.not( u ); - - if( u.same(target) ){ - break; - } - - if( dist[uid] === Math.Infinite ){ - break; - } - - var neighbors = u.neighborhood().nodes(); - for( var i = 0; i < neighbors.length; i++ ){ - var v = neighbors[i]; - var vid = v.id() - - var duv = distBetween(u, v); - var alt = dist[uid] + duv.dist; - if( alt < dist[vid] ){ - dist[vid] = alt; - prev[vid] = { - node: v, - edge: duv.edge - }; - // TODO decrease-key v in Q - } - } - } - } - }); - - // nice, short mathemathical alias - $$.elesfn.bfs = $$.elesfn.breadthFirstSearch; - $$.elesfn.dfs = $$.elesfn.depthFirstSearch; - - - - // Neighbourhood functions - ////////////////////////// - - $$.fn.eles({ - neighborhood: function(selector){ - var elements = []; - var cy = this._private.cy; - var nodes = this.nodes(); - - for( var i = 0; i < nodes.length; i++ ){ // for all nodes - var node = nodes[i]; - var connectedEdges = node.connectedEdges(); - - // for each connected edge, add the edge and the other node - for( var j = 0; j < connectedEdges.length; j++ ){ - var edge = connectedEdges[j]; - var otherNode = edge.connectedNodes().not(node); - - // need check in case of loop - if( otherNode.length > 0 ){ - elements.push( otherNode[0] ); // add node 1 hop away - } - - // add connected edge - elements.push( edge[0] ); - } - - } - - return ( new $$.Collection( cy, elements ) ).filter( selector ); - }, - - closedNeighborhood: function(selector){ - return this.neighborhood().add(this).filter(selector); - }, - - openNeighborhood: function(selector){ - return this.neighborhood(selector); - } - }); - - - // Edge functions - ///////////////// - - $$.fn.eles({ - source: defineSourceFunction({ - attr: "source" - }), - - target: defineSourceFunction({ - attr: "target" - }) - }); - - function defineSourceFunction( params ){ - return function( selector ){ - var sources = []; - var edges = this.edges(); - var cy = this._private.cy; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var id = edge._private.data[params.attr]; - var src = cy.getElementById( id ); - - if( src.length > 0 ){ - sources.push( src ); - } - } - - return new $$.Collection( cy, sources ).filter( selector ); - } - } - - $$.fn.eles({ - edgesWith: defineEdgesWithFunction(), - - edgesTo: defineEdgesWithFunction({ - thisIs: "source" - }) - }); - - function defineEdgesWithFunction( params ){ - - return function(otherNodes){ - var elements = []; - var cy = this._private.cy; - var p = params || {}; - - // get elements if a selector is specified - if( $$.is.string(otherNodes) ){ - otherNodes = cy.$( otherNodes ); - } - - var edges = otherNodes.connectedEdges(); - var thisIds = this._private.ids; - - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var foundId; - var edgeData = edge._private.data; - - if( p.thisIs ){ - var idToFind = edgeData[ p.thisIs ]; - foundId = thisIds[ idToFind ]; - } else { - foundId = thisIds[ edgeData.source ] || thisIds[ edgeData.target ]; - } - - if( foundId ){ - elements.push( edge ); - } - } - - return new $$.Collection( cy, elements ); - }; - } - - $$.fn.eles({ - connectedEdges: function( selector ){ - var retEles = []; - var cy = this._private.cy; - - var eles = this; - for( var i = 0; i < eles.length; i++ ){ - var node = eles[i]; - if( !node.isNode() ){ continue; } - - var edges = node._private.edges; - - for( var j = 0; j < edges.length; j++ ){ - var edge = edges[j]; - retEles.push( edge ); - } - } - - return new $$.Collection( cy, retEles ).filter( selector ); - }, - - connectedNodes: function( selector ){ - var retEles = []; - var cy = this._private.cy; - - var eles = this; - for( var i = 0; i < eles.length; i++ ){ - var edge = eles[i]; - if( !edge.isEdge() ){ continue; } - - retEles.push( edge.source()[0] ); - retEles.push( edge.target()[0] ); - } - - return new $$.Collection( cy, retEles ).filter( selector ); - }, - - parallelEdges: defineParallelEdgesFunction(), - - codirectedEdges: defineParallelEdgesFunction({ - codirected: true - }) - }); - - function defineParallelEdgesFunction(params){ - var defaults = { - codirected: false - }; - params = $$.util.extend({}, defaults, params); - - return function( selector ){ - var cy = this._private.cy; - var elements = []; - var edges = this.edges(); - var p = params; - - // look at all the edges in the collection - for( var i = 0; i < edges.length; i++ ){ - var edge1 = edges[i]; - var src1 = edge1.source()[0]; - var srcid1 = src1.id(); - var tgt1 = edge1.target()[0]; - var tgtid1 = tgt1.id(); - var srcEdges1 = src1._private.edges; - - // look at edges connected to the src node of this edge - for( var j = 0; j < srcEdges1.length; j++ ){ - var edge2 = srcEdges1[j]; - var edge2data = edge2._private.data; - var tgtid2 = edge2data.target; - var srcid2 = edge2data.source; - - var codirected = tgtid2 === tgtid1 && srcid2 === srcid1; - var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2; - - if( (p.codirected && codirected) - || (!p.codirected && (codirected || oppdirected)) ){ - elements.push( edge2 ); - } - } - } - - return new $$.Collection( cy, elements ).filter( selector ); - }; - - } - - - // Compound functions - ///////////////////// - - $$.fn.eles({ - parent: function( selector ){ - var parents = []; - var cy = this._private.cy; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - var parent = cy.getElementById( ele._private.data.parent ); - - if( parent.size() > 0 ){ - parents.push( parent ); - } - } - - return new $$.Collection( cy, parents ).filter( selector ); - }, - - parents: function( selector ){ - var parents = []; - - var eles = this.parent(); - while( eles.nonempty() ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - parents.push( ele ); - } - - eles = eles.parent(); - } - - return new $$.Collection( this.cy(), parents ).filter( selector ); - }, - - children: function( selector ){ - var children = []; - - for( var i = 0; i < this.length; i++ ){ - var ele = this[i]; - children = children.concat( ele._private.children ); - } - - return new $$.Collection( this.cy(), children ).filter( selector ); - }, - - siblings: function( selector ){ - return this.parent().children().not( this ).filter( selector ); - }, - - isParent: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.children.length !== 0; - } - }, - - isChild: function(){ - var ele = this[0]; - - if( ele ){ - return ele._private.data.parent !== undefined && ele.parent().length !== 0; - } - }, - - descendants: function( selector ){ - var elements = []; - - function add( eles ){ - for( var i = 0; i < eles.length; i++ ){ - var ele = eles[i]; - - elements.push( ele ); - - if( ele.children().nonempty() ){ - add( ele.children() ); - } - } - } - - add( this.children() ); - - return new $$.Collection( this.cy(), elements ).filter( selector ); - } - }); - - // aliases - $$.fn.eles.ancestors = $$.fn.eles.parents; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - function NullRenderer(options){ - } - - NullRenderer.prototype.notify = function(params){ - }; - - $$("renderer", "null", NullRenderer); - -})( cytoscape ); - -/* - The canvas renderer was written by Yue Dong. - - Modifications tracked on Github. -*/ - -(function($$) { "use strict"; - - function CanvasRenderer(options) { - - CanvasRenderer.CANVAS_LAYERS = 5; - CanvasRenderer.SELECT_BOX = 0; - CanvasRenderer.DRAG = 2; - CanvasRenderer.NODE = 4; - CanvasRenderer.BUFFER_COUNT = 2; - - this.options = options; - - this.data = { - - select: [undefined, undefined, undefined, undefined, 0], // Coordinates for selection box, plus enabled flag - renderer: this, cy: options.cy, container: options.cy.container(), - - canvases: new Array(CanvasRenderer.CANVAS_LAYERS), - canvasNeedsRedraw: new Array(CanvasRenderer.CANVAS_LAYERS), - - bufferCanvases: new Array(CanvasRenderer.BUFFER_COUNT) - - }; - - //--Pointer-related data - this.hoverData = {down: null, last: null, - downTime: null, triggerMode: null, - dragging: false, - initialPan: [null, null], capture: false}; - - this.timeoutData = {panTimeout: null}; - - this.dragData = {possibleDragElements: []}; - - this.touchData = {start: null, capture: false, - // These 3 fields related to tap, taphold events - startPosition: [null, null, null, null, null, null], - singleTouchStartTime: null, - singleTouchMoved: true, - - - now: [null, null, null, null, null, null], - earlier: [null, null, null, null, null, null] }; - //-- - - //--Wheel-related data - this.zoomData = {freeToZoom: false, lastPointerX: null}; - //-- - - this.redraws = 0; - - this.bindings = []; - - this.data.canvasContainer = document.createElement("div"); - var containerStyle = this.data.canvasContainer.style; - containerStyle.position = "absolute"; - containerStyle.zIndex = "0"; - - this.data.container.appendChild( this.data.canvasContainer ); - - for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) { - this.data.canvases[i] = document.createElement("canvas"); - this.data.canvases[i].style.position = "absolute"; - this.data.canvases[i].setAttribute("data-id", "layer" + i); - this.data.canvases[i].style.zIndex = String(CanvasRenderer.CANVAS_LAYERS - i); - this.data.canvasContainer.appendChild(this.data.canvases[i]); - - this.data.canvasNeedsRedraw[i] = false; - } - - this.data.canvases[CanvasRenderer.NODE].setAttribute("data-id", "layer" + CanvasRenderer.NODE + '-node'); - this.data.canvases[CanvasRenderer.SELECT_BOX].setAttribute("data-id", "layer" + CanvasRenderer.SELECT_BOX + '-selectbox'); - this.data.canvases[CanvasRenderer.DRAG].setAttribute("data-id", "layer" + CanvasRenderer.DRAG + '-drag'); - - for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) { - this.data.bufferCanvases[i] = document.createElement("canvas"); - this.data.bufferCanvases[i].style.position = "absolute"; - this.data.bufferCanvases[i].setAttribute("data-id", "buffer" + i); - this.data.bufferCanvases[i].style.zIndex = String(-i - 1); - this.data.bufferCanvases[i].style.visibility = "hidden"; - this.data.canvasContainer.appendChild(this.data.bufferCanvases[i]); - } - - this.hideEdgesOnViewport = options.hideEdgesOnViewport; - - this.load(); - } - - CanvasRenderer.panOrBoxSelectDelay = 400; - CanvasRenderer.isTouch = $$.is.touch(); - - CanvasRenderer.prototype.notify = function(params) { - switch( params.type ){ - - case "destroy": - this.destroy(); - return; - - case "add": - case "remove": - case "load": - this.updateNodesCache(); - this.updateEdgesCache(); - break; - - case "viewport": - this.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - break; - - case "style": - this.updateCachedZSortedEles(); - break; - } - - - this.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - this.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - - this.redraw(); - }; - - CanvasRenderer.prototype.destroy = function(){ - this.destroyed = true; - - for( var i = 0; i < this.bindings.length; i++ ){ - var binding = this.bindings[i]; - var b = binding; - - b.target.removeEventListener(b.event, b.handler, b.useCapture); - } - }; - - - - // copy the math functions into the renderer prototype - // unfortunately these functions are used interspersed t/o the code - // and this makes sure things work just in case a ref was missed in refactoring - // TODO remove this eventually - for( var fnName in $$.math ){ - CanvasRenderer.prototype[ fnName ] = $$.math[ fnName ]; - } - - - var debug = function(){}; - $$("renderer", "canvas", CanvasRenderer); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - var rendFunc = CanvasRenderer.prototype; - var arrowShapes = CanvasRenderer.arrowShapes = {}; - - CanvasRenderer.arrowShapeHeight = 0.3; - - // Contract for arrow shapes: - // 0, 0 is arrow tip - // (0, 1) is direction towards node - // (1, 0) is right - // - // functional api: - // collide: check x, y in shape - // roughCollide: called before collide, no false negatives - // draw: draw - // spacing: dist(arrowTip, nodeBoundary) - // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip - - arrowShapes["arrow"] = { - _points: [ - -0.15, -0.3, - 0, 0, - 0.15, -0.3 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["arrow"]._points; - -// console.log("collide(): " + direction); - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["arrow"]._farthestPointSqDistance) == "undefined") { - arrowShapes["arrow"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["arrow"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["arrow"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["arrow"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["triangle"] = arrowShapes["arrow"]; - - arrowShapes["none"] = { - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return false; - }, - draw: function(context) { - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return 0; - } - } - - arrowShapes["circle"] = { - _baseRadius: 0.15, - - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - // Transform x, y to get non-rotated ellipse - - if (width != height) { - // This gives negative of the angle - var angle = Math.asin(direction[1] / - (Math.sqrt(direction[0] * direction[0] - + direction[1] * direction[1]))); - - var cos = Math.cos(-angle); - var sin = Math.sin(-angle); - - var rotatedPoint = - [x * cos - y * sin, - y * cos + x * sin]; - - var aspectRatio = (height + padding) / (width + padding); - y /= aspectRatio; - centerY /= aspectRatio; - - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } else { - return (Math.pow(centerX - x, 2) - + Math.pow(centerY - y, 2) <= Math.pow((width + padding) - * arrowShapes["circle"]._baseRadius, 2)); - } - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - return true; - }, - draw: function(context) { - context.arc(0, 0, arrowShapes["circle"]._baseRadius, 0, Math.PI * 2, false); - }, - spacing: function(edge) { - return rendFunc.getArrowWidth(edge._private.style["width"].pxValue) - * arrowShapes["circle"]._baseRadius; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["inhibitor"] = { - _points: [ - -0.25, 0, - -0.25, -0.1, - 0.25, -0.1, - 0.25, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["inhibitor"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["inhibitor"]._farthestPointSqDistance) == "undefined") { - arrowShapes["inhibitor"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["inhibitor"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["inhibitor"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["inhibitor"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 4; - }, - gap: function(edge) { - return 4; - } - } - - arrowShapes["square"] = { - _points: [ - -0.12, 0.00, - 0.12, 0.00, - 0.12, -0.24, - -0.12, -0.24 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["square"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["square"]._farthestPointSqDistance) == "undefined") { - arrowShapes["square"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["square"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["square"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { - var points = arrowShapes["square"]._points; - - for (var i = 0; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["diamond"] = { - _points: [ - -0.14, -0.14, - 0, -0.28, - 0.14, -0.14, - 0, 0 - ], - collide: function(x, y, centerX, centerY, width, height, direction, padding) { - var points = arrowShapes["diamond"]._points; - - return $$.math.pointInsidePolygon( - x, y, points, centerX, centerY, width, height, direction, padding); - }, - roughCollide: function(x, y, centerX, centerY, width, height, direction, padding) { - if (typeof(arrowShapes["diamond"]._farthestPointSqDistance) == "undefined") { - arrowShapes["diamond"]._farthestPointSqDistance = - $$.math.findMaxSqDistanceToOrigin(arrowShapes["diamond"]._points); - } - - return $$.math.checkInBoundingCircle( - x, y, arrowShapes["diamond"]._farthestPointSqDistance, - 0, width, height, centerX, centerY); - }, - draw: function(context) { -// context.translate(0, 0.16); - context.lineTo(-0.14, -0.14); - context.lineTo(0, -0.28); - context.lineTo(0.14, -0.14); - context.lineTo(0, 0.0); - }, - spacing: function(edge) { - return 0; - }, - gap: function(edge) { - return edge._private.style["width"].pxValue * 2; - } - } - - arrowShapes["tee"] = arrowShapes["inhibitor"]; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.getCachedNodes = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - if (data.cache.cachedNodes == undefined) { - data.cache.cachedNodes = cy.nodes(); - } - - return data.cache.cachedNodes; - } - - CanvasRenderer.prototype.updateNodesCache = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - data.cache.cachedNodes = cy.nodes(); - } - - CanvasRenderer.prototype.getCachedEdges = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - if (data.cache.cachedEdges == undefined) { - data.cache.cachedEdges = cy.edges(); - } - - return data.cache.cachedEdges; - } - - CanvasRenderer.prototype.updateEdgesCache = function() { - var data = this.data; var cy = this.data.cy; - - if (data.cache == undefined) { - data.cache = {}; - } - - data.cache.cachedEdges = cy.edges(); - } - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Project mouse - CanvasRenderer.prototype.projectIntoViewport = function(pageX, pageY) { - - var n = this.data.container; - - var offsets = this.findContainerPageCoords(); - var offsetLeft = offsets[0]; - var offsetTop = offsets[1]; - -// console.log("calce"); - - // By here, offsetLeft and offsetTop represent the "pageX/pageY" of the top-left corner of the div. So, do subtraction to find relative position. - var x = pageX - offsetLeft; - var y = pageY - offsetTop; - - x -= this.data.cy.pan().x; y -= this.data.cy.pan().y; x /= this.data.cy.zoom(); y /= this.data.cy.zoom(); - return [x, y]; - } - - CanvasRenderer.prototype.findContainerPageCoords = function() { - var offsetLeft = 0; - var offsetTop = 0; - var container = this.data.container; - var n = container; - - while (n != null) { - var style = window.getComputedStyle(n); - if (typeof(n.offsetLeft) === "number") { - var position = style.getPropertyValue("position").toLowerCase(); - var borderLeft = parseFloat( style.getPropertyValue("border-left-width") ); - var borderTop = parseFloat( style.getPropertyValue("border-top-width") ); - - offsetLeft += n.offsetLeft; - offsetTop += n.offsetTop; - - if( position !== "static" || n === container ){ - offsetLeft += borderLeft; - offsetTop += borderTop; - } - - if( position === "fixed" ){ - offsetLeft += window.scrollX; - offsetTop += window.scrollY; - - break; // don't want to check any more parents after position:fixed - } - - if (n == document.body || n == document.header) { - // offsetLeft -= n.scrollLeft; - // offsetTop -= n.scrollTop; - - break; - } - } - - if( n ){ n = n.offsetParent }; - } - - // By here, offsetLeft and offsetTop represent the "pageX/pageY" of the top-left corner of the div. - return [offsetLeft, offsetTop]; - } - - // Find nearest element - CanvasRenderer.prototype.findNearestElement = function(x, y, visibleElementsOnly) { - var data = this.data; var nodes = this.getCachedNodes(); var edges = this.getCachedEdges(); var near = []; - var isTouch = CanvasRenderer.isTouch; - - var zoom = this.data.cy.zoom(); - var edgeThreshold = (isTouch ? 256 : 32) / zoom; - var nodeThreshold = (isTouch ? 16 : 0) / zoom; - - // Check nodes - for (var i = 0; i < nodes.length; i++) { - if (CanvasRenderer.nodeShapes[this.getNodeShape(nodes[i])].checkPointRough(x, y, - nodes[i]._private.style["border-width"].pxValue / 2, - this.getNodeWidth(nodes[i]) + nodeThreshold, this.getNodeHeight(nodes[i]) + nodeThreshold, - nodes[i]._private.position.x, nodes[i]._private.position.y) - && - CanvasRenderer.nodeShapes[this.getNodeShape(nodes[i])].checkPoint(x, y, - nodes[i]._private.style["border-width"].pxValue / 2, - (this.getNodeWidth(nodes[i]) + nodeThreshold), (this.getNodeHeight(nodes[i]) + nodeThreshold), - nodes[i]._private.position.x, nodes[i]._private.position.y)) { - - if (visibleElementsOnly) { - if (nodes[i]._private.style["opacity"].value != 0 - && nodes[i]._private.style["visibility"].value == "visible" - && nodes[i]._private.style["display"].value == "element") { - - near.push(nodes[i]); - } - } else { - near.push(nodes[i]); - } - } - } - - // Check edges - var addCurrentEdge; - for (var i = 0; i < edges.length; i++) { - var edge = edges[i]; - var rs = edge._private.rscratch; - - addCurrentEdge = false; - - if (rs.edgeType == "self") { - if (($$.math.inBezierVicinity(x, y, - rs.startX, - rs.startY, - rs.cp2ax, - rs.cp2ay, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - Math.pow(edge._private.style["width"].pxValue/2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue/2, 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2ax, - rs.cp2ay, - rs.selfEdgeMidX, - rs.selfEdgeMidY))) - || - ($$.math.inBezierVicinity(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].pxValue/2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue/2, 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.selfEdgeMidX, - rs.selfEdgeMidY, - rs.cp2cx, - rs.cp2cy, - rs.endX, - rs.endY)))) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "straight") { - if ($$.math.inLineVicinity(x, y, rs.startX, rs.startY, rs.endX, rs.endY, edges[i]._private.style["width"].pxValue * 2) - && - Math.pow(edges[i]._private.style["width"].pxValue / 2, 2) + edgeThreshold > - $$.math.sqDistanceToFiniteLine(x, y, - rs.startX, - rs.startY, - rs.endX, - rs.endY)) - { addCurrentEdge = true; } - - } else if (rs.edgeType == "bezier") { - if ($$.math.inBezierVicinity(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY, - Math.pow(edges[i]._private.style["width"].pxValue / 2, 2)) - && - (Math.pow(edges[i]._private.style["width"].pxValue / 2 , 2) + edgeThreshold > - $$.math.sqDistanceToQuadraticBezier(x, y, - rs.startX, - rs.startY, - rs.cp2x, - rs.cp2y, - rs.endX, - rs.endY))) - { addCurrentEdge = true; } - } - - if (!near.length || near[near.length - 1] != edges[i]) { - if ((CanvasRenderer.arrowShapes[edges[i]._private.style["source-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0) - && - CanvasRenderer.arrowShapes[edges[i]._private.style["source-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowStartX, edges[i]._private.rscratch.arrowStartY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowStartX - edges[i].source()[0]._private.position.x, - edges[i]._private.rscratch.arrowStartY - edges[i].source()[0]._private.position.y], 0)) - || - (CanvasRenderer.arrowShapes[edges[i]._private.style["target-arrow-shape"].value].roughCollide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0) - && - CanvasRenderer.arrowShapes[edges[i]._private.style["target-arrow-shape"].value].collide(x, y, - edges[i]._private.rscratch.arrowEndX, edges[i]._private.rscratch.arrowEndY, - this.getArrowWidth(edges[i]._private.style["width"].pxValue), - this.getArrowHeight(edges[i]._private.style["width"].pxValue), - [edges[i]._private.rscratch.arrowEndX - edges[i].target()[0]._private.position.x, - edges[i]._private.rscratch.arrowEndY - edges[i].target()[0]._private.position.y], 0))) - { addCurrentEdge = true; } - } - - if (addCurrentEdge) { - if (visibleElementsOnly) { - // For edges, make sure the edge is visible/has nonzero opacity, - // then also make sure both source and target nodes are visible/have - // nonzero opacity - var source = data.cy.getElementById(edges[i]._private.data.source) - var target = data.cy.getElementById(edges[i]._private.data.target) - - if (edges[i]._private.style["opacity"].value != 0 - && edges[i]._private.style["visibility"].value == "visible" - && edges[i]._private.style["display"].value == "element" - && source._private.style["opacity"].value != 0 - && source._private.style["visibility"].value == "visible" - && source._private.style["display"].value == "element" - && target._private.style["opacity"].value != 0 - && target._private.style["visibility"].value == "visible" - && target._private.style["display"].value == "element") { - - near.push(edges[i]); - } - } else { - near.push(edges[i]); - } - } - } - - near.sort( this.zOrderSort ); - - if (near.length > 0) { return near[ near.length - 1 ]; } else { return null; } - } - - // "Give me everything from this box" - CanvasRenderer.prototype.getAllInBox = function(x1, y1, x2, y2) { - var data = this.data; var nodes = this.getCachedNodes(); var edges = this.getCachedEdges(); var box = []; - - var x1c = Math.min(x1, x2); var x2c = Math.max(x1, x2); var y1c = Math.min(y1, y2); var y2c = Math.max(y1, y2); x1 = x1c; x2 = x2c; y1 = y1c; y2 = y2c; var heur; - - for (var i=0;i list of edges between them - var pairId; - for (var i = 0; i < edges.length; i++){ - var edge = edges[i]; - - // ignore edges who are not to be displayed - // they shouldn't take up space - if( edge._private.style.display.value === 'none' ){ - continue; - } - - var srcId = edge._private.data.source; - var tgtId = edge._private.data.target; - - pairId = srcId > tgtId ? - tgtId + '-' + srcId : - srcId + '-' + tgtId ; - - if (hashTable[pairId] == undefined) { - hashTable[pairId] = []; - } - - hashTable[pairId].push( edge ); - pairIds.push( pairId ); - } - - var src, tgt, srcPos, tgtPos, srcW, srcH, tgtW, tgtH, srcShape, tgtShape, srcBorder, tgtBorder; - var midpt; - var vectorNormInverse; - var badBezier; - - // for each pair (src, tgt), create the ctrl pts - // Nested for loop is OK; total number of iterations for both loops = edgeCount - for (var p = 0; p < pairIds.length; p++) { - pairId = pairIds[p]; - - src = cy.getElementById( hashTable[pairId][0]._private.data.source ); - tgt = cy.getElementById( hashTable[pairId][0]._private.data.target ); - - srcPos = src._private.position; - tgtPos = tgt._private.position; - - srcW = this.getNodeWidth(src); - srcH = this.getNodeHeight(src); - - tgtW = this.getNodeWidth(tgt); - tgtH = this.getNodeHeight(tgt); - - srcShape = CanvasRenderer.nodeShapes[ this.getNodeShape(src) ]; - tgtShape = CanvasRenderer.nodeShapes[ this.getNodeShape(tgt) ]; - - srcBorder = src._private.style["border-width"].pxValue; - tgtBorder = tgt._private.style["border-width"].pxValue; - - badBezier = false; - - - if (hashTable[pairId].length > 1) { - - // pt outside src shape to calc distance/displacement from src to tgt - var srcOutside = srcShape.intersectLine( - srcPos.x, - srcPos.y, - srcW, - srcH, - tgtPos.x, - tgtPos.y, - srcBorder / 2 - ); - - // pt outside tgt shape to calc distance/displacement from src to tgt - var tgtOutside = tgtShape.intersectLine( - tgtPos.x, - tgtPos.y, - tgtW, - tgtH, - srcPos.x, - srcPos.y, - tgtBorder / 2 - ); - - var midpt = { - x: ( srcOutside[0] + tgtOutside[0] )/2, - y: ( srcOutside[1] + tgtOutside[1] )/2 - }; - - var dy = ( tgtOutside[1] - srcOutside[1] ); - var dx = ( tgtOutside[0] - srcOutside[0] ); - var l = Math.sqrt( dx*dx + dy*dy ); - - var vector = { - x: dx, - y: dy - }; - - var vectorNorm = { - x: vector.x/l, - y: vector.y/l - }; - vectorNormInverse = { - x: -vectorNorm.y, - y: vectorNorm.x - }; - - // if src intersection is inside tgt or tgt intersection is inside src, then no ctrl pts to draw - if( - tgtShape.checkPoint( srcOutside[0], srcOutside[1], tgtBorder/2, tgtW, tgtH, tgtPos.x, tgtPos.y ) || - srcShape.checkPoint( tgtOutside[0], tgtOutside[1], srcBorder/2, srcW, srcH, srcPos.x, srcPos.y ) - ){ - vectorNormInverse = {}; - badBezier = true; - } - - } - - var edge; - var rs; - - for (var i = 0; i < hashTable[pairId].length; i++) { - edge = hashTable[pairId][i]; - rs = edge._private.rscratch; - - var edgeIndex1 = rs.lastEdgeIndex; - var edgeIndex2 = i; - - var numEdges1 = rs.lastNumEdges; - var numEdges2 = hashTable[pairId].length; - - var srcX1 = rs.lastSrcCtlPtX; - var srcX2 = srcPos.x; - var srcY1 = rs.lastSrcCtlPtY; - var srcY2 = srcPos.y; - var srcW1 = rs.lastSrcCtlPtW; - var srcW2 = src.outerWidth(); - var srcH1 = rs.lastSrcCtlPtH; - var srcH2 = src.outerHeight(); - - var tgtX1 = rs.lastTgtCtlPtX; - var tgtX2 = tgtPos.x; - var tgtY1 = rs.lastTgtCtlPtY; - var tgtY2 = tgtPos.y; - var tgtW1 = rs.lastTgtCtlPtW; - var tgtW2 = tgt.outerWidth(); - var tgtH1 = rs.lastTgtCtlPtH; - var tgtH2 = tgt.outerHeight(); - - if( badBezier ){ - rs.badBezier = true; - } else { - rs.badBezier = false; - } - - if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2 - && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2 - && edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2 ){ - // console.log('edge ctrl pt cache HIT') - continue; // then the control points haven't changed and we can skip calculating them - } else { - rs.lastSrcCtlPtX = srcX2; - rs.lastSrcCtlPtY = srcY2; - rs.lastSrcCtlPtW = srcW2; - rs.lastSrcCtlPtH = srcH2; - rs.lastTgtCtlPtX = tgtX2; - rs.lastTgtCtlPtY = tgtY2; - rs.lastTgtCtlPtW = tgtW2; - rs.lastTgtCtlPtH = tgtH2; - rs.lastEdgeIndex = edgeIndex2; - rs.lastNumEdges = numEdges2; - // console.log('edge ctrl pt cache MISS') - } - - var stepSize = edge._private.style["control-point-step-size"].value; - - // Self-edge - if ( src.id() == tgt.id() ) { - - rs.edgeType = "self"; - - // New -- fix for large nodes - rs.cp2ax = srcPos.x; - rs.cp2ay = srcPos.y - (1 + Math.pow(srcH, 1.12) / 100) * stepSize * (i / 3 + 1); - - rs.cp2cx = src._private.position.x - (1 + Math.pow(srcW, 1.12) / 100) * stepSize * (i / 3 + 1); - rs.cp2cy = srcPos.y; - - rs.selfEdgeMidX = (rs.cp2ax + rs.cp2cx) / 2.0; - rs.selfEdgeMidY = (rs.cp2ay + rs.cp2cy) / 2.0; - - // Straight edge - } else if (hashTable[pairId].length % 2 == 1 - && i == Math.floor(hashTable[pairId].length / 2)) { - - rs.edgeType = "straight"; - - // Bezier edge - } else { - var distanceFromMidpoint = (0.5 - hashTable[pairId].length / 2 + i) * stepSize; - - rs.edgeType = "bezier"; - - rs.cp2x = midpt.x + vectorNormInverse.x * distanceFromMidpoint; - rs.cp2y = midpt.y + vectorNormInverse.y * distanceFromMidpoint; - - // console.log(edge, midPointX, displacementX, distanceFromMidpoint); - } - - // find endpts for edge - this.findEndpoints( edge ); - - var badStart = !$$.is.number( rs.startX ) || !$$.is.number( rs.startY ); - var badAStart = !$$.is.number( rs.arrowStartX ) || !$$.is.number( rs.arrowStartY ); - var badEnd = !$$.is.number( rs.endX ) || !$$.is.number( rs.endY ); - var badAEnd = !$$.is.number( rs.arrowEndX ) || !$$.is.number( rs.arrowEndY ); - - var minCpADistFactor = 3; - var arrowW = this.getArrowWidth( edge._private.style['width'].pxValue ) * CanvasRenderer.arrowShapeHeight; - var minCpADist = minCpADistFactor * arrowW; - var startACpDist = $$.math.distance( { x: rs.cp2x, y: rs.cp2y }, { x: rs.startX, y: rs.startY } ); - var closeStartACp = startACpDist < minCpADist; - var endACpDist = $$.math.distance( { x: rs.cp2x, y: rs.cp2y }, { x: rs.endX, y: rs.endY } ); - var closeEndACp = endACpDist < minCpADist; - - if( rs.edgeType === "bezier" ){ - var overlapping = false; - - if( badStart || badAStart || closeStartACp ){ - overlapping = true; - - // project control point along line from src centre to outside the src shape - // (otherwise intersection will yield nothing) - var cpD = { // delta - x: rs.cp2x - srcPos.x, - y: rs.cp2y - srcPos.y - }; - var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line - var cpM = { // normalised delta - x: cpD.x / cpL, - y: cpD.y / cpL - }; - var radius = Math.max(srcW, srcH); - var cpProj = { // *2 radius guarantees outside shape - x: rs.cp2x + cpM.x * 2 * radius, - y: rs.cp2y + cpM.y * 2 * radius - }; - - var srcCtrlPtIntn = srcShape.intersectLine( - srcPos.x, - srcPos.y, - srcW, - srcH, - cpProj.x, - cpProj.y, - srcBorder / 2 - ); - - if( closeStartACp ){ - rs.cp2x = rs.cp2x + cpM.x * (minCpADist - startACpDist); - rs.cp2y = rs.cp2y + cpM.y * (minCpADist - startACpDist) - } else { - rs.cp2x = srcCtrlPtIntn[0] + cpM.x * minCpADist; - rs.cp2y = srcCtrlPtIntn[1] + cpM.y * minCpADist; - } - } - - if( badEnd || badAEnd || closeEndACp ){ - overlapping = true; - - // project control point along line from tgt centre to outside the tgt shape - // (otherwise intersection will yield nothing) - var cpD = { // delta - x: rs.cp2x - tgtPos.x, - y: rs.cp2y - tgtPos.y - }; - var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line - var cpM = { // normalised delta - x: cpD.x / cpL, - y: cpD.y / cpL - }; - var radius = Math.max(srcW, srcH); - var cpProj = { // *2 radius guarantees outside shape - x: rs.cp2x + cpM.x * 2 * radius, - y: rs.cp2y + cpM.y * 2 * radius - }; - - var tgtCtrlPtIntn = tgtShape.intersectLine( - tgtPos.x, - tgtPos.y, - tgtW, - tgtH, - cpProj.x, - cpProj.y, - tgtBorder / 2 - ); - - if( closeEndACp ){ - rs.cp2x = rs.cp2x + cpM.x * (minCpADist - endACpDist); - rs.cp2y = rs.cp2y + cpM.y * (minCpADist - endACpDist); - } else { - rs.cp2x = tgtCtrlPtIntn[0] + cpM.x * minCpADist; - rs.cp2y = tgtCtrlPtIntn[1] + cpM.y * minCpADist; - } - - } - - if( overlapping ){ - // recalc endpts - this.findEndpoints( edge ); - } - } - - // project the edge into rstyle - this.projectBezier( edge ); - - } - } - - return hashTable; - } - - CanvasRenderer.prototype.findEndpoints = function(edge) { - var intersect; - - var source = edge.source()[0]; - var target = edge.target()[0]; - - var srcPos = source._private.position; - var tgtPos = target._private.position; - - var tgtArShape = edge._private.style["target-arrow-shape"].value; - var srcArShape = edge._private.style["source-arrow-shape"].value; - - var tgtBorderW = target._private.style["border-width"].pxValue; - var srcBorderW = source._private.style["border-width"].pxValue; - - var rs = edge._private.rscratch; - - if (edge._private.rscratch.edgeType == "self") { - - var cp = [rs.cp2cx, rs.cp2cy]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], - cp[1], - tgtBorderW / 2 - ); - - var arrowEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - var cp = [rs.cp2ax, rs.cp2ay]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - srcBorderW / 2 - ); - - var arrowStart = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[srcArShape].spacing(edge)); - var edgeStart = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[srcArShape].gap(edge)); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - } else if (rs.edgeType == "straight") { - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - source.position().x, - source.position().y, - tgtBorderW / 2); - - if (intersect.length == 0) { - rs.noArrowPlacement = true; - // return; - } else { - rs.noArrowPlacement = false; - } - - var arrowEnd = $$.math.shortenIntersection(intersect, - [source.position().x, source.position().y], - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, - [source.position().x, source.position().y], - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - intersect = CanvasRenderer.nodeShapes[this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - target.position().x, - target.position().y, - srcBorderW / 2); - - if (intersect.length == 0) { - rs.noArrowPlacement = true; - // return; - } else { - rs.noArrowPlacement = false; - } - - /* - console.log("1: " - + CanvasRenderer.arrowShapes[srcArShape], - srcArShape); - */ - var arrowStart = $$.math.shortenIntersection(intersect, - [target.position().x, target.position().y], - CanvasRenderer.arrowShapes[srcArShape].spacing(edge)); - var edgeStart = $$.math.shortenIntersection(intersect, - [target.position().x, target.position().y], - CanvasRenderer.arrowShapes[srcArShape].gap(edge)); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - } else if (rs.edgeType == "bezier") { - // if( window.badArrow) debugger; - var cp = [rs.cp2x, rs.cp2y]; - - intersect = CanvasRenderer.nodeShapes[ - this.getNodeShape(target)].intersectLine( - target._private.position.x, - target._private.position.y, - this.getNodeWidth(target), - this.getNodeHeight(target), - cp[0], //halfPointX, - cp[1], //halfPointY - tgtBorderW / 2 - ); - - /* - console.log("2: " - + CanvasRenderer.arrowShapes[srcArShape], - srcArShape); - */ - var arrowEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].spacing(edge)); - var edgeEnd = $$.math.shortenIntersection(intersect, cp, - CanvasRenderer.arrowShapes[tgtArShape].gap(edge)); - - rs.endX = edgeEnd[0]; - rs.endY = edgeEnd[1]; - - rs.arrowEndX = arrowEnd[0]; - rs.arrowEndY = arrowEnd[1]; - - intersect = CanvasRenderer.nodeShapes[ - this.getNodeShape(source)].intersectLine( - source._private.position.x, - source._private.position.y, - this.getNodeWidth(source), - this.getNodeHeight(source), - cp[0], //halfPointX, - cp[1], //halfPointY - srcBorderW / 2 - ); - - var arrowStart = $$.math.shortenIntersection( - intersect, - cp, - CanvasRenderer.arrowShapes[srcArShape].spacing(edge) - ); - var edgeStart = $$.math.shortenIntersection( - intersect, - cp, - CanvasRenderer.arrowShapes[srcArShape].gap(edge) - ); - - rs.startX = edgeStart[0]; - rs.startY = edgeStart[1]; - - rs.arrowStartX = arrowStart[0]; - rs.arrowStartY = arrowStart[1]; - - // if( isNaN(rs.startX) || isNaN(rs.startY) ){ - // debugger; - // } - - } else if (rs.isArcEdge) { - return; - } - } - - // Find adjacent edges - CanvasRenderer.prototype.findEdges = function(nodeSet) { - - var edges = this.getCachedEdges(); - - var hashTable = {}; - var adjacentEdges = []; - - for (var i = 0; i < nodeSet.length; i++) { - hashTable[nodeSet[i]._private.data.id] = nodeSet[i]; - } - - for (var i = 0; i < edges.length; i++) { - if (hashTable[edges[i]._private.data.source] - || hashTable[edges[i]._private.data.target]) { - - adjacentEdges.push(edges[i]); - } - } - - return adjacentEdges; - } - - CanvasRenderer.prototype.getArrowWidth = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - CanvasRenderer.prototype.getArrowHeight = function(edgeWidth) { - return Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); - } - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - -// Draw edge - CanvasRenderer.prototype.drawEdge = function(context, edge, drawOverlayInstead) { - - if( !edge.visible() ){ - return; - } - - if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching - - var rs = edge._private.rscratch; - - // if bezier ctrl pts can not be calculated, then die - if( rs.badBezier ){ - return; - } - - var startNode, endNode; - - startNode = edge.source()[0]; - endNode = edge.target()[0]; - - if ( - edge._private.style["visibility"].value != "visible" - || edge._private.style["display"].value != "element" - || startNode._private.style["visibility"].value != "visible" - || startNode._private.style["display"].value != "element" - || endNode._private.style["visibility"].value != "visible" - || endNode._private.style["display"].value != "element" - ){ - return; - } - - var overlayPadding = edge._private.style["overlay-padding"].pxValue; - var overlayOpacity = edge._private.style["overlay-opacity"].value; - var overlayColor = edge._private.style["overlay-color"].value; - - // Edge color & opacity - if( drawOverlayInstead ){ - context.strokeStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - context.lineCap = "round"; - - if( edge._private.rscratch.edgeType == "self"){ - context.lineCap = "butt"; - } - - } else { - context.strokeStyle = "rgba(" - + edge._private.style["line-color"].value[0] + "," - + edge._private.style["line-color"].value[1] + "," - + edge._private.style["line-color"].value[2] + "," - + edge._private.style.opacity.value + ")"; - - - context.lineCap = "butt"; - } - - // Edge line width - if (edge._private.style["width"].pxValue <= 0) { - return; - } - - var edgeWidth = edge._private.style["width"].pxValue + (drawOverlayInstead ? 2 * overlayPadding : 0); - var lineStyle = drawOverlayInstead ? "solid" : edge._private.style["line-style"].value; - context.lineWidth = edgeWidth; - - this.findEndpoints(edge); - - if (edge._private.rscratch.edgeType == "self") { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, details.cp2ax, - details.cp2ay, details.selfEdgeMidX, details.selfEdgeMidY], - lineStyle, - edgeWidth); - - this.drawStyledEdge(edge, context, [details.selfEdgeMidX, details.selfEdgeMidY, - details.cp2cx, details.cp2cy, details.endX, details.endY], - lineStyle, - edgeWidth); - - // DEBUG: draw projected bezier pts - // context.fillStyle = 'red'; - // var bpts = edge._private.rstyle.bezierPts; - // for( var i = 0; i < bpts.length; i++ ){ - // var pt = bpts[i]; - - // context.fillRect(pt.x, pt.y, 2, 2); - // } - - } else if (edge._private.rscratch.edgeType == "straight") { - - var nodeDirectionX = endNode._private.position.x - startNode._private.position.x; - var nodeDirectionY = endNode._private.position.y - startNode._private.position.y; - - var edgeDirectionX = edge._private.rscratch.endX - edge._private.rscratch.startX; - var edgeDirectionY = edge._private.rscratch.endY - edge._private.rscratch.startY; - - if (nodeDirectionX * edgeDirectionX - + nodeDirectionY * edgeDirectionY < 0) { - - edge._private.rscratch.straightEdgeTooShort = true; - } else { - - var details = edge._private.rscratch; - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.endX, details.endY], - lineStyle, - edgeWidth); - - edge._private.rscratch.straightEdgeTooShort = false; - } - } else { - - var details = edge._private.rscratch; - - // context.fillStyle = 'rgba(255, 0, 0, 1)'; - // context.fillRect(details.startX, details.startY, 2, 2); - // context.fillRect(details.endX, details.endY, 2, 2); - - // context.fillStyle = edge._private.style['line-color'].strValue; - // context.fillRect(details.cp2x, details.cp2y, 2, 2); - - - this.drawStyledEdge(edge, context, [details.startX, details.startY, - details.cp2x, details.cp2y, details.endX, details.endY], - lineStyle, - edgeWidth); - - // DEBUG: draw projected bezier pts - // context.fillStyle = 'red'; - // var bpts = edge._private.rstyle.bezierPts; - // for( var i = 0; i < bpts.length; i++ ){ - // var pt = bpts[i]; - - // context.fillRect(pt.x, pt.y, 2, 2); - // } - - } - - if (edge._private.rscratch.noArrowPlacement !== true - && edge._private.rscratch.startX !== undefined) { - this.drawArrowheads(context, edge, drawOverlayInstead); - } - - } - - var _genPoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[4] - pt[0], 2) + Math.pow(pt[5] - pt[1], 2)); - approxLen += Math.sqrt(Math.pow((pt[4] + pt[0]) / 2 - pt[2], 2) + Math.pow((pt[5] + pt[1]) / 2 - pt[3], 2)); - - var pts = Math.ceil(approxLen / spacing); var inc = approxLen / spacing; - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = pt[0] * (1 - cur) * (1 - cur) + 2 * (pt[2]) * (1 - cur) * cur + pt[4] * (cur) * (cur); - pz[i * 2 + 1] = pt[1] * (1 - cur) * (1 - cur) + 2 * (pt[3]) * (1 - cur) * cur + pt[5] * (cur) * (cur); - } - - return pz; - } - - var _genStraightLinePoints = function(pt, spacing, even) { - - var approxLen = Math.sqrt(Math.pow(pt[2] - pt[0], 2) + Math.pow(pt[3] - pt[1], 2)); - - var pts = Math.ceil(approxLen / spacing); - var pz; - - if (pts > 0) { - pz = new Array(pts * 2); - } else { - return null; - } - - var lineOffset = [pt[2] - pt[0], pt[3] - pt[1]]; - for (var i = 0; i < pts; i++) { - var cur = i / pts; - pz[i * 2] = lineOffset[0] * cur + pt[0]; - pz[i * 2 + 1] = lineOffset[1] * cur + pt[1]; - } - - return pz; - } - - var _genEvenOddpts = function(pt, evenspac, oddspac) { - - pt1 = _genpts(pt, evenspac); - pt2 = _genpts(pt, oddspac); - } - - - CanvasRenderer.prototype.drawStyledEdge = function( - edge, context, pts, type, width) { - - // 3 points given -> assume Bezier - // 2 -> assume straight - - var cy = this.data.cy; - var zoom = cy.zoom(); - - - // Adjusted edge width for dotted -// width = Math.max(width * 1.6, 3.4) * zoom; - - // console.log("w", width); - - if (type == "solid") { - - context.beginPath(); - context.moveTo(pts[0], pts[1]); - if (pts.length == 3 * 2) { - context.quadraticCurveTo(pts[2], pts[3], pts[4], pts[5]); - } else { - context.lineTo(pts[2], pts[3]); - } -// context.closePath(); - context.stroke(); - - } else if (type == "dotted") { - - var pt; - if (pts.length == 3 * 2) { - pt = _genPoints(pts, 16, true); - } else { - pt = _genStraightLinePoints(pts, 16, true); - } - - if (!pt) { return; } - - var dotRadius = Math.max(width * 1.6, 3.4) * zoom; - var bufW = dotRadius * 2, bufH = dotRadius * 2; - bufW = Math.max(bufW, 1); - bufH = Math.max(bufH, 1); - - var buffer = this.createBuffer(bufW, bufH); - - var context2 = buffer[1]; -// console.log(buffer); -// console.log(bufW, bufH); - - // Draw on buffer - context2.setTransform(1, 0, 0, 1, 0, 0); - context2.clearRect(0, 0, bufW, bufH); - - context2.fillStyle = context.strokeStyle; - context2.beginPath(); - context2.arc(bufW/2, bufH/2, dotRadius * 0.5, 0, Math.PI * 2, false); - context2.fill(); - - // Now use buffer - context.beginPath(); - //context.save(); - - for (var i=0; i 0) { - context.stroke(); - } - - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Draw edge text - CanvasRenderer.prototype.drawEdgeText = function(context, edge) { - - if( !edge.visible() ){ - return; - } - - if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching - - var computedSize = edge._private.style["font-size"].pxValue * edge.cy().zoom(); - var minSize = edge._private.style["min-zoomed-font-size"].pxValue; - - if( computedSize < minSize ){ - return; - } - - // Calculate text draw position - - context.textAlign = "center"; - context.textBaseline = "middle"; - - this.recalculateEdgeLabelProjection( edge ); - - var rs = edge._private.rscratch; - this.drawText(context, edge, rs.labelX, rs.labelY); - }; - - // Draw node text - CanvasRenderer.prototype.drawNodeText = function(context, node) { - - if ( !node.visible() ) { - return; - } - - var computedSize = node._private.style["font-size"].pxValue * node.cy().zoom(); - var minSize = node._private.style["min-zoomed-font-size"].pxValue; - - if( computedSize < minSize ){ - return; - } - - this.recalculateNodeLabelProjection( node ); - - var textHalign = node._private.style["text-halign"].strValue; - var textValign = node._private.style["text-valign"].strValue; - var rs = node._private.rscratch; - - switch( textHalign ){ - case "left": - context.textAlign = "right"; - break; - - case "right": - context.textAlign = "left"; - break; - - case "center": - default: - context.textAlign = "center"; - } - - switch( textValign ){ - case "top": - context.textBaseline = "bottom"; - break; - - case "bottom": - context.textBaseline = "top"; - break; - - case "center": - default: - context.textBaseline = "middle"; - } - - this.drawText(context, node, rs.labelX, rs.labelY); - }; - - // set up canvas context with font - // returns transformed text string - CanvasRenderer.prototype.setupTextStyle = function( context, element ){ - // Font style - var parentOpacity = element.effectiveOpacity(); - var style = element._private.style; - var labelStyle = style["font-style"].strValue; - var labelSize = style["font-size"].pxValue + "px"; - var labelFamily = style["font-family"].strValue; - var labelVariant = style["font-variant"].strValue; - var labelWeight = style["font-weight"].strValue; - - context.font = labelStyle + " " + labelWeight + " " - + labelSize + " " + labelFamily; - - var text = String(style["content"].value); - var textTransform = style["text-transform"].value; - - if (textTransform == "none") { - } else if (textTransform == "uppercase") { - text = text.toUpperCase(); - } else if (textTransform == "lowercase") { - text = text.toLowerCase(); - } - - // Calculate text draw position based on text alignment - - // so text outlines aren't jagged - context.lineJoin = 'round'; - - context.fillStyle = "rgba(" - + style["color"].value[0] + "," - + style["color"].value[1] + "," - + style["color"].value[2] + "," - + (style["text-opacity"].value - * style["opacity"].value * parentOpacity) + ")"; - - context.strokeStyle = "rgba(" - + style["text-outline-color"].value[0] + "," - + style["text-outline-color"].value[1] + "," - + style["text-outline-color"].value[2] + "," - + (style["text-opacity"].value - * style["opacity"].value * parentOpacity) + ")"; - - return text; - } - - // Draw text - CanvasRenderer.prototype.drawText = function(context, element, textX, textY) { - var style = element._private.style; - var parentOpacity = element.effectiveOpacity(); - if( parentOpacity === 0 ){ return; } - - var text = this.setupTextStyle( context, element ); - - if ( text != undefined && !isNaN(textX) && !isNaN(textY) ) { - var lineWidth = 2 * style["text-outline-width"].value; // *2 b/c the stroke is drawn centred on the middle - if (lineWidth > 0) { - context.lineWidth = lineWidth; - context.strokeText(text, textX, textY); - } - - context.fillText("" + text, textX, textY); - } - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - // Draw node - CanvasRenderer.prototype.drawNode = function(context, node, drawOverlayInstead) { - - var nodeWidth, nodeHeight; - - if ( !node.visible() ) { - return; - } - - var parentOpacity = node.effectiveOpacity(); - if( parentOpacity === 0 ){ return; } - - // context.fillStyle = "orange"; - // context.fillRect(node.position().x, node.position().y, 2, 2); - - nodeWidth = this.getNodeWidth(node); - nodeHeight = this.getNodeHeight(node); - - context.lineWidth = node._private.style["border-width"].pxValue; - - if( drawOverlayInstead === undefined || !drawOverlayInstead ){ - - // Node color & opacity - context.fillStyle = "rgba(" - + node._private.style["background-color"].value[0] + "," - + node._private.style["background-color"].value[1] + "," - + node._private.style["background-color"].value[2] + "," - + (node._private.style["background-opacity"].value - * node._private.style["opacity"].value * parentOpacity) + ")"; - - // Node border color & opacity - context.strokeStyle = "rgba(" - + node._private.style["border-color"].value[0] + "," - + node._private.style["border-color"].value[1] + "," - + node._private.style["border-color"].value[2] + "," - + (node._private.style["border-opacity"].value * node._private.style["opacity"].value * parentOpacity) + ")"; - - context.lineJoin = 'miter'; // so borders are square with the node shape - - //var image = this.getCachedImage("url"); - - var url = node._private.style["background-image"].value[2] || - node._private.style["background-image"].value[1]; - - if (url != undefined) { - - var r = this; - var image = this.getCachedImage(url, - - function() { - -// console.log(e); - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - - // Replace Image object with Canvas to solve zooming too far - // into image graphical errors (Jan 10 2013) - r.swapCachedImage(url); - - r.redraw(); - } - ); - - if (image.complete == false) { - - CanvasRenderer.nodeShapes[r.getNodeShape(node)].drawPath( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, nodeHeight); - //node._private.style["width"].value, - //node._private.style["height"].value); - - context.stroke(); - context.fillStyle = "#555555"; - context.fill(); - - } else { - //context.clip - this.drawInscribedImage(context, image, node); - } - - } else { - - // Draw node - CanvasRenderer.nodeShapes[this.getNodeShape(node)].draw( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, - nodeHeight); //node._private.data.weight / 5.0 - } - - this.drawPie(context, node); - - // Border width, draw border - if (node._private.style["border-width"].pxValue > 0) { - CanvasRenderer.nodeShapes[this.getNodeShape(node)].drawPath( - context, - node._private.position.x, - node._private.position.y, - nodeWidth, - nodeHeight) - ; - - context.stroke(); - } - - // draw the overlay - } else { - - var overlayPadding = node._private.style["overlay-padding"].pxValue; - var overlayOpacity = node._private.style["overlay-opacity"].value; - var overlayColor = node._private.style["overlay-color"].value; - if( overlayOpacity > 0 ){ - context.fillStyle = "rgba( " + overlayColor[0] + ", " + overlayColor[1] + ", " + overlayColor[2] + ", " + overlayOpacity + " )"; - - CanvasRenderer.nodeShapes['roundrectangle'].draw( - context, - node._private.position.x, - node._private.position.y, - nodeWidth + overlayPadding * 2, - nodeHeight + overlayPadding * 2 - ); - } - } - - }; - - // does the node have at least one pie piece? - CanvasRenderer.prototype.hasPie = function(node){ - node = node[0]; // ensure ele ref - - for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N - var size = node._private.style['pie-' + i + '-background-size'].value; - - if( size > 0 ){ - return true; - } - } - - return false; - }; - - CanvasRenderer.prototype.drawPie = function(context, node){ - node = node[0]; // ensure ele ref - - if( !this.hasPie(node) ){ return; } // exit early if not needed - - var nodeW = this.getNodeWidth( node ); - var nodeH = this.getNodeHeight( node ); - var x = node._private.position.x; - var y = node._private.position.y; - var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node - var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1] - - context.save(); - - // clip to the node shape - CanvasRenderer.nodeShapes[ this.getNodeShape(node) ] - .drawPath( context, x, y, nodeW, nodeH ) - ; - context.clip(); - - for( var i = 1; i <= $$.style.pieBackgroundN; i++ ){ // 1..N - var size = node._private.style['pie-' + i + '-background-size'].value; - var color = node._private.style['pie-' + i + '-background-color']; - var percent = size / 100; // map integer range [0, 100] to [0, 1] - var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise - var angleDelta = 2 * Math.PI * percent; - var angleEnd = angleStart + angleDelta; - - // slice start and end points - var sx1 = x + radius * Math.cos( angleStart ); - var sy1 = y + radius * Math.sin( angleStart ); - - // ignore if - // - zero size - // - we're already beyond the full circle - // - adding the current slice would go beyond the full circle - if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){ - continue; - } - - context.beginPath(); - context.moveTo(x, y); - context.arc( x, y, radius, angleStart, angleEnd ); - context.closePath(); - - context.fillStyle = 'rgb(' - + color.value[0] + ',' - + color.value[1] + ',' - + color.value[2] + ')' - ; - - context.fill(); - - lastPercent += percent; - } - - context.restore(); - }; - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.getPixelRatio = function(){ - var canvas = this.data.canvases[0]; - var context = canvas.getContext("2d"); - - var backingStore = context.backingStorePixelRatio || - context.webkitBackingStorePixelRatio || - context.mozBackingStorePixelRatio || - context.msBackingStorePixelRatio || - context.oBackingStorePixelRatio || - context.backingStorePixelRatio || 1; - - //console.log(window.devicePixelRatio, backingStore); - - var isFirefox = typeof InstallTrigger !== 'undefined'; - - if( isFirefox ){ // because ff can't scale canvas properly - return 1; - } - - return (window.devicePixelRatio || 1) / backingStore; - } - - // Resize canvas - CanvasRenderer.prototype.matchCanvasSize = function(container) { - var data = this.data; var width = container.clientWidth; var height = container.clientHeight; - - var canvas, canvasWidth = width, canvasHeight = height; - var pixelRatio = this.getPixelRatio(); - - // apply pixel ratio - canvasWidth *= pixelRatio; - canvasHeight *= pixelRatio; - - var canvasContainer = data.canvasContainer; - canvasContainer.style.width = width + 'px'; - canvasContainer.style.height = height + 'px'; - - for (var i = 0; i < CanvasRenderer.CANVAS_LAYERS; i++) { - - canvas = data.canvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - - canvas.style.width = width + 'px'; - canvas.style.height = height + 'px'; - } - } - - for (var i = 0; i < CanvasRenderer.BUFFER_COUNT; i++) { - - canvas = data.bufferCanvases[i]; - - if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { - - canvas.width = canvasWidth; - canvas.height = canvasHeight; - } - } - - } - - CanvasRenderer.prototype.renderTo = function( cxt, zoom, pan ){ - this.redraw({ - forcedContext: cxt, - forcedZoom: zoom, - forcedPan: pan, - drawAllLayers: true - }); - }; - - // Redraw frame - CanvasRenderer.prototype.redraw = function( options ) { - options = options || {}; - - var forcedContext = options.forcedContext; - var drawAllLayers = options.drawAllLayers; - var forcedZoom = options.forcedZoom; - var forcedPan = options.forcedPan; - var r = this; - var pixelRatio = this.getPixelRatio(); - var cy = r.data.cy; var data = r.data; - - clearTimeout( this.redrawTimeout ); - - if( this.averageRedrawTime === undefined ){ this.averageRedrawTime = 0; } - - var minRedrawLimit = 1000/60; // people can't see much better than 60fps - var maxRedrawLimit = 1000; // don't cap max b/c it's more important to be responsive than smooth - - var redrawLimit = this.averageRedrawTime; // estimate the ideal redraw limit based on how fast we can draw - redrawLimit = Math.max(minRedrawLimit, redrawLimit); - redrawLimit = Math.min(redrawLimit, maxRedrawLimit); - - //console.log('--\nideal: %i; effective: %i', this.averageRedrawTime, redrawLimit); - - if( this.lastDrawTime === undefined ){ this.lastDrawTime = 0; } - - var nowTime = +new Date; - var timeElapsed = nowTime - this.lastDrawTime; - var callAfterLimit = timeElapsed >= redrawLimit; - - if( !forcedContext ){ - if( !callAfterLimit ){ - clearTimeout( this.redrawTimeout ); - this.redrawTimeout = setTimeout(function(){ - r.redraw(); - }, redrawLimit); - return; - } - - this.lastDrawTime = nowTime; - } - - - var startTime = nowTime; - - var looperMax = 100; - //console.log('-- redraw --') - - // console.time('init'); for( var looper = 0; looper <= looperMax; looper++ ){ - - - // } console.timeEnd('init') - - function drawToContext(){ - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - - if( !forcedContext ){ - r.matchCanvasSize(data.container); - } - - var zoom = cy.zoom(); - var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom; - var pan = cy.pan(); - var effectivePan = { - x: pan.x, - y: pan.y - }; - - if( forcedPan ){ - effectivePan = forcedPan; - } - - // apply pixel ratio - effectiveZoom *= pixelRatio; - effectivePan.x *= pixelRatio; - effectivePan.y *= pixelRatio; - - var elements; - var elesInDragLayer; - var elesNotInDragLayer; - var element; - - function setContextTransform(context){ - context.setTransform(1, 0, 0, 1, 0, 0); - !forcedContext && context.clearRect(0, 0, context.canvas.width, context.canvas.height); - - if( !drawAllLayers ){ - context.translate(effectivePan.x, effectivePan.y); - context.scale(effectiveZoom, effectiveZoom); - } - if( forcedPan ){ - context.translate(forcedPan.x, forcedPan.y); - } - if( forcedZoom ){ - context.scale(forcedZoom, forcedZoom); - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) { - //NB : VERY EXPENSIVE - //console.time('edgectlpts'); for( var looper = 0; looper <= looperMax; looper++ ){ - - if( r.hideEdgesOnViewport && (r.pinching || r.hoverData.dragging || r.data.wheel || r.swipePanning) ){ - } else { - r.findEdgeControlPoints(edges); - } - - //} console.timeEnd('edgectlpts') - - - - // console.time('sort'); for( var looper = 0; looper <= looperMax; looper++ ){ - elements = r.getCachedZSortedEles(); - // } console.timeEnd('sort') - - elesInDragLayer = []; - elesNotInDragLayer = []; - - for (var index = 0; index < elements.length; index++) { - element = elements[index]; - - if ( element._private.rscratch.inDragLayer ) { - elesInDragLayer.push( element ); - } else { - elesNotInDragLayer.push( element ); - } - } - - // console.time('updatecompounds'); for( var looper = 0; looper <= looperMax; looper++ ){ - // no need to update graph if there is no compound node - // if ( cy.hasCompoundNodes() ) - // { - // r.updateAllCompounds(elements); - // } - // } console.timeEnd('updatecompounds') - } - - - function drawElements( eleList, context ){ - var edges = []; - var nodes = []; - - for (var i = 0; i < eleList.length; i++) { - ele = eleList[i]; - - if ( ele.isNode() ) { - nodes.push( ele ); - - } else if ( ele.isEdge() ) { - r.drawEdge(context, ele); - edges.push( ele ); - } - } - - for (var i = 0; i < edges.length; i++) { - ele = edges[i]; - - r.drawEdgeText(context, ele); - r.drawEdge(context, ele, true); - } - - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - - r.drawNode(context, ele); - r.drawNodeText(context, ele); - r.drawNode(context, ele, true); - } - } - - - // console.time('drawing'); for( var looper = 0; looper <= looperMax; looper++ ){ - if (data.canvasNeedsRedraw[CanvasRenderer.NODE] || drawAllLayers) { - // console.log("redrawing node layer"); - - var context = forcedContext || data.canvases[CanvasRenderer.NODE].getContext("2d"); - - setContextTransform( context ); - drawElements(elesNotInDragLayer, context); - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.NODE] = false; - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.DRAG] || drawAllLayers) { - - var context = forcedContext || data.canvases[CanvasRenderer.DRAG].getContext("2d"); - - setContextTransform( context ); - drawElements(elesInDragLayer, context); - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.DRAG] = false; - } - } - - if (data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] && !drawAllLayers) { - // console.log("redrawing selection box"); - - var context = forcedContext || data.canvases[CanvasRenderer.SELECT_BOX].getContext("2d"); - - setContextTransform( context ); - - var coreStyle = cy.style()._private.coreStyle; - - if (data.select[4] == 1) { - var zoom = data.cy.zoom(); - var borderWidth = coreStyle["selection-box-border-width"].value / zoom; - - context.lineWidth = borderWidth; - context.fillStyle = "rgba(" - + coreStyle["selection-box-color"].value[0] + "," - + coreStyle["selection-box-color"].value[1] + "," - + coreStyle["selection-box-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.fillRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - - if (borderWidth > 0) { - context.strokeStyle = "rgba(" - + coreStyle["selection-box-border-color"].value[0] + "," - + coreStyle["selection-box-border-color"].value[1] + "," - + coreStyle["selection-box-border-color"].value[2] + "," - + coreStyle["selection-box-opacity"].value + ")"; - - context.strokeRect( - data.select[0], - data.select[1], - data.select[2] - data.select[0], - data.select[3] - data.select[1]); - } - } - - if( data.bgActivePosistion ){ - var zoom = data.cy.zoom(); - var pos = data.bgActivePosistion; - - context.fillStyle = "rgba(" - + coreStyle["active-bg-color"].value[0] + "," - + coreStyle["active-bg-color"].value[1] + "," - + coreStyle["active-bg-color"].value[2] + "," - + coreStyle["active-bg-opacity"].value + ")"; - - context.beginPath(); - context.arc(pos.x, pos.y, coreStyle["active-bg-size"].pxValue / zoom, 0, 2 * Math.PI); - context.fill(); - } - - if( !drawAllLayers ){ - data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = false; - } - } - - // } console.timeEnd('drawing') - - var endTime = +new Date; - - if( r.averageRedrawTime === undefined ){ - r.averageRedrawTime = endTime - startTime; - } - - // use a weighted average with a bias from the previous average so we don't spike so easily - r.averageRedrawTime = r.averageRedrawTime/2 + (endTime - startTime)/2; - //console.log('actual: %i, average: %i', endTime - startTime, this.averageRedrawTime); - } - - if( !forcedContext ){ - setTimeout(drawToContext, 0); // makes direct renders to screen a bit more responsive - } else { - drawToContext(); - } - - if( !forcedContext && !r.initrender ){ - r.initrender = true; - cy.trigger('initrender'); - } - - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - -// @O Polygon drawing - CanvasRenderer.prototype.drawPolygonPath = function( - context, x, y, width, height, points) { - - //context.save(); - - - context.translate(x, y); - context.scale(width / 2, height / 2); - - context.beginPath(); - - context.moveTo(points[0], points[1]); - - for (var i = 1; i < points.length / 2; i++) { - context.lineTo(points[i * 2], points[i * 2 + 1]); - } - - context.closePath(); - - context.scale(2/width, 2/height); - context.translate(-x, -y); - // context.restore(); - } - - CanvasRenderer.prototype.drawPolygon = function( - context, x, y, width, height, points) { - - // Draw path - this.drawPolygonPath(context, x, y, width, height, points); - - // Fill path - context.fill(); - } - - // Round rectangle drawing - CanvasRenderer.prototype.drawRoundRectanglePath = function( - context, x, y, width, height, radius) { - - var halfWidth = width / 2; - var halfHeight = height / 2; - var cornerRadius = $$.math.getRoundRectangleRadius(width, height); - context.translate(x, y); - - context.beginPath(); - - // Start at top middle - context.moveTo(0, -halfHeight); - // Arc from middle top to right side - context.arcTo(halfWidth, -halfHeight, halfWidth, 0, cornerRadius); - // Arc from right side to bottom - context.arcTo(halfWidth, halfHeight, 0, halfHeight, cornerRadius); - // Arc from bottom to left side - context.arcTo(-halfWidth, halfHeight, -halfWidth, 0, cornerRadius); - // Arc from left side to topBorder - context.arcTo(-halfWidth, -halfHeight, 0, -halfHeight, cornerRadius); - // Join line - context.lineTo(0, -halfHeight); - - /* - void arc(unrestricted double x, - unrestricted double y, - unrestricted double radius, - unrestricted double startAngle, - unrestricted double endAngle, - optional boolean anticlockwise = false); - */ - /* - context.arc(-width / 2 + cornerRadius, - -height / 2 + cornerRadius, - cornerRadius, - 0, - Math.PI * 2 * 0.999); - */ - - context.closePath(); - - context.translate(-x, -y); - } - - CanvasRenderer.prototype.drawRoundRectangle = function( - context, x, y, width, height, radius) { - - this.drawRoundRectanglePath(context, x, y, width, height, radius); - - context.fill(); - } - - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.createBuffer = function(w, h) { - var buffer = document.createElement("canvas"); - buffer.width = w; - buffer.height = h; - - return [buffer, buffer.getContext("2d")]; - } - - CanvasRenderer.prototype.png = function( options ){ - var data = this.data; - var cy = data.cy; - var bb = cy.boundingBox(); - var width = options.full ? Math.ceil(bb.w) : this.data.container.clientWidth; - var height = options.full ? Math.ceil(bb.h) : this.data.container.clientHeight; - var buffCanvas = document.createElement("canvas"); - - buffCanvas.width = width; - buffCanvas.height = height; - - buffCanvas.style.width = width + 'px'; - buffCanvas.style.height = height + 'px'; - - var buffCxt = buffCanvas.getContext("2d"); - - // Rasterize the layers, but only if container has nonzero size - if (width > 0 && height > 0) { - - buffCxt.clearRect( 0, 0, width, height ); - - if( options.bg ){ - buffCxt.fillStyle = options.bg; - buffCxt.rect( 0, 0, width, height ); - buffCxt.fill(); - } - - buffCxt.globalCompositeOperation = "source-over"; - - if( options.full ){ // draw the full bounds of the graph - this.redraw({ - forcedContext: buffCxt, - drawAllLayers: true, - forcedZoom: 1, - forcedPan: { x: -bb.x1, y: -bb.y1 } - }); - } else { // draw the current view - this.redraw({ - forcedContext: buffCxt, - drawAllLayers: true - }); - } - } - - return buffCanvas.toDataURL("image/png"); - }; - -})( cytoscape ); - -;(function($$){ "use strict"; - - var CanvasRenderer = $$('renderer', 'canvas'); - - CanvasRenderer.prototype.registerBinding = function(target, event, handler, useCapture){ - this.bindings.push({ - target: target, - event: event, - handler: handler, - useCapture: useCapture - }); - - target.addEventListener(event, handler, useCapture); - }; - - CanvasRenderer.prototype.load = function() { - var r = this; - - // helper function to determine which child nodes and inner edges - // of a compound node to be dragged as well as the grabbed and selected nodes - var addDescendantsToDrag = function(node, addSelected, dragElements) { - if (!addSelected) - { - var parents = node.parents(); - - // do not process descendants for this node, - // because those will be handled for the topmost selected parent - for (var i=0; i < parents.size(); i++) - { - if (parents[i]._private.selected) - { - return; - } - } - } - - var innerNodes = node.descendants(); - - var hasNonAutoParent = function(ele){ - while( ele.parent().nonempty() && ele.parent().id() !== node.id() ){ - parent = ele.parent()[0]; - var pstyle = parent._private.style; - - if( pstyle.width.value !== 'auto' || pstyle.height.value !== 'auto' ){ - return true; - } - - ele = ele.parent(); - } - - return false; - }; - - // TODO do not drag hidden children & children of hidden children? - for (var i=0; i < innerNodes.size(); i++) - { - // if addSelected is true, then add node in any case, - // if not, then add only non-selected nodes - if ( (addSelected || !innerNodes[i]._private.selected) ) - { - innerNodes[i]._private.rscratch.inDragLayer = true; - //innerNodes[i].trigger(new $$.Event(e, {type: "grab"})); - //innerNodes[i].trigger(event); - dragElements.push(innerNodes[i]); - - for (var j=0; j < innerNodes[i]._private.edges.length; j++) - { - innerNodes[i]._private.edges[j]._private.rscratch.inDragLayer = true; - } - } - } - }; - - // adds the given nodes, and its edges to the drag layer - var addNodeToDrag = function(node, dragElements) { - node._private.grabbed = true; - node._private.rscratch.inDragLayer = true; - - dragElements.push(node); - - for (var i=0;i containerPageCoords[0] && e.pageX < containerPageCoords[0] + r.data.container.clientWidth - && e.pageY > containerPageCoords[1] && e.pageY < containerPageCoords[1] + r.data.container.clientHeight) { - - } else { - return; - } - } - - var cy = r.data.cy; - var pos = r.projectIntoViewport(e.pageX, e.pageY); - var select = r.data.select; - - var near = r.findNearestElement(pos[0], pos[1], true); - var last = r.hoverData.last; - var down = r.hoverData.down; - - var disp = [pos[0] - select[2], pos[1] - select[3]]; - var nodes = r.getCachedNodes(); - var edges = r.getCachedEdges(); - - var draggedElements = r.dragData.possibleDragElements; - - - var shiftDown = e.shiftKey; - - - preventDefault = true; - - // Mousemove event - { - if (near != null) { - near - .trigger(new $$.Event(e, { - type: "mousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - - } else if (near == null) { - cy - .trigger(new $$.Event(e, { - type: "mousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } - - } - - - // trigger context drag if rmouse down - if( r.hoverData.which === 3 ){ - var cxtEvt = new $$.Event(e, { - type: "cxtdrag", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - r.hoverData.cxtDragged = true; - - // Check if we are drag panning the entire graph - } else if (r.hoverData.dragging) { - preventDefault = true; - - if( cy.panningEnabled() && cy.userPanningEnabled() ){ - var deltaP = {x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}; - - cy.panBy( deltaP ); - } - - // Needs reproject due to pan changing viewport - pos = r.projectIntoViewport(e.pageX, e.pageY); - - // Checks primary button down & out of time & mouse not moved much - } else if (select[4] == 1 && (down == null || down.isEdge()) - && ( !cy.boxSelectionEnabled() || +new Date - r.hoverData.downTime >= CanvasRenderer.panOrBoxSelectDelay ) - && (Math.abs(select[3] - select[1]) + Math.abs(select[2] - select[0]) < 4) - && cy.panningEnabled() && cy.userPanningEnabled() ) { - - r.hoverData.dragging = true; - select[4] = 0; - - } else { - // deactivate bg on box selection - if (cy.boxSelectionEnabled() && Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) > 7 && select[4]){ - clearTimeout( r.bgActiveTimeout ); - r.data.bgActivePosistion = undefined; - } - - if( down && down.isEdge() && down.active() ){ down.unactivate(); } - - if (near != last) { - - if (last) { - last.trigger( new $$.Event(e, { - type: "mouseout", - cyPosition: { x: pos[0], y: pos[1] } - }) ); - } - - if (near) { - near.trigger( new $$.Event(e, { - type: "mouseover", - cyPosition: { x: pos[0], y: pos[1] } - }) ); - } - - r.hoverData.last = near; - } - - if ( down && down.isNode() && r.nodeIsDraggable(down) ) { - r.dragData.didDrag = true; // indicate that we actually did drag the node - - r.hoverData.draggingEles = true; - - var toTrigger = []; - new $$.Collection(cy, draggedElements).positions(function(i, ele){ - // Locked nodes not draggable, as well as non-visible nodes - if (ele.isNode() && r.nodeIsDraggable(ele)) { - var pos = ele.position(); - - return { - x: pos.x + disp[0], - y: pos.y + disp[1] - }; - - toTrigger.push( ele ); - } - }); - - - (new $$.Collection(cy, toTrigger)) - .trigger("drag") - ; - - if (select[2] == select[0] && select[3] == select[1]) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - } - - if( cy.boxSelectionEnabled() ){ - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } - - // prevent the dragging from triggering text selection on the page - preventDefault = true; - } - - select[2] = pos[0]; select[3] = pos[1]; - - r.redraw(); - - if( preventDefault ){ - if(e.stopPropagation) e.stopPropagation(); - if(e.preventDefault) e.preventDefault(); - return false; - } - }, false); - - r.registerBinding(window, "mouseup", function(e) { - // console.log('--\nmouseup', e) - - var capture = r.hoverData.capture; if (!capture) { return; }; r.hoverData.capture = false; - - var cy = r.data.cy; var pos = r.projectIntoViewport(e.pageX, e.pageY); var select = r.data.select; - var near = r.findNearestElement(pos[0], pos[1], true); - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - var draggedElements = r.dragData.possibleDragElements; var down = r.hoverData.down; - var shiftDown = e.shiftKey; - - r.data.bgActivePosistion = undefined; // not active bg now - clearTimeout( r.bgActiveTimeout ); - - r.hoverData.cxtStarted = false; - r.hoverData.draggingEles = false; - - if( down ){ - down.unactivate(); - } - - if( r.hoverData.which === 3 ){ - var cxtEvt = new $$.Event(e, { - type: "cxttapend", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - if( !r.hoverData.cxtDragged ){ - var cxtTap = new $$.Event(e, { - type: "cxttap", - cyPosition: { x: pos[0], y: pos[1] } - }); - - if( down ){ - down.trigger( cxtTap ); - } else { - cy.trigger( cxtTap ); - } - } - - r.hoverData.cxtDragged = false; - r.hoverData.which = null; - - // if not right mouse - } else { - - // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something - if ( (down == null) // not mousedown on node - && !r.dragData.didDrag // didn't move the node around - && !(Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) > 7 && select[4]) // not box selection - && !r.hoverData.dragging // not panning - ) { - - // console.log('unselect all from bg'); - - //++clock+unselect - // var a = time(); - cy.$(':selected').unselect(); - - //++clock+unselect - // console.log("unselect", time() - a); - - if (draggedElements.length > 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - r.dragData.possibleDragElements = draggedElements = []; - } - - - // Mouseup event - { - // console.log('trigger mouseup et al'); - - if (near != null) { - near - .trigger(new $$.Event(e, { - type: "mouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapend", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } else if (near == null) { - cy - .trigger(new $$.Event(e, { - type: "mouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "tapend", - cyPosition: { x: pos[0], y: pos[1] } - })) - .trigger(new $$.Event(e, { - type: "vmouseup", - cyPosition: { x: pos[0], y: pos[1] } - })) - ; - } - } - - // Click event - { - // console.log('trigger click et al'); - - if (Math.pow(select[2] - select[0], 2) + Math.pow(select[3] - select[1], 2) == 0) { - if (near != null) { - near - .trigger( new $$.Event(e, { - type: "click", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "tap", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "vclick", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - ; - } else if (near == null) { - cy - .trigger( new $$.Event(e, { - type: "click", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "tap", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - .trigger( new $$.Event(e, { - type: "vclick", - cyPosition: { x: pos[0], y: pos[1] } - }) ) - ; - } - } - } - - // Single selection - if (near == down && !r.dragData.didDrag) { - if (near != null && near._private.selectable) { - - // console.log('single selection') - - if( cy.selectionType() === 'additive' || shiftDown ){ - if( near.selected() ){ - near.unselect(); - } else { - near.select(); - } - } else { - if( !shiftDown ){ - cy.$(':selected').unselect(); - near.select(); - } - } - - - updateAncestorsInDragLayer(near, false); - - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - - } - // Ungrab single drag - } else if (near == down) { - if (near != null && near._private.grabbed) { - // console.log('ungrab single drag') - - var grabbedEles = cy.$(':grabbed'); - - for(var i = 0; i < grabbedEles.length; i++){ - var ele = grabbedEles[i]; - - ele._private.grabbed = false; - - var sEdges = ele._private.edges; - for (var j=0;j 7 && select[4] ) { - // console.log("box selection"); - - var newlySelected = []; - var box = r.getAllInBox(select[0], select[1], select[2], select[3]); - // console.log(box); - var event = new $$.Event(e, {type: "select"}); - for (var i=0;i 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - } - - // Cancel drag pan - r.hoverData.dragging = false; - - if (!select[4]) { - // console.log('free at end', draggedElements) - - for (var i=0;i 250) { - if (r.touchData.start) { - r.touchData.start.trigger( new $$.Event(e, { - type: "taphold", - cyPosition: { x: now[0], y: now[1] } - }) ); - } else { - r.data.cy.trigger( new $$.Event(e, { - type: "taphold", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.$(':selected').unselect(); - } - -// console.log("taphold"); - } - }, 1000); - } - - r.redraw(); - - }, false); - -// console.log = function(m){ $('#console').append('
                      '+m+'
                      '); }; - - r.registerBinding(window, "touchmove", function(e) { - - var select = r.data.select; - var capture = r.touchData.capture; //if (!capture) { return; }; - capture && e.preventDefault(); - - var cy = r.data.cy; - var nodes = r.getCachedNodes(); var edges = r.getCachedEdges(); - var now = r.touchData.now; var earlier = r.touchData.earlier; - - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - var disp = []; for (var j=0;j= 1.5 || distance2 >= 150 ){ - r.touchData.cxt = false; - if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; } - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - var cxtEvt = new $$.Event(e, { - type: "cxttapend", - cyPosition: { x: now[0], y: now[1] } - }); - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - } - - } - - if( capture && r.touchData.cxt ){ - var cxtEvt = new $$.Event(e, { - type: "cxtdrag", - cyPosition: { x: now[0], y: now[1] } - }); - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if( r.touchData.start ){ - r.touchData.start.trigger( cxtEvt ); - } else { - cy.trigger( cxtEvt ); - } - - if( r.touchData.start ){ r.touchData.start._private.grabbed = false; } - r.touchData.cxtDragged = true; - - //console.log('cxtdrag') - - } else if( capture && e.touches[2] && cy.boxSelectionEnabled() ){ - r.data.bgActivePosistion = undefined; - clearTimeout( this.threeFingerSelectTimeout ); - this.lastThreeTouch = +new Date; - - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if( !select || select.length === 0 || select[0] === undefined ){ - select[0] = (now[0] + now[2] + now[4])/3; - select[1] = (now[1] + now[3] + now[5])/3; - select[2] = (now[0] + now[2] + now[4])/3 + 1; - select[3] = (now[1] + now[3] + now[5])/3 + 1; - } else { - select[2] = (now[0] + now[2] + now[4])/3; - select[3] = (now[1] + now[3] + now[5])/3; - } - - select[4] = 1; - - } else if ( capture && e.touches[1] && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled() ) { // two fingers => pinch to zoom - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - // console.log('touchmove ptz'); - - // (x2, y2) for fingers 1 and 2 - var f1x2 = e.touches[0].pageX - offsetLeft, f1y2 = e.touches[0].pageY - offsetTop; - var f2x2 = e.touches[1].pageX - offsetLeft, f2y2 = e.touches[1].pageY - offsetTop; - - // console.log( f1x2, f1y2 ) - // console.log( f2x2, f2y2 ) - - var distance2 = distance( f1x2, f1y2, f2x2, f2y2 ); - var factor = distance2 / distance1; - - // console.log(distance2) - // console.log(factor) - - if( factor != 1 && twoFingersStartInside){ - - // console.log(factor) - // console.log(distance2 + ' / ' + distance1); - // console.log('--'); - - // delta finger1 - var df1x = f1x2 - f1x1; - var df1y = f1y2 - f1y1; - - // delta finger 2 - var df2x = f2x2 - f2x1; - var df2y = f2y2 - f2y1; - - // translation is the normalised vector of the two fingers movement - // i.e. so pinching cancels out and moving together pans - var tx = (df1x + df2x)/2; - var ty = (df1y + df2y)/2; - - // adjust factor by the speed multiplier - // var speed = 1.5; - // if( factor > 1 ){ - // factor = (factor - 1) * speed + 1; - // } else { - // factor = 1 - (1 - factor) * speed; - // } - - // now calculate the zoom - var zoom1 = cy.zoom(); - var zoom2 = zoom1 * factor; - var pan1 = cy.pan(); - - // the model center point converted to the current rendered pos - var ctrx = modelCenter1[0] * zoom1 + pan1.x; - var ctry = modelCenter1[1] * zoom1 + pan1.y; - - var pan2 = { - x: -zoom2/zoom1 * (ctrx - pan1.x - tx) + ctrx, - y: -zoom2/zoom1 * (ctry - pan1.y - ty) + ctry - }; - - // console.log(pan2); - // console.log(zoom2); - - cy._private.zoom = zoom2; - cy._private.pan = pan2; - cy - .trigger('pan zoom') - .notify('viewport') - ; - - distance1 = distance2; - f1x1 = f1x2; - f1y1 = f1y2; - f2x1 = f2x2; - f2y1 = f2y2; - - r.pinching = true; - } - - // Re-project - if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); now[0] = pos[0]; now[1] = pos[1]; } - if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].pageX, e.touches[1].pageY); now[2] = pos[0]; now[3] = pos[1]; } - if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].pageX, e.touches[2].pageY); now[4] = pos[0]; now[5] = pos[1]; } - - } else if (e.touches[0]) { - var start = r.touchData.start; - var last = r.touchData.last; - - if ( start != null && start._private.group == "nodes" && r.nodeIsDraggable(start)) { - var draggedEles = r.dragData.touchDragEles; - - var dEleCol = new $$.Collection(cy, draggedEles).positions(function(i, draggedEle){ - if( r.nodeIsDraggable(draggedEle) ){ - r.dragData.didDrag = true; - var pos = draggedEle.position(); - - return { - x: pos.x + disp[0], - y: pos.y + disp[1] - }; - } - }); - - dEleCol - .trigger("drag") - ; - - r.data.canvasNeedsRedraw[CanvasRenderer.DRAG] = true; - - if (r.touchData.startPosition[0] == earlier[0] - && r.touchData.startPosition[1] == earlier[1]) { - - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - } - - // Touchmove event - { - if (start != null) { - start.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - start.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - start.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - - if (start == null) { - var near = r.findNearestElement(now[0], now[1], true); - - if (near != null) { - near.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - near.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - near.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - - if (near == null) { - cy.trigger( new $$.Event(e, { - type: "touchmove", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.trigger( new $$.Event(e, { - type: "tapdrag", - cyPosition: { x: now[0], y: now[1] } - }) ); - - cy.trigger( new $$.Event(e, { - type: "vmousemove", - cyPosition: { x: now[0], y: now[1] } - }) ); - } - } - - // if (near != last) { - // if (last) { last.trigger(new $$.Event(e, {type: "touchout"})); } - // if (near) { near.trigger(new $$.Event(e, {type: "touchover"})); } - // } - - r.touchData.last = near; - } - - // Check to cancel taphold - for (var i=0;i 4) { - - r.touchData.singleTouchMoved = true; - } - } - - if ( capture && (start == null || start.isEdge()) && cy.panningEnabled() && cy.userPanningEnabled() ) { - if( start ){ - start.unactivate(); - - if( !r.data.bgActivePosistion ){ - r.data.bgActivePosistion = { - x: now[0], - y: now[1] - }; - } - - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } - - cy.panBy({x: disp[0] * cy.zoom(), y: disp[1] * cy.zoom()}); - r.swipePanning = true; - - // Re-project - var pos = r.projectIntoViewport(e.touches[0].pageX, e.touches[0].pageY); - now[0] = pos[0]; now[1] = pos[1]; - } - } - - for (var j=0;j 0) { - r.data.canvasNeedsRedraw[CanvasRenderer.NODE] = true; - } - - //}, 100); - } - - if( !e.touches[1] ){ - r.pinching = false; - } - - var updateStartStyle = false; - - if( start != null ){ - start._private.active = false; - updateStartStyle = true; - start.trigger("unactivate"); - } - - if (e.touches[2]) { - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - } else if (e.touches[1]) { - - } else if (e.touches[0]) { - - // Last touch released - } else if (!e.touches[0]) { - - r.data.bgActivePosistion = undefined; - r.data.canvasNeedsRedraw[CanvasRenderer.SELECT_BOX] = true; - - if (start != null ) { - - if (start._private.grabbed == true) { - start._private.grabbed = false; - start.trigger("free"); - start._private.rscratch.inDragLayer = false; - } - - var sEdges = start._private.edges; - for (var j=0;j cells ){ - var sm = small(); - var lg = large(); - - // reducing the small side takes away the most cells, so try it first - if( (sm - 1) * lg >= cells ){ - small(sm - 1); - } else if( (lg - 1) * sm >= cells ){ - large(lg - 1); - } - } else { - - // if rounding was too low, add rows or columns - while( cols * rows < cells ){ - var sm = small(); - var lg = large(); - - // try to add to larger side first (adds less in multiplication) - if( (lg + 1) * sm >= cells ){ - large(lg + 1); - } else { - small(sm + 1); - } - } - } - - var cellWidth = width / cols; - var cellHeight = height / rows; - - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - var w = node.outerWidth(); - var h = node.outerHeight(); - - cellWidth = Math.max( cellWidth, w ); - cellHeight = Math.max( cellHeight, h ); - } - - var cellUsed = {}; // e.g. 'c-0-2' => true - - var used = function(row, col){ - return cellUsed['c-' + row + '-' + col] ? true : false; - }; - - var use = function(row, col){ - cellUsed['c-' + row + '-' + col] = true; - }; - - // to keep track of current cell position - var row = 0; - var col = 0; - var moveToNextCell = function(){ - col++; - if( col >= cols ){ - col = 0; - row++; - } - }; - - // get a cache of all the manual positions - var id2manPos = {}; - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - var rcPos = options.position( node ); - - if( rcPos && (rcPos.row !== undefined || rcPos.col !== undefined) ){ // must have at least row or col def'd - var pos = { - row: rcPos.row, - col: rcPos.col - }; - - if( pos.col === undefined ){ // find unused col - pos.col = 0; - - while( used(pos.row, pos.col) ){ - pos.col++; - } - } else if( pos.row === undefined ){ // find unused row - pos.row = 0; - - while( used(pos.row, pos.col) ){ - pos.row++; - } - } - - id2manPos[ node.id() ] = pos; - use( pos.row, pos.col ); - } - } - - - var atLeastOneManSet = false; - nodes.positions(function(i, element){ - var x, y; - - if( element.locked() || element.isFullAutoParent() ){ - return false; - } - - // see if we have a manual position set - var rcPos = id2manPos[ element.id() ]; - if( rcPos ){ - x = rcPos.col * cellWidth + cellWidth/2; - y = rcPos.row * cellHeight + cellHeight/2; - - } else { // otherwise set automatically - - while( used(row, col) ){ - moveToNextCell(); - } - - x = col * cellWidth + cellWidth/2; - y = row * cellHeight + cellHeight/2; - use( row, col ); - - moveToNextCell(); - } - - return { x: x, y: y }; - - }); - } - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - GridLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "grid", GridLayout); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit to viewport - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - positions: undefined, // map of (node id) => (position obj) - zoom: undefined, // the zoom level to set (prob want fit = false if set) - pan: undefined, // the pan level to set (prob want fit = false if set) - padding: 30 // padding on fit - }; - - function PresetLayout( options ){ - this.options = $$.util.extend(true, {}, defaults, options); - } - - PresetLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - function getPosition(node){ - if( options.positions == null ){ - return null; - } - - if( options.positions[node._private.data.id] == null ){ - return null; - } - - return options.positions[node._private.data.id]; - } - - nodes.positions(function(i, node){ - var position = getPosition(node); - - if( node.locked() || position == null ){ - return false; - } - - return position; - }); - - if( options.pan != null ){ - cy.pan( options.pan ); - } - - if( options.zoom != null ){ - cy.zoom( options.zoom ); - } - - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - if( options.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - $$("layout", "preset", PresetLayout); - - $$("core", "presetLayout", function(){ - var cy = this; - var layout = {}; - var elements = {}; - - cy.nodes().each(function(i, ele){ - elements[ ele.data("id") ] = ele.position(); - }); - - layout.positions = elements; - layout.name = "preset"; - layout.zoom = cy.zoom(); - layout.pan = cy.pan(); - - return layout; - }); - -})(cytoscape); - -;(function($$){ "use strict"; - - var defaults = { - liveUpdate: true, // whether to show the layout as it's running - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - maxSimulationTime: 4000, // max length in ms to run the layout - fit: true, // reset viewport to fit default simulationBounds - padding: [ 50, 50, 50, 50 ], // top, right, bottom, left - simulationBounds: undefined, // [x1, y1, x2, y2]; [0, 0, width, height] by default - ungrabifyWhileSimulating: true, // so you can't drag nodes during layout - - // forces used by arbor (use arbor default on undefined) - repulsion: undefined, - stiffness: undefined, - friction: undefined, - gravity: true, - fps: undefined, - precision: undefined, - - // static numbers or functions that dynamically return what these - // values should be for each element - nodeMass: undefined, - edgeLength: undefined, - - stepSize: 1, // size of timestep in simulation - - // function that returns true if the system is stable to indicate - // that the layout can be stopped - stableEnergy: function( energy ){ - var e = energy; - return (e.max <= 0.5) || (e.mean <= 0.3); - } - }; - - function ArborLayout(options){ - this.options = $$.util.extend({}, defaults, options); - } - - ArborLayout.prototype.run = function(){ - var options = this.options; - var cy = options.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - var simulationBounds = options.simulationBounds; - - if( options.simulationBounds ){ - width = simulationBounds[2] - simulationBounds[0]; // x2 - x1 - height = simulationBounds[3] - simulationBounds[1]; // y2 - y1 - } else { - options.simulationBounds = [ - 0, - 0, - width, - height - ]; - } - - // make nice x & y fields - var simBB = options.simulationBounds; - simBB.x1 = simBB[0]; - simBB.y1 = simBB[1]; - simBB.x2 = simBB[2]; - simBB.y2 = simBB[3]; - - // arbor doesn't work with just 1 node - if( cy.nodes().size() <= 1 ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().position({ - x: Math.round( (simBB.x1 + simBB.x2)/2 ), - y: Math.round( (simBB.y1 + simBB.y2)/2 ) - }); - - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - - return; - } - - var sys = this.system = arbor.ParticleSystem(options.repulsion, options.stiffness, options.friction, options.gravity, options.fps, options.dt, options.precision); - this.system = sys; - - if( options.liveUpdate && options.fit ){ - cy.reset(); - }; - - var doneTime = 250; - var doneTimeout; - - var ready = false; - - var lastDraw = +new Date; - var sysRenderer = { - init: function(system){ - }, - redraw: function(){ - var energy = sys.energy(); - - // if we're stable (according to the client), we're done - if( options.stableEnergy != null && energy != null && energy.n > 0 && options.stableEnergy(energy) ){ - sys.stop(); - return; - } - - clearTimeout(doneTimeout); - doneTimeout = setTimeout(doneHandler, doneTime); - - var movedNodes = []; - - sys.eachNode(function(n, point){ - var id = n.name; - var data = n.data; - var node = data.element; - - if( node == null ){ - return; - } - - if( !node.locked() && !node.grabbed() ){ - node.silentPosition({ - x: simBB.x1 + point.x, - y: simBB.y1 + point.y - }); - - movedNodes.push( node ); - } - }); - - - var timeToDraw = (+new Date - lastDraw) >= 16; - if( options.liveUpdate && movedNodes.length > 0 && timeToDraw ){ - new $$.Collection(cy, movedNodes).rtrigger("position"); - lastDraw = +new Date; - } - - - if( !ready ){ - ready = true; - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - } - } - - }; - sys.renderer = sysRenderer; - sys.screenSize( width, height ); - sys.screenPadding( options.padding[0], options.padding[1], options.padding[2], options.padding[3] ); - sys.screenStep( options.stepSize ); - - function calculateValueForElement(element, value){ - if( value == null ){ - return undefined; - } else if( typeof value == typeof function(){} ){ - return value.apply(element, [element._private.data, { - nodes: nodes.length, - edges: edges.length, - element: element - }]); - } else { - return value; - } - } - - // TODO we're using a hack; sys.toScreen should work :( - function fromScreen(pos){ - var x = pos.x; - var y = pos.y; - var w = width; - var h = height; - - var left = -2; - var right = 2; - var top = -2; - var bottom = 2; - - var d = 4; - - return { - x: x/w * d + left, - y: y/h * d + right - }; - } - - var grabHandler = function(e){ - grabbed = this; - var pos = sys.fromScreen( this.position() ); - var p = arbor.Point(pos.x, pos.y); - this.scratch().arbor.p = p; - - switch( e.type ){ - case "grab": - this.scratch().arbor.fixed = true; - break; - case "dragstop": - this.scratch().arbor.fixed = false; - this.scratch().arbor.tempMass = 1000 - break; - } - }; - nodes.bind("grab drag dragstop", grabHandler); - - nodes.each(function(i, node){ - if( this.isFullAutoParent() ){ return; } // they don't exist in the sim - - var id = this._private.data.id; - var mass = calculateValueForElement(this, options.nodeMass); - var locked = this._private.locked; - - if( node.isFullAutoParent() ){ - return; - } - - var pos = fromScreen({ - x: node.position().x, - y: node.position().y - }); - - if( node.locked() ){ - return; - } - - this.scratch().arbor = sys.addNode(id, { - element: this, - mass: mass, - fixed: locked, - x: locked ? pos.x : undefined, - y: locked ? pos.y : undefined - }); - }); - - edges.each(function(){ - var id = this.id(); - var src = this.source().id(); - var tgt = this.target().id(); - var length = calculateValueForElement(this, options.edgeLength); - - this.scratch().arbor = sys.addEdge(src, tgt, { - length: length - }); - }); - - function packToCenter(callback){ - // TODO implement this for IE :( - - if( options.fit ){ - cy.fit(); - } - callback(); - }; - - var grabbableNodes = nodes.filter(":grabbable"); - // disable grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.ungrabify(); - } - - var doneHandler = function(){ - if( window.isIE ){ - packToCenter(function(){ - done(); - }); - } else { - done(); - } - - function done(){ - if( !options.liveUpdate ){ - if( options.fit ){ - cy.reset(); - } - - cy.nodes().rtrigger("position"); - } - - // unbind handlers - nodes.unbind("grab drag dragstop", grabHandler); - - // enable back grabbing if so set - if( options.ungrabifyWhileSimulating ){ - grabbableNodes.grabify(); - } - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - } - }; - - sys.start(); - setTimeout(function(){ - sys.stop(); - }, options.maxSimulationTime); - - }; - - ArborLayout.prototype.stop = function(){ - if( this.system != null ){ - system.stop(); - } - }; - - $$("layout", "arbor", ArborLayout); - - -})(cytoscape); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - rStepSize: 10, // the step size for increasing the radius if the nodes don't fit on screen - padding: 30, // the padding on fit - startAngle: 3/2 * Math.PI, // the position of the first node - counterclockwise: false // whether the layout should go counterclockwise (true) or clockwise (false) - }; - - function CircleLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - CircleLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes().filter(function(){ - return !this.isFullAutoParent(); - }); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var center = { - x: width/2, - y: height/2 - }; - - var padding = 50; - - var theta = options.startAngle; - var dTheta = 2 * Math.PI / nodes.length; - var maxNodeSize = 0; - - for( var i = 0; i < nodes.length; i++ ){ - var node = nodes[i]; - - maxNodeSize = Math.max( node.outerWidth(), node.outerHeight() ); - } - - var r = width/2 - maxNodeSize; - - function distanceBetweenNodes(){ - var t1 = 0; - var t2 = dTheta; - - var p1 = { - x: center.x + r * Math.cos(t1), - y: center.y + r * Math.sin(t1) - }; - - var p2 = { - x: center.x + r * Math.cos(t2), - y: center.y + r * Math.sin(t2) - }; - - var dist = Math.sqrt( (p2.x - p1.x)*(p2.x - p1.x) + (p2.y - p1.y)*(p2.y - p1.y) ); - - return dist; - } - - while( distanceBetweenNodes() < maxNodeSize && !(nodes.length < 2) ){ - r += options.rStepSize; - } - - - var i = 0; - nodes.positions(function(){ - var node = this; - var rx = r * Math.cos( theta ); - var ry = r * Math.sin( theta ); - var pos = { - x: center.x + rx, - y: center.y + ry - }; - - i++; - theta = options.counterclockwise ? theta - dTheta : theta + dTheta; - return pos; - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - CircleLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "circle", CircleLayout); - -})( cytoscape ); - -;(function($$){ "use strict"; - - var defaults = { - fit: true, // whether to fit the viewport to the graph - ready: undefined, // callback on layoutready - stop: undefined, // callback on layoutstop - directed: true, // whether the tree is directed downwards (or edges can point in any direction if false) - padding: 30, // padding on fit - circle: false, // put depths in concentric circles if true, put depths top down if false - roots: undefined, // the roots of the trees - maximalAdjustments: 0 // how many times to try to position the nodes in a maximal way (i.e. no backtracking) - }; - - function BreadthFirstLayout( options ){ - this.options = $$.util.extend({}, defaults, options); - } - - BreadthFirstLayout.prototype.run = function(){ - var params = this.options; - var options = params; - - var cy = params.cy; - var nodes = cy.nodes(); - var edges = cy.edges(); - var container = cy.container(); - - var width = container.clientWidth; - var height = container.clientHeight; - - var roots; - if( $$.is.elementOrCollection(options.roots) ){ - roots = options.roots; - } else if( $$.is.array(options.roots) ){ - var rootsArray = []; - - for( var i = 0; i < options.roots.length; i++ ){ - var id = options.roots[i]; - var ele = cy.getElementById( id ); - roots.push( ele ); - } - - roots = new $$.Collection( cy, rootsArray ); - } else { - roots = nodes.roots(); - } - - - var depths = []; - var foundByBfs = {}; - var id2depth = {}; - - // find the depths of the nodes - roots.bfs(function(i, depth){ - var ele = this[0]; - - if( !depths[depth] ){ - depths[depth] = []; - } - - depths[depth].push( ele ); - foundByBfs[ ele.id() ] = true; - id2depth[ ele.id() ] = depth; - }, options.directed); - - // check for nodes not found by bfs - var orphanNodes = []; - for( var i = 0; i < nodes.length; i++ ){ - var ele = nodes[i]; - - if( foundByBfs[ ele.id() ] ){ - continue; - } else { - orphanNodes.push( ele ); - } - } - - // assign orphan nodes a depth from their neighborhood - var maxChecks = orphanNodes.length * 3; - var checks = 0; - while( orphanNodes.length !== 0 && checks < maxChecks ){ - var node = orphanNodes.shift(); - var neighbors = node.neighborhood().nodes(); - var assignedDepth = false; - - for( var i = 0; i < neighbors.length; i++ ){ - var depth = id2depth[ neighbors[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ - orphanNodes.push( node ); - } - - checks++; - } - - // assign orphan nodes that are still left to the depth of their subgraph - while( orphanNodes.length !== 0 ){ - var node = orphanNodes.shift(); - var subgraph = node.bfs(); - var assignedDepth = false; - - for( var i = 0; i < subgraph.length; i++ ){ - var depth = id2depth[ subgraph[i].id() ]; - - if( depth !== undefined ){ - depths[depth].push( node ); - assignedDepth = true; - break; - } - } - - if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0 - if( depths.length === 0 ){ - depths.push([]); - } - - depths[0].push( node ); - } - } - - // assign the nodes a depth and index - var assignDepthsToEles = function(){ - for( var i = 0; i < depths.length; i++ ){ - var eles = depths[i]; - - for( var j = 0; j < eles.length; j++ ){ - var ele = eles[j]; - - ele._private.scratch.BreadthFirstLayout = { - depth: i, - index: j - }; - } - } - }; - assignDepthsToEles(); - - // make maximal if so set by adjusting depths - for( var adj = 0; adj < options.maximalAdjustments; adj++ ){ - - var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth - var edges = node.connectedEdges('[target = "' + node.id() + '"]'); - var thisInfo = node._private.scratch.BreadthFirstLayout; - var highestDepthOfOther = 0; - var highestOther; - for( var i = 0; i < edges.length; i++ ){ - var edge = edges[i]; - var otherNode = edge.source()[0]; - var otherInfo = otherNode._private.scratch.BreadthFirstLayout; - - if( thisInfo.depth < otherInfo.depth && highestDepthOfOther < otherInfo.depth ){ - highestDepthOfOther = otherInfo.depth; - highestOther = otherNode; - } - } - - return highestOther; - }; - - var nDepths = depths.length; - var elesToMove = []; - for( var i = 0; i < nDepths; i++ ){ - var depth = depths[i]; - - var nDepth = depth.length; - for( var j = 0; j < nDepth; j++ ){ - var ele = depth[j]; - var info = ele._private.scratch.BreadthFirstLayout; - var intEle = intersectsDepth(ele); - - if( intEle ){ - info.intEle = intEle; - elesToMove.push( ele ); - } - } - } - - for( var i = 0; i < elesToMove.length; i++ ){ - var ele = elesToMove[i]; - var info = ele._private.scratch.BreadthFirstLayout; - var intEle = info.intEle; - var intInfo = intEle._private.scratch.BreadthFirstLayout; - - depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index - - // add to end of new depth - var newDepth = intInfo.depth + 1; - while( newDepth > depths.length - 1 ){ - depths.push([]); - } - depths[ newDepth ].push( ele ); - - info.depth = newDepth; - info.index = depths[newDepth].length - 1; - } - - assignDepthsToEles(); - } - - // find min distance we need to leave between nodes - var minDistance = 0; - for( var i = 0; i < nodes.length; i++ ){ - var w = nodes[i].outerWidth(); - var h = nodes[i].outerHeight(); - - minDistance = Math.max(minDistance, w, h); - } - minDistance *= 1.75; // just to have some nice spacing - - // get the weighted percent for an element based on its connectivity to other levels - var cachedWeightedPercent = {}; - var getWeightedPercent = function( ele ){ - if( cachedWeightedPercent[ ele.id() ] ){ - return cachedWeightedPercent[ ele.id() ]; - } - - var eleDepth = ele._private.scratch.BreadthFirstLayout.depth; - var neighbors = ele.neighborhood().nodes(); - var percent = 0; - var samples = 0; - - for( var i = 0; i < neighbors.length; i++ ){ - var neighbor = neighbors[i]; - var nEdges = neighbor.edgesWith( ele ); - var index = neighbor._private.scratch.BreadthFirstLayout.index; - var depth = neighbor._private.scratch.BreadthFirstLayout.depth; - var nDepth = depths[depth].length; - - if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above - percent += index / nDepth; - samples++; - } - } - - samples = Math.max(1, samples); - percent = percent / samples; - - if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting - percent = undefined; - } - - cachedWeightedPercent[ ele.id() ] = percent; - return percent; - }; - - // rearrange the indices in each depth level based on connectivity - for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result - - for( var i = 0; i < depths.length; i++ ){ - var depth = i; - var newDepths = []; - - depths[i] = depths[i].sort(function(a, b){ - var apct = getWeightedPercent( a ); - var bpct = getWeightedPercent( b ); - - - return apct - bpct; - }); - } - assignDepthsToEles(); // and update - - } - - var center = { - x: width/2, - y: height/2 - }; - nodes.positions(function(){ - var ele = this[0]; - var info = ele._private.scratch.BreadthFirstLayout; - var depth = info.depth; - var index = info.index; - - var distanceX = Math.max( width / (depths[depth].length + 1), minDistance ); - var distanceY = Math.max( height / (depths.length + 1), minDistance ); - var radiusStepSize = Math.min( width / 2 / depths.length, height / 2 / depths.length ); - radiusStepSize = Math.max( radiusStepSize, minDistance ); - - if( options.circle ){ - var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0); - var theta = 2 * Math.PI / depths[depth].length * index; - - if( depth === 0 && depths[0].length === 1 ){ - radius = 1; - } - - return { - x: center.x + radius * Math.cos(theta), - y: center.y + radius * Math.sin(theta) - }; - - } else { - return { - x: (index + 1) * distanceX, - y: (depth + 1) * distanceY - }; - } - - }); - - if( params.fit ){ - cy.fit( options.padding ); - } - - cy.one("layoutready", params.ready); - cy.trigger("layoutready"); - - cy.one("layoutstop", params.stop); - cy.trigger("layoutstop"); - }; - - BreadthFirstLayout.prototype.stop = function(){ - // not a continuous layout - }; - - $$("layout", "breadthfirst", BreadthFirstLayout); - -})( cytoscape ); - -/* - The CoSE layout was written by Gerardo Huck. - - Modifications tracked on Github. -*/ - -;(function($$) { "use strict"; - - var DEBUG; - - /** - * @brief : default layout options - */ - var defaults = { - // Called on `layoutready` - ready : function() {}, - - // Called on `layoutstop` - stop : function() {}, - - // Number of iterations between consecutive screen positions update (0 -> only updated on the end) - refresh : 0, - - // Whether to fit the network view after when done - fit : true, - - // Padding on fit - padding : 30, - - - // Whether to randomize node positions on the beginning - randomize : true, - - // Whether to use the JS console to print debug messages - debug : false, - - // Node repulsion (non overlapping) multiplier - nodeRepulsion : 10000, - - // Node repulsion (overlapping) multiplier - nodeOverlap : 10, - - // Ideal edge (non nested) length - idealEdgeLength : 10, - - // Divisor to compute edge forces - edgeElasticity : 100, - - // Nesting factor (multiplier) to compute ideal edge length for nested edges - nestingFactor : 5, - - // Gravity force (constant) - gravity : 250, - - // Maximum number of iterations to perform - numIter : 100, - - // Initial temperature (maximum node displacement) - initialTemp : 200, - - // Cooling factor (how the temperature is reduced between consecutive iterations - coolingFactor : 0.95, - - // Lower temperature threshold (below this point the layout will end) - minTemp : 1 - }; - - - /** - * @brief : constructor - * @arg options : object containing layout options - */ - function CoseLayout(options) { - this.options = $$.util.extend({}, defaults, options); - } - - - /** - * @brief : runs the layout - */ - CoseLayout.prototype.run = function() { - var options = this.options; - var cy = options.cy; - - // Set DEBUG - Global variable - if (true == options.debug) { - DEBUG = true; - } else { - DEBUG = false; - } - - // Get start time - var startTime = new Date(); - - // Initialize layout info - var layoutInfo = createLayoutInfo(cy, options); - - // Show LayoutInfo contents if debugging - if (DEBUG) { - printLayoutInfo(layoutInfo); - } - - // If required, randomize node positions - if (true == options.randomize) { - randomizePositions(layoutInfo, cy); - - if (0 < options.refresh) { - refreshPositions(layoutInfo, cy, options); - } - } - - updatePositions(layoutInfo, cy, options); - - // Main loop - for (var i = 0; i < options.numIter; i++) { - // Do one step in the phisical simulation - step(layoutInfo, cy, options, i); - - // If required, update positions - if (0 < options.refresh && 0 == (i % options.refresh)) { - refreshPositions(layoutInfo, cy, options); - } - - // Update temperature - layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor; - logDebug("New temperature: " + layoutInfo.temperature); - - if (layoutInfo.temperature < options.minTemp) { - logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i); - break; - } - } - - refreshPositions(layoutInfo, cy, options); - - // Fit the graph if necessary - if (true == options.fit) { - cy.fit( options.padding ); - } - - // Get end time - var endTime = new Date(); - - console.info("Layout took " + (endTime - startTime) + " ms"); - - // Layout has finished - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - - /** - * @brief : called on continuous layouts to stop them before they finish - */ - CoseLayout.prototype.stop = function(){ - var options = this.options; - - cy.one("layoutstop", options.stop); - cy.trigger("layoutstop"); - }; - - - /** - * @brief : Creates an object which is contains all the data - * used in the layout process - * @arg cy : cytoscape.js object - * @return : layoutInfo object initialized - */ - var createLayoutInfo = function(cy, options) { - var layoutInfo = { - layoutNodes : [], - idToIndex : {}, - nodeSize : cy.nodes().size(), - graphSet : [], - indexToGraph : [], - layoutEdges : [], - edgeSize : cy.edges().size(), - temperature : options.initialTemp - }; - - // Shortcut - var nodes = cy.nodes(); - - // Iterate over all nodes, creating layout nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var tempNode = {}; - tempNode.id = nodes[i].data('id'); - tempNode.parentId = nodes[i].data('parent'); - tempNode.children = []; - tempNode.positionX = nodes[i].position('x'); - tempNode.positionY = nodes[i].position('y'); - tempNode.offsetX = 0; - tempNode.offsetY = 0; - tempNode.height = nodes[i].height(); - tempNode.width = nodes[i].width(); - tempNode.maxX = tempNode.positionX + tempNode.width / 2; - tempNode.minX = tempNode.positionX - tempNode.width / 2; - tempNode.maxY = tempNode.positionY + tempNode.height / 2; - tempNode.minY = tempNode.positionY - tempNode.height / 2; - tempNode.padLeft = nodes[i]._private.style['padding-left'].pxValue; - tempNode.padRight = nodes[i]._private.style['padding-right'].pxValue; - tempNode.padTop = nodes[i]._private.style['padding-top'].pxValue; - tempNode.padBottom = nodes[i]._private.style['padding-bottom'].pxValue; - - // Add new node - layoutInfo.layoutNodes.push(tempNode); - // Add entry to id-index map - layoutInfo.idToIndex[tempNode.id] = i; - } - - // Inline implementation of a queue, used for traversing the graph in BFS order - var queue = []; - var start = 0; // Points to the start the queue - var end = -1; // Points to the end of the queue - - var tempGraph = []; - - // Second pass to add child information and - // initialize queue for hierarchical traversal - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - var p_id = n.parentId; - // Check if node n has a parent node - if (undefined != p_id) { - // Add node Id to parent's list of children - layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id); - } else { - // If a node doesn't have a parent, then it's in the root graph - queue[++end] = n.id; - tempGraph.push(n.id); - } - } - - // Add root graph to graphSet - layoutInfo.graphSet.push(tempGraph); - - // Traverse the graph, level by level, - while (start <= end) { - // Get the node to visit and remove it from queue - var node_id = queue[start++]; - var node_ix = layoutInfo.idToIndex[node_id]; - var node = layoutInfo.layoutNodes[node_ix]; - var children = node.children; - if (children.length > 0) { - // Add children nodes as a new graph to graph set - layoutInfo.graphSet.push(children); - // Add children to que queue to be visited - for (var i = 0; i < children.length; i++) { - queue[++end] = children[i]; - } - } - } - - // Create indexToGraph map - for (var i = 0; i < layoutInfo.graphSet.length; i++) { - var graph = layoutInfo.graphSet[i]; - for (var j = 0; j < graph.length; j++) { - var index = layoutInfo.idToIndex[graph[j]]; - layoutInfo.indexToGraph[index] = i; - } - } - - // Shortcut - var edges = cy.edges(); - - // Iterate over all edges, creating Layout Edges - for (var i = 0; i < layoutInfo.edgeSize; i++) { - var e = edges[i]; - var tempEdge = {}; - tempEdge.id = e.data('id'); - tempEdge.sourceId = e.data('source'); - tempEdge.targetId = e.data('target'); - - // Compute ideal length - var idealLength = options.idealEdgeLength; - - // Check if it's an inter graph edge - var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId]; - var targetIx = layoutInfo.idToIndex[tempEdge.targetId]; - var sourceGraph = layoutInfo.indexToGraph[sourceIx]; - var targetGraph = layoutInfo.indexToGraph[targetIx]; - - if (sourceGraph != targetGraph) { - // Find lowest common graph ancestor - var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo); - - // Compute sum of node depths, relative to lca graph - var lcaGraph = layoutInfo.graphSet[lca]; - var depth = 0; - - // Source depth - var tempNode = layoutInfo.layoutNodes[sourceIx]; - while (-1 == $.inArray(tempNode.id, lcaGraph)) { - tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; - depth++; - } - - // Target depth - tempNode = layoutInfo.layoutNodes[targetIx]; - while (-1 == $.inArray(tempNode.id, lcaGraph)) { - tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]]; - depth++; - } - - logDebug("LCA of nodes " + tempEdge.sourceId + " and " + tempEdge.targetId + - ". Index: " + lca + " Contents: " + lcaGraph.toString() + - ". Depth: " + depth); - - // Update idealLength - idealLength *= depth * options.nestingFactor; - } - - tempEdge.idealLength = idealLength; - - layoutInfo.layoutEdges.push(tempEdge); - } - - // Finally, return layoutInfo object - return layoutInfo; - }; - - - /** - * @brief : This function finds the index of the lowest common - * graph ancestor between 2 nodes in the subtree - * (from the graph hierarchy induced tree) whose - * root is graphIx - * - * @arg node1: node1's ID - * @arg node2: node2's ID - * @arg layoutInfo: layoutInfo object - * - */ - var findLCA = function(node1, node2, layoutInfo) { - // Find their common ancester, starting from the root graph - var res = findLCA_aux(node1, node2, 0, layoutInfo); - if (2 > res.count) { - // If aux function couldn't find the common ancester, - // then it is the root graph - return 0; - } else { - return res.graph; - } - }; - - - /** - * @brief : Auxiliary function used for LCA computation - * - * @arg node1 : node1's ID - * @arg node2 : node2's ID - * @arg graphIx : subgraph index - * @arg layoutInfo : layoutInfo object - * - * @return : object of the form {count: X, graph: Y}, where: - * X is the number of ancesters (max: 2) found in - * graphIx (and it's subgraphs), - * Y is the graph index of the lowest graph containing - * all X nodes - */ - var findLCA_aux = function(node1, node2, graphIx, layoutInfo) { - var graph = layoutInfo.graphSet[graphIx]; - // If both nodes belongs to graphIx - if (-1 < $.inArray(node1, graph) && -1 < $.inArray(node2, graph)) { - return {count:2, graph:graphIx}; - } - - // Make recursive calls for all subgraphs - var c = 0; - for (var i = 0; i < graph.length; i++) { - var nodeId = graph[i]; - var nodeIx = layoutInfo.idToIndex[nodeId]; - var children = layoutInfo.layoutNodes[nodeIx].children; - - // If the node has no child, skip it - if (0 == children.length) { - continue; - } - - var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]]; - var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo); - if (0 == result.count) { - // Neither node1 nor node2 are present in this subgraph - continue; - } else if (1 == result.count) { - // One of (node1, node2) is present in this subgraph - c++; - if (2 == c) { - // We've already found both nodes, no need to keep searching - break; - } - } else { - // Both nodes are present in this subgraph - return result; - } - } - - return {count:c, graph:graphIx}; - }; - - - /** - * @brief: printsLayoutInfo into js console - * Only used for debbuging - */ - var printLayoutInfo = function(layoutInfo) { - if (!DEBUG) { - return; - } - console.debug("layoutNodes:"); - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - var s = - "\nindex: " + i + - "\nId: " + n.id + - "\nChildren: " + n.children.toString() + - "\nparentId: " + n.parentId + - "\npositionX: " + n.positionX + - "\npositionY: " + n.positionY + - "\nOffsetX: " + n.offsetX + - "\nOffsetY: " + n.offsetY + - "\npadLeft: " + n.padLeft + - "\npadRight: " + n.padRight + - "\npadTop: " + n.padTop + - "\npadBottom: " + n.padBottom; - - console.debug(s); - } - - console.debug("idToIndex"); - for (var i in layoutInfo.idToIndex) { - console.debug("Id: " + i + "\nIndex: " + layoutInfo.idToIndex[i]); - } - - console.debug("Graph Set"); - var set = layoutInfo.graphSet; - for (var i = 0; i < set.length; i ++) { - console.debug("Set : " + i + ": " + set[i].toString()); - } - - var s = "IndexToGraph"; - for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) { - s += "\nIndex : " + i + " Graph: "+ layoutInfo.indexToGraph[i]; - } - console.debug(s); - - s = "Layout Edges"; - for (var i = 0; i < layoutInfo.layoutEdges.length; i++) { - var e = layoutInfo.layoutEdges[i]; - s += "\nEdge Index: " + i + " ID: " + e.id + - " SouceID: " + e.sourceId + " TargetId: " + e.targetId + - " Ideal Length: " + e.idealLength; - } - console.debug(s); - - s = "nodeSize: " + layoutInfo.nodeSize; - s += "\nedgeSize: " + layoutInfo.edgeSize; - s += "\ntemperature: " + layoutInfo.temperature; - console.debug(s); - - return; - }; - - - /** - * @brief : Randomizes the position of all nodes - */ - var randomizePositions = function(layoutInfo, cy) { - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - // No need to randomize compound nodes - if (true || 0 == n.children.length) { - n.positionX = Math.random() * width; - n.positionY = Math.random() * height; - } - } - } - - - /** - * @brief : Updates the positions of nodes in the network - * @arg layoutInfo : LayoutInfo object - * @arg cy : Cytoscape object - * @arg options : Layout options - */ - var refreshPositions = function(layoutInfo, cy, options) { - var container = cy.container(); - var width = container.clientWidth; - var height = container.clientHeight; - - var s = "Refreshing positions"; - logDebug(s); - - cy.nodes().positions(function(i, ele) { - var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]]; - s = "Node: " + lnode.id + ". Refreshed position: (" + - lnode.positionX + ", " + lnode.positionY + ")."; - logDebug(s); - return { - x: lnode.positionX, - y: lnode.positionY - }; - }); - - // Trigger layoutReady only on first call - if (true != layoutInfo.ready) { - s = "Triggering layoutready"; - logDebug(s); - layoutInfo.ready = true; - cy.one("layoutready", options.ready); - cy.trigger("layoutready"); - } - }; - - - /** - * @brief : Performs one iteration of the physical simulation - * @arg layoutInfo : LayoutInfo object already initialized - * @arg cy : Cytoscape object - * @arg options : Layout options - */ - var step = function(layoutInfo, cy, options, step) { - var s = "\n\n###############################"; - s += "\nSTEP: " + step; - s += "\n###############################\n"; - logDebug(s); - - // Calculate node repulsions - calculateNodeForces(layoutInfo, cy, options); - // Calculate edge forces - calculateEdgeForces(layoutInfo, cy, options); - // Calculate gravity forces - calculateGravityForces(layoutInfo, cy, options); - // Propagate forces from parent to child - propagateForces(layoutInfo, cy, options); - // Update positions based on calculated forces - updatePositions(layoutInfo, cy, options); - }; - - - /** - * @brief : Computes the node repulsion forces - */ - var calculateNodeForces = function(layoutInfo, cy, options) { - // Go through each of the graphs in graphSet - // Nodes only repel each other if they belong to the same graph - var s = "calculateNodeForces"; - logDebug(s); - for (var i = 0; i < layoutInfo.graphSet.length; i ++) { - var graph = layoutInfo.graphSet[i]; - var numNodes = graph.length; - - s = "Set: " + graph.toString(); - logDebug(s); - - // Now get all the pairs of nodes - // Only get each pair once, (A, B) = (B, A) - for (var j = 0; j < numNodes; j++) { - var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; - for (var k = j + 1; k < numNodes; k++) { - var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]]; - nodeRepulsion(node1, node2, layoutInfo, cy, options); - } - } - } - }; - - - /** - * @brief : Compute the node repulsion forces between a pair of nodes - */ - var nodeRepulsion = function(node1, node2, layoutInfo, cy, options) { - var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id; - - // Get direction of line connecting both node centers - var directionX = node2.positionX - node1.positionX; - var directionY = node2.positionY - node1.positionY; - s += "\ndirectionX: " + directionX + ", directionY: " + directionY; - - // If both centers are the same, apply a random force - if (0 == directionX && 0 == directionY) { - s += "\nNodes have the same position."; - return; // TODO - } - - var overlap = nodesOverlap(node1, node2, directionX, directionY); - - if (overlap > 0) { - s += "\nNodes DO overlap."; - s += "\nOverlap: " + overlap; - // If nodes overlap, repulsion force is proportional - // to the overlap - var force = options.nodeOverlap * overlap; - - // Compute the module and components of the force vector - var distance = Math.sqrt(directionX * directionX + directionY * directionY); - s += "\nDistance: " + distance; - var forceX = force * directionX / distance; - var forceY = force * directionY / distance; - - } else { - s += "\nNodes do NOT overlap."; - // If there's no overlap, force is inversely proportional - // to squared distance - - // Get clipping points for both nodes - var point1 = findClippingPoint(node1, directionX, directionY); - var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY); - - // Use clipping points to compute distance - var distanceX = point2.x - point1.x; - var distanceY = point2.y - point1.y; - var distanceSqr = distanceX * distanceX + distanceY * distanceY; - var distance = Math.sqrt(distanceSqr); - s += "\nDistance: " + distance; - - // Compute the module and components of the force vector - var force = options.nodeRepulsion / distanceSqr; - var forceX = force * distanceX / distance; - var forceY = force * distanceY / distance; - } - - // Apply force - node1.offsetX -= forceX; - node1.offsetY -= forceY; - node2.offsetX += forceX; - node2.offsetY += forceY; - - s += "\nForceX: " + forceX + " ForceY: " + forceY; - logDebug(s); - - return; - }; - - - /** - * @brief : Finds the point in which an edge (direction dX, dY) intersects - * the rectangular bounding box of it's source/target node - */ - var findClippingPoint = function(node, dX, dY) { - - // Shorcuts - var X = node.positionX; - var Y = node.positionY; - var H = node.height; - var W = node.width; - var dirSlope = dY / dX; - var nodeSlope = H / W; - var nodeinvSlope = W / H; - - var s = "Computing clipping point of node " + node.id + - " . Height: " + H + ", Width: " + W + - "\nDirection " + dX + ", " + dY; - - // Compute intersection - var res = {}; - do { - // Case: Vertical direction (up) - if (0 == dX && 0 < dY) { - res.x = X; - s += "\nUp direction"; - res.y = Y + H / 2; - break; - } - - // Case: Vertical direction (down) - if (0 == dX && 0 > dY) { - res.x = X; - res.y = Y + H / 2; - s += "\nDown direction"; - break; - } - - // Case: Intersects the right border - if (0 < dX && - -1 * nodeSlope <= dirSlope && - dirSlope <= nodeSlope) { - res.x = X + W / 2; - res.y = Y + (W * dY / 2 / dX); - s += "\nRightborder"; - break; - } - - // Case: Intersects the left border - if (0 > dX && - -1 * nodeSlope <= dirSlope && - dirSlope <= nodeSlope) { - res.x = X - W / 2; - res.y = Y - (W * dY / 2 / dX); - s += "\nLeftborder"; - break; - } - - // Case: Intersects the top border - if (0 < dY && - ( dirSlope <= -1 * nodeSlope || - dirSlope >= nodeSlope )) { - res.x = X + (H * dX / 2 / dY); - res.y = Y + H / 2; - s += "\nTop border"; - break; - } - - // Case: Intersects the bottom border - if (0 > dY && - ( dirSlope <= -1 * nodeSlope || - dirSlope >= nodeSlope )) { - res.x = X - (H * dX / 2 / dY); - res.y = Y - H / 2; - s += "\nBottom border"; - break; - } - - } while (false); - - s += "\nClipping point found at " + res.x + ", " + res.y; - logDebug(s); - return res; - }; - - - /** - * @brief : Determines whether two nodes overlap or not - * @return : Amount of overlapping (0 => no overlap) - */ - var nodesOverlap = function(node1, node2, dX, dY) { - - if (dX > 0) { - var overlapX = node1.maxX - node2.minX; - } else { - var overlapX = node2.maxX - node1.minX; - } - - if (dY > 0) { - var overlapY = node1.maxY - node2.minY; - } else { - var overlapY = node2.maxY - node1.minY; - } - - if (overlapX >= 0 && overlapY >= 0) { - return Math.sqrt(overlapX * overlapX + overlapY * overlapY); - } else { - return 0; - } - }; - - - /** - * @brief : Calculates all edge forces - */ - var calculateEdgeForces = function(layoutInfo, cy, options) { - // Iterate over all edges - for (var i = 0; i < layoutInfo.edgeSize; i++) { - // Get edge, source & target nodes - var edge = layoutInfo.layoutEdges[i]; - var sourceIx = layoutInfo.idToIndex[edge.sourceId]; - var source = layoutInfo.layoutNodes[sourceIx]; - var targetIx = layoutInfo.idToIndex[edge.targetId]; - var target = layoutInfo.layoutNodes[targetIx]; - - // Get direction of line connecting both node centers - var directionX = target.positionX - source.positionX; - var directionY = target.positionY - source.positionY; - - // If both centers are the same, do nothing. - // A random force has already been applied as node repulsion - if (0 == directionX && 0 == directionY) { - return; - } - - // Get clipping points for both nodes - var point1 = findClippingPoint(source, directionX, directionY); - var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY); - - - var lx = point2.x - point1.x; - var ly = point2.y - point1.y; - var l = Math.sqrt(lx * lx + ly * ly); - - var force = Math.pow(edge.idealLength - l, 2) / options.edgeElasticity; - - if (0 != l) { - var forceX = force * lx / l; - var forceY = force * ly / l; - } else { - var forceX = 0; - var forceY = 0; - } - - // Add this force to target and source nodes - source.offsetX += forceX; - source.offsetY += forceY; - target.offsetX -= forceX; - target.offsetY -= forceY; - - var s = "Edge force between nodes " + source.id + " and " + target.id; - s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")"; - logDebug(s); - } - }; - - - /** - * @brief : Computes gravity forces for all nodes - */ - var calculateGravityForces = function(layoutInfo, cy, options) { - var s = "calculateGravityForces"; - logDebug(s); - for (var i = 0; i < layoutInfo.graphSet.length; i ++) { - var graph = layoutInfo.graphSet[i]; - var numNodes = graph.length; - - s = "Set: " + graph.toString(); - logDebug(s); - - // Compute graph center - if (0 == i) { - var container = cy.container(); - var centerX = container.clientHeight / 2; - var centerY = container.clientWidth / 2; - } else { - // Get Parent node for this graph, and use its position as center - var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]]; - var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]]; - var centerX = parent.positionX; - var centerY = parent.positionY; - } - s = "Center found at: " + centerX + ", " + centerY; - logDebug(s); - - // Apply force to all nodes in graph - for (var j = 0; j < numNodes; j++) { - var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]]; - s = "Node: " + node.id; - var dx = centerX - node.positionX; - var dy = centerY - node.positionY; - var d = Math.sqrt(dx * dx + dy * dy); - if (d > 1.0) { // TODO: Use global variable for distance threshold - var fx = options.gravity * dx / d; - var fy = options.gravity * dy / d; - node.offsetX += fx; - node.offsetY += fy; - s += ": Applied force: " + fx + ", " + fy; - } else { - s += ": skypped since it's too close to center"; - } - logDebug(s); - } - } - }; - - - /** - * @brief : This function propagates the existing offsets from - * parent nodes to its descendents. - * @arg layoutInfo : layoutInfo Object - * @arg cy : cytoscape Object - * @arg options : Layout options - */ - var propagateForces = function(layoutInfo, cy, options) { - // Inline implementation of a queue, used for traversing the graph in BFS order - var queue = []; - var start = 0; // Points to the start the queue - var end = -1; // Points to the end of the queue - - logDebug("propagateForces"); - - // Start by visiting the nodes in the root graph - queue.push.apply(queue, layoutInfo.graphSet[0]); - end += layoutInfo.graphSet[0].length; - - // Traverse the graph, level by level, - while (start <= end) { - // Get the node to visit and remove it from queue - var nodeId = queue[start++]; - var nodeIndex = layoutInfo.idToIndex[nodeId]; - var node = layoutInfo.layoutNodes[nodeIndex]; - var children = node.children; - - // We only need to process the node if it's compound - if (0 < children.length) { - var offX = node.offsetX; - var offY = node.offsetY; - - var s = "Propagating offset from parent node : " + node.id + - ". OffsetX: " + offX + ". OffsetY: " + offY; - s += "\n Children: " + children.toString(); - logDebug(s); - - for (var i = 0; i < children.length; i++) { - var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]]; - // Propagate offset - childNode.offsetX += offX; - childNode.offsetY += offY; - // Add children to queue to be visited - queue[++end] = children[i]; - } - - // Reset parent offsets - node.offsetX = 0; - node.offsetY = 0; - } - - } - }; - - - /** - * @brief : Updates the layout model positions, based on - * the accumulated forces - */ - var updatePositions = function(layoutInfo, cy, options) { - var s = "Updating positions"; - logDebug(s); - - // Reset boundaries for compound nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - logDebug("Resetting boundaries of compound node: " + n.id); - n.maxX = undefined; - n.minX = undefined; - n.maxY = undefined; - n.minY = undefined; - } - } - - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - // No need to set compound node position - logDebug("Skipping position update of node: " + n.id); - continue; - } - s = "Node: " + n.id + " Previous position: (" + - n.positionX + ", " + n.positionY + ")."; - - // Limit displacement in order to improve stability - var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature); - n.positionX += tempForce.x; - n.positionY += tempForce.y; - n.offsetX = 0; - n.offsetY = 0; - n.minX = n.positionX - n.width; - n.maxX = n.positionX + n.width; - n.minY = n.positionY - n.height; - n.maxY = n.positionY + n.height; - s += " New Position: (" + n.positionX + ", " + n.positionY + ")."; - logDebug(s); - - // Update ancestry boudaries - updateAncestryBoundaries(n, layoutInfo); - } - - // Update size, position of compund nodes - for (var i = 0; i < layoutInfo.nodeSize; i++) { - var n = layoutInfo.layoutNodes[i]; - if (0 < n.children.length) { - n.positionX = (n.maxX + n.minX) / 2; - n.positionY = (n.maxY + n.minY) / 2; - n.width = n.maxX - n.minX; - n.height = n.maxY - n.minY; - s = "Updating position, size of compound node " + n.id; - s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY; - s += "\nWidth: " + n.width + ", Height: " + n.height; - logDebug(s); - } - } - }; - - - /** - * @brief : Limits a force (forceX, forceY) to be not - * greater (in modulo) than max. - 8 Preserves force direction. - */ - var limitForce = function(forceX, forceY, max) { - var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max; - var force = Math.sqrt(forceX * forceX + forceY * forceY); - - if (force > max) { - var res = { - x : max * forceX / force, - y : max * forceY / force - }; - - } else { - var res = { - x : forceX, - y : forceY - }; - } - - s += ".\nResult: (" + res.x + ", " + res.y + ")"; - logDebug(s); - - return res; - }; - - - /** - * @brief : Function used for keeping track of compound node - * sizes, since they should bound all their subnodes. - */ - var updateAncestryBoundaries = function(node, layoutInfo) { - var s = "Propagating new position/size of node " + node.id; - var parentId = node.parentId; - if (undefined == parentId) { - // If there's no parent, we are done - s += ". No parent node."; - logDebug(s); - return; - } - - // Get Parent Node - var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]]; - var flag = false; - - // MaxX - if (undefined == p.maxX || node.maxX + p.padRight > p.maxX) { - p.maxX = node.maxX + p.padRight; - flag = true; - s += "\nNew maxX for parent node " + p.id + ": " + p.maxX; - } - - // MinX - if (undefined == p.minX || node.minX - p.padLeft < p.minX) { - p.minX = node.minX - p.padLeft; - flag = true; - s += "\nNew minX for parent node " + p.id + ": " + p.minX; - } - - // MaxY - if (undefined == p.maxY || node.maxY + p.padBottom > p.maxY) { - p.maxY = node.maxY + p.padBottom; - flag = true; - s += "\nNew maxY for parent node " + p.id + ": " + p.maxY; - } - - // MinY - if (undefined == p.minY || node.minY - p.padTop < p.minY) { - p.minY = node.minY - p.padTop; - flag = true; - s += "\nNew minY for parent node " + p.id + ": " + p.minY; - } - - // If updated boundaries, propagate changes upward - if (flag) { - logDebug(s); - return updateAncestryBoundaries(p, layoutInfo); - } - - s += ". No changes in boundaries/position of parent node " + p.id; - logDebug(s); - return; - }; - - - /** - * @brief : Logs a debug message in JS console, if DEBUG is ON - */ - var logDebug = function(text) { - if (DEBUG) { - console.debug(text); - } - }; - - - // register the layout - $$("layout", "cose", CoseLayout); - -})(cytoscape); diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.min.js deleted file mode 100755 index 8c0e8c08c3..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/cytoscape/cytoscape.min.js +++ /dev/null @@ -1,27 +0,0 @@ - -/* cytoscape.min.js */ - -/** - * This file is part of cytoscape.js 2.1.0. - * - * Cytoscape.js is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) any - * later version. - * - * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more - * details. - * - * You should have received a copy of the GNU Lesser General Public License along with - * cytoscape.js. If not, see . - */ - -var cytoscape;!function(e){"use strict";var t=cytoscape=function(){return cytoscape.init.apply(cytoscape,arguments)};t.init=function(e){return void 0===e&&(e={}),t.is.plainObject(e)?new t.Core(e):t.is.string(e)?t.extension.apply(t.extension,arguments):void 0},t.fn={},"undefined"!=typeof exports&&(exports=module.exports=cytoscape),e&&(e.cytoscape=cytoscape)}("undefined"==typeof window?null:window),function(e,t){"use strict";e.is={string:function(e){return null!=e&&"string"==typeof e},fn:function(e){return null!=e&&"function"==typeof e},array:function(e){return null!=e&&e instanceof Array},plainObject:function(t){return null!=t&&typeof t==typeof{}&&!e.is.array(t)&&t.constructor===Object},number:function(e){return null!=e&&"number"==typeof e&&!isNaN(e)},integer:function(t){return e.is.number(t)&&Math.floor(t)===t},color:function(e){return null!=e&&"string"==typeof e&&""!==$.Color(e).toString()},bool:function(e){return null!=e&&typeof e==typeof!0},elementOrCollection:function(t){return e.is.element(t)||e.is.collection(t)},element:function(t){return t instanceof e.Element&&t._private.single},collection:function(t){return t instanceof e.Collection&&!t._private.single},core:function(t){return t instanceof e.Core},style:function(t){return t instanceof e.Style},stylesheet:function(t){return t instanceof e.Stylesheet},event:function(t){return t instanceof e.Event},emptyString:function(t){return t?e.is.string(t)&&(""===t||t.match(/^\s+$/))?!0:!1:!0},nonemptyString:function(t){return t&&e.is.string(t)&&""!==t&&!t.match(/^\s+$/)?!0:!1},domElement:function(e){return"undefined"==typeof HTMLElement?!1:e instanceof HTMLElement},touch:function(){return t&&("ontouchstart"in t||t.DocumentTouch&&document instanceof DocumentTouch)}}}(cytoscape,"undefined"==typeof window?null:window),function(e){"use strict";e.util={extend:function(){var t,r,a,i,n,o,s=arguments[0]||{},l=1,c=arguments.length,d=!1;for("boolean"==typeof s&&(d=s,s=arguments[1]||{},l=2),"object"==typeof s||e.is.fn(s)||(s={}),c===l&&(s=this,--l);c>l;l++)if(null!=(t=arguments[l]))for(r in t)a=s[r],i=t[r],s!==i&&(d&&i&&(e.is.plainObject(i)||(n=e.is.array(i)))?(n?(n=!1,o=a&&e.is.array(a)?a:[]):o=a&&e.is.plainObject(a)?a:{},s[r]=e.util.extend(d,o,i)):void 0!==i&&(s[r]=i));return s},error:function(e){if(!console)throw e;if(console.error)console.error(e);else{if(!console.log)throw e;console.log(e)}},clone:function(e){var t={};for(var r in e)e.hasOwnProperty(r)&&(t[r]=e[r]);return t},copy:function(t){return null==t?t:e.is.array(t)?t.slice():e.is.plainObject(t)?e.util.clone(t):t},mapEmpty:function(e){var t=!0;if(null!=e)for(var r in e){t=!1;break}return t},pushMap:function(t){var r=e.util.getMap(t);null==r?e.util.setMap($.extend({},t,{value:[t.value]})):r.push(t.value)},setMap:function(t){for(var r,a=t.map,i=t.keys,n=i.length,o=0;n>o;o++){var r=i[o];e.is.plainObject(r)&&e.util.error("Tried to set map with object key"),on;n++){var o=a[n];if(e.is.plainObject(o)&&e.util.error("Tried to get map with object key"),r=r[o],null==r)return r}return r},deleteMap:function(t){for(var r=t.map,a=t.keys,i=a.length,n=t.keepChildren,o=0;i>o;o++){var s=a[o];e.is.plainObject(s)&&e.util.error("Tried to delete map with object key");var l=o===t.keys.length-1;if(l)if(n)for(var c in r)n[c]||delete r[c];else delete r[s];else r=r[s]}},capitalize:function(t){return e.is.emptyString(t)?t:t.charAt(0).toUpperCase()+t.substring(1)},camel2dash:function(e){for(var t=[],r=0;rt&&" "===e[r];r--);return e.substring(t,r+1)},hex2tuple:function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,r,a,i=4===e.length,n=16;return i?(t=parseInt(e[1]+e[1],n),r=parseInt(e[2]+e[2],n),a=parseInt(e[3]+e[3],n)):(t=parseInt(e[1]+e[2],n),r=parseInt(e[3]+e[4],n),a=parseInt(e[5]+e[6],n)),[t,r,a]}},hsl2tuple:function(t){function r(e,t,r){return 0>r&&(r+=1),r>1&&(r-=1),1/6>r?e+6*(t-e)*r:.5>r?t:2/3>r?e+(t-e)*(2/3-r)*6:e}var a,i,n,o,s,l,c,d,u=(e.util.regex.number,new RegExp("^"+e.util.regex.hsla+"$").exec(t));if(u){if(i=parseInt(u[1]),0>i?i=(360- -1*i%360)%360:i>360&&(i%=360),i/=360,n=parseFloat(u[2]),0>n||n>100)return;if(n/=100,o=parseFloat(u[3]),0>o||o>100)return;if(o/=100,s=u[4],void 0!==s&&(s=parseFloat(s),0>s||s>1))return;if(0===n)l=c=d=Math.round(255*o);else{var p=.5>o?o*(1+n):o+n-o*n,h=2*o-p;l=Math.round(255*r(h,p,i+1/3)),c=Math.round(255*r(h,p,i)),d=Math.round(255*r(h,p,i-1/3))}a=[l,c,d,s]}return a},rgb2tuple:function(t){var r,a=(e.util.regex.number,new RegExp("^"+e.util.regex.rgba+"$").exec(t));if(a){r=[];for(var i=[],n=1;3>=n;n++){var o=a[n];if("%"===o[o.length-1]&&(i[n]=!0),o=parseFloat(o),i[n]&&(o=o/100*255),0>o||o>255)return;r.push(Math.floor(o))}var s=i[1]||i[2]||i[3],l=i[1]&&i[2]&&i[3];if(s&&!l)return;var c=a[4];if(void 0!==c){if(c=parseFloat(c),0>c||c>1)return;r.push(c)}}return r},colorname2tuple:function(t){return e.util.colors[t.toLowerCase()]},color2tuple:function(t){return e.util.colorname2tuple(t)||e.util.hex2tuple(t)||e.util.rgb2tuple(t)||e.util.hsl2tuple(t)},tuple2hex:function(e){function t(e){var t=e.toString(16);return 1===t.length&&(t="0"+t),t}var r=e[0],a=e[1],i=e[2];return"#"+t(r)+t(a)+t(i)},colors:{transparent:[0,0,0,0],aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],grey:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]}},e.util.regex={},e.util.regex.number="(?:[-]?\\d*\\.\\d+|[-]?\\d+|[-]?\\d*\\.\\d+[eE]\\d+)",e.util.regex.rgba="rgb[a]?\\(("+e.util.regex.number+"[%]?)\\s*,\\s*("+e.util.regex.number+"[%]?)\\s*,\\s*("+e.util.regex.number+"[%]?)(?:\\s*,\\s*("+e.util.regex.number+"))?\\)",e.util.regex.rgbaNoBackRefs="rgb[a]?\\((?:"+e.util.regex.number+"[%]?)\\s*,\\s*(?:"+e.util.regex.number+"[%]?)\\s*,\\s*(?:"+e.util.regex.number+"[%]?)(?:\\s*,\\s*(?:"+e.util.regex.number+"))?\\)",e.util.regex.hsla="hsl[a]?\\(("+e.util.regex.number+")\\s*,\\s*("+e.util.regex.number+"[%])\\s*,\\s*("+e.util.regex.number+"[%])(?:\\s*,\\s*("+e.util.regex.number+"))?\\)",e.util.regex.hslaNoBackRefs="hsl[a]?\\((?:"+e.util.regex.number+")\\s*,\\s*(?:"+e.util.regex.number+"[%])\\s*,\\s*(?:"+e.util.regex.number+"[%])(?:\\s*,\\s*(?:"+e.util.regex.number+"))?\\)",e.util.regex.hex3="\\#[0-9a-fA-F]{3}",e.util.regex.hex6="\\#[0-9a-fA-F]{6}"}(cytoscape),function(e){"use strict";e.math={},e.math.signum=function(e){return e>0?1:0>e?-1:0},e.math.distance=function(e,t){var r=t.x-e.x,a=t.y-e.y;return Math.sqrt(r*r+a*a)},e.math.qbezierAt=function(e,t,r,a){return(1-a)*(1-a)*e+2*(1-a)*a*t+a*a*r},e.math.qbezierPtAt=function(t,r,a,i){return{x:e.math.qbezierAt(t.x,r.x,a.x,i),y:e.math.qbezierAt(t.y,r.y,a.y,i)}},e.math.roundRectangleIntersectLine=function(e,t,r,a,i,n,o){var s,l=this.getRoundRectangleRadius(i,n),c=i/2,d=n/2,u=r-c+l-o,p=a-d-o,h=r+c-l+o,v=p;if(s=this.finiteLinesIntersect(e,t,r,a,u,p,h,v,!1),s.length>0)return s;var g=r+c+o,f=a-d+l-o,y=g,m=a+d-l+o;if(s=this.finiteLinesIntersect(e,t,r,a,g,f,y,m,!1),s.length>0)return s;var b=r-c+l-o,x=a+d+o,w=r+c-l+o,_=x;if(s=this.finiteLinesIntersect(e,t,r,a,b,x,w,_,!1),s.length>0)return s;var E=r-c-o,S=a-d+l-o,P=E,M=a+d-l+o;if(s=this.finiteLinesIntersect(e,t,r,a,E,S,P,M,!1),s.length>0)return s;var k,C=r-c+l,D=a-d+l;if(k=this.intersectLineCircle(e,t,r,a,C,D,l+o),k.length>0&&k[0]<=C&&k[1]<=D)return[k[0],k[1]];var N=r+c-l,T=a-d+l;if(k=this.intersectLineCircle(e,t,r,a,N,T,l+o),k.length>0&&k[0]>=N&&k[1]<=T)return[k[0],k[1]];var I=r+c-l,z=a+d-l;if(k=this.intersectLineCircle(e,t,r,a,I,z,l+o),k.length>0&&k[0]>=I&&k[1]>=z)return[k[0],k[1]];var B=r-c+l,X=a+d-l;return k=this.intersectLineCircle(e,t,r,a,B,X,l+o),k.length>0&&k[0]<=B&&k[1]>=X?[k[0],k[1]]:[]},e.math.roundRectangleIntersectBox=function(e,t,r,a,i,n,o,s,l){var c=this.getRoundRectangleRadius(i,n),d=o-i/2-l,u=s-n/2+c-l,p=o+i/2+l,h=s+n/2-c+l,v=o-i/2+c-l,g=s-n/2-l,f=o+i/2-c+l,y=s+n/2+l,m=Math.min(e,r),b=Math.max(e,r),x=Math.min(t,a),w=Math.max(t,a);return d>b?!1:m>p?!1:g>w?!1:x>y?!1:d>=m&&b>=d&&u>=x&&w>=u?!0:p>=m&&b>=p&&u>=x&&w>=u?!0:p>=m&&b>=p&&h>=x&&w>=h?!0:d>=m&&b>=d&&h>=x&&w>=h?!0:m>=d&&p>=m&&x>=u&&h>=x?!0:b>=d&&p>=b&&x>=u&&h>=x?!0:b>=d&&p>=b&&w>=u&&h>=w?!0:m>=d&&p>=m&&w>=u&&h>=w?!0:v>=m&&b>=v&&g>=x&&w>=g?!0:f>=m&&b>=f&&g>=x&&w>=g?!0:f>=m&&b>=f&&y>=x&&w>=y?!0:v>=m&&b>=v&&y>=x&&w>=y?!0:m>=v&&f>=m&&x>=g&&y>=x?!0:b>=v&&f>=b&&x>=g&&y>=x?!0:b>=v&&f>=b&&w>=g&&y>=w?!0:m>=v&&f>=m&&w>=g&&y>=w?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,v+l,u+l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,f-l,u+l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,f-l,h-l)?!0:this.boxIntersectEllipse(m,x,b,w,l,2*c,2*c,v+l,h-l)?!0:!1},e.math.checkInBoundingCircle=function(e,t,r,a,i,n,o,s){return e=(e-o)/(i+a),t=(t-s)/(n+a),r>=e*e+t*t},e.math.checkInBoundingBox=function(e,t,r,a,i,n,o,s){for(var l=r[0],c=r[1],d=r[0],u=r[1],p=1;pd&&(d=r[2*p]),r[2*p+1]u&&(u=r[2*p+1]);return e-=o,t-=s,e/=i,t/=n,l>e?!1:e>d?!1:c>t?!1:t>u?!1:!0},e.math.boxInBezierVicinity=function(e,t,r,a,i,n,o,s,l,c,d){var u=.25*i+.5*o+.25*l,p=.25*n+.5*s+.25*c,h=Math.min(e,r)-d,v=Math.min(t,a)-d,g=Math.max(e,r)+d,f=Math.max(t,a)+d;if(i>=h&&g>=i&&n>=v&&f>=n)return 1;if(l>=h&&g>=l&&c>=v&&f>=c)return 1;if(u>=h&&g>=u&&p>=v&&f>=p)return 1;if(o>=h&&g>=o&&s>=v&&f>=s)return 1;var y=Math.min(i,u,l),m=Math.min(n,p,c),b=Math.max(i,u,l),x=Math.max(n,p,c);return y>g||h>b||m>f||v>x?0:1},e.math.checkBezierInBox=function(t,r,a,i,n,o,s,l,c,d){function u(u){var p=e.math.qbezierAt(n,s,c,u),h=e.math.qbezierAt(o,l,d,u);return p>=t&&a>=p&&h>=r&&i>=h}for(var p=0;1>=p;p+=.25)if(!u(p))return!1;return!0},e.math.checkStraightEdgeInBox=function(e,t,r,a,i,n,o,s){return i>=e&&r>=i&&o>=e&&r>=o&&n>=t&&a>=n&&s>=t&&a>=s},e.math.checkStraightEdgeCrossesBox=function(e,t,r,a,i,n,o,s,l){var c,d,u=Math.min(e,r)-l,p=Math.min(t,a)-l,h=Math.max(e,r)+l,v=Math.max(t,a)+l,g=o-i,f=i,y=s-n,m=n;if(Math.abs(g)<1e-4)return i>=u&&h>=i&&Math.min(n,s)<=p&&Math.max(n,s)>=v;var b=(u-f)/g;if(b>0&&1>=b&&(c=y*b+m,c>=p&&v>=c))return!0;var x=(h-f)/g;if(x>0&&1>=x&&(c=y*x+m,c>=p&&v>=c))return!0;var w=(p-m)/y;if(w>0&&1>=w&&(d=g*w+f,d>=u&&h>=d))return!0;var _=(v-m)/y;return _>0&&1>=_&&(d=g*_+f,d>=u&&h>=d)?!0:!1},e.math.checkBezierCrossesBox=function(e,t,r,a,i,n,o,s,l,c,d){var u=Math.min(e,r)-d,p=Math.min(t,a)-d,h=Math.max(e,r)+d,v=Math.max(t,a)+d;if(i>=u&&h>=i&&n>=p&&v>=n)return!0;if(l>=u&&h>=l&&c>=p&&v>=c)return!0;var g=i-2*o+l,f=-2*i+2*o,y=i,m=[];if(Math.abs(g)<1e-4){var b=(u-i)/f,x=(h-i)/f;m.push(b,x)}else{var w,_,E=f*f-4*g*(y-u);if(E>0){var S=Math.sqrt(E);w=(-f+S)/(2*g),_=(-f-S)/(2*g),m.push(w,_)}var P,M,k=f*f-4*g*(y-h);if(k>0){var S=Math.sqrt(k);P=(-f+S)/(2*g),M=(-f-S)/(2*g),m.push(P,M)}}m.sort(function(e,t){return e-t});var C=n-2*s+c,D=-2*n+2*s,N=n,T=[];if(Math.abs(C)<1e-4){var I=(p-n)/D,z=(v-n)/D;T.push(I,z)}else{var B,X,R=D*D-4*C*(N-p);if(R>0){var S=Math.sqrt(R);B=(-D+S)/(2*C),X=(-D-S)/(2*C),T.push(B,X)}var Y,L,V=D*D-4*C*(N-v);if(V>0){var S=Math.sqrt(V);Y=(-D+S)/(2*C),L=(-D-S)/(2*C),T.push(Y,L)}}T.sort(function(e,t){return e-t});for(var A=0;A=0&&m[A]<=1&&m[A+1]>T[q-1]&&T[q-1]<=1&&m[A+1]>=0)return!0;return!1},e.math.inLineVicinity=function(e,t,r,a,i,n,o){var s=o,l=Math.min(r,i),c=Math.max(r,i),d=Math.min(a,n),u=Math.max(a,n);return e>=l-s&&c+s>=e&&t>=d-s&&u+s>=t},e.math.inBezierVicinity=function(e,t,r,a,i,n,o,s,l){var c={x1:Math.min(r,o,i),x2:Math.max(r,o,i),y1:Math.min(a,s,n),y2:Math.max(a,s,n)};return ec.x2||tc.y2?!1:!0;var c},e.math.solveCubic=function(e,t,r,a,i){t/=e,r/=e,a/=e;var n,o,s,l,c,d,u,p;return o=(3*r-t*t)/9,s=-(27*a)+t*(9*r-2*t*t),s/=54,n=o*o*o+s*s,i[1]=0,u=t/3,n>0?(c=s+Math.sqrt(n),c=0>c?-Math.pow(-c,1/3):Math.pow(c,1/3),d=s-Math.sqrt(n),d=0>d?-Math.pow(-d,1/3):Math.pow(d,1/3),i[0]=-u+c+d,u+=(c+d)/2,i[4]=i[2]=-u,u=Math.sqrt(3)*(-d+c)/2,i[3]=u,void(i[5]=-u)):(i[5]=i[3]=0,0==n?(p=0>s?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=-u+2*p,void(i[4]=i[2]=-(p+u))):(o=-o,l=o*o*o,l=Math.acos(s/Math.sqrt(l)),p=2*Math.sqrt(o),i[0]=-u+p*Math.cos(l/3),i[2]=-u+p*Math.cos((l+2*Math.PI)/3),void(i[4]=-u+p*Math.cos((l+4*Math.PI)/3))))},e.math.sqDistanceToQuadraticBezier=function(e,t,r,a,i,n,o,s){var l=1*r*r-4*r*i+2*r*o+4*i*i-4*i*o+o*o+a*a-4*a*n+2*a*s+4*n*n-4*n*s+s*s,c=9*r*i-3*r*r-3*r*o-6*i*i+3*i*o+9*a*n-3*a*a-3*a*s-6*n*n+3*n*s,d=3*r*r-6*r*i+r*o-r*e+2*i*i+2*i*e-o*e+3*a*a-6*a*n+a*s-a*t+2*n*n+2*n*t-s*t,u=1*r*i-r*r+r*e-i*e+a*n-a*a+a*t-n*t,p=[];this.solveCubic(l,c,d,u,p);for(var h=1e-7,v=[],g=0;6>g;g+=2)Math.abs(p[g+1])=0&&p[g]<=1&&v.push(p[g]);v.push(1),v.push(0);for(var f,y,m,b,x=-1,w=0;w=0?x>b&&(x=b,f=v[w]):(x=b,f=v[w]);return x},e.math.sqDistanceToFiniteLine=function(e,t,r,a,i,n){var o=[e-r,t-a],s=[i-r,n-a],l=s[0]*s[0]+s[1]*s[1],c=o[0]*o[0]+o[1]*o[1],d=o[0]*s[0]+o[1]*s[1],u=d*d/l;return 0>d?c:u>l?(e-i)*(e-i)+(t-n)*(t-n):c-u},e.math.pointInsidePolygon=function(e,t,r,a,i,n,o,s,l){var c=new Array(r.length),d=Math.asin(s[1]/Math.sqrt(s[0]*s[0]+s[1]*s[1]));s[0]<0?d+=Math.PI/2:d=-d-Math.PI/2;for(var u=Math.cos(-d),p=Math.sin(-d),h=0;h0){var g=this.expandPolygon(c,-l);v=this.joinLines(g)}else v=c;for(var f,y,m,b,x,w=0,_=0,h=0;h=e&&e>=m||e>=f&&m>=e))continue;x=(e-f)/(m-f)*(b-y)+y,x>t&&w++,t>x&&_++}return w%2==0?!1:!0},e.math.joinLines=function(e){for(var t,r,a,i,n,o,s,l,c=new Array(e.length/2),d=0;dc)return[];var d=c/l;return[(r-e)*d+e,(a-t)*d+t]},e.math.dotProduct=function(e,t){if(2!=e.length||2!=t.length)throw"dot product: arguments are not vectors";return e[0]*t[0]+e[1]*t[1]},e.math.intersectLineCircle=function(e,t,r,a,i,n,o){var s=[r-e,a-t],l=[i,n],c=[e-i,t-n],d=s[0]*s[0]+s[1]*s[1],u=2*(c[0]*s[0]+c[1]*s[1]),l=c[0]*c[0]+c[1]*c[1]-o*o,p=u*u-4*d*l;if(0>p)return[];var h=(-u+Math.sqrt(p))/(2*d),v=(-u-Math.sqrt(p))/(2*d),g=Math.min(h,v),f=Math.max(h,v),y=[];if(g>=0&&1>=g&&y.push(g),f>=0&&1>=f&&y.push(f),0==y.length)return[];var m=y[0]*s[0]+e,b=y[0]*s[1]+t;if(y.length>1){if(y[0]==y[1])return[m,b];var x=y[1]*s[0]+e,w=y[1]*s[1]+t;return[m,b,x,w]}return[m,b]},e.math.findCircleNearPoint=function(e,t,r,a,i){var n=a-e,o=i-t,s=Math.sqrt(n*n+o*o),l=n/s,c=o/s;return[e+l*r,t+c*r]},e.math.findMaxSqDistanceToOrigin=function(e){for(var t,r=1e-6,a=0;ar&&(r=t);return r},e.math.finiteLinesIntersect=function(e,t,r,a,i,n,o,s,l){var c=(o-i)*(t-n)-(s-n)*(e-i),d=(r-e)*(t-n)-(a-t)*(e-i),u=(s-n)*(r-e)-(o-i)*(a-t);if(0!=u){var p=c/u,h=d/u;return p>=0&&1>=p&&h>=0&&1>=h?[e+p*(r-e),t+p*(a-t)]:l?[e+p*(r-e),t+p*(a-t)]:[]}return 0==c||0==d?[e,r,o].sort()[1]==o?[o,s]:[e,r,i].sort()[1]==i?[i,n]:[i,o,r].sort()[1]==r?[r,a]:[]:[]},e.math.boxIntersectEllipse=function(e,t,r,a,i,n,o,s,l){if(e>r){var c=e;e=r,r=c}if(t>a){var d=t;t=a,a=d}var u=[s-n/2-i,l],p=[s+n/2+i,l],h=[s,l-o/2-i],v=[s,l+o/2+i];return rp[0]?!1:t>v[1]?!1:a=e*e+t*t?!0:1>=r*r+t*t?!0:1>=r*r+a*a?!0:1>=e*e+a*a?!0:!1)},e.math.boxIntersectPolygon=function(t,r,a,i,n,o,s,l,c,d,u){if(t>a){var p=t;t=a,a=p}if(r>i){var h=r;r=i,i=h}var v=new Array(n.length),g=Math.asin(d[1]/Math.sqrt(d[0]*d[0]+d[1]*d[1]));d[0]<0?g+=Math.PI/2:g=-g-Math.PI/2;for(var f=Math.cos(-g),y=Math.sin(-g),m=0;mx&&(x=v[2*m]),v[2*m]_&&(_=v[2*m+1]),v[2*m+1]a)return!1;if(t>x+u)return!1;if(w-u>i)return!1;if(r>_+u)return!1;var E;if(u>0){var S=e.math.expandPolygon(v,-u);E=e.math.joinLines(S)}else E=v;for(var m=0;m0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,t,i,a,i,!1).length>0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,t,r,t,i,!1).length>0)return!0;if(e.math.finiteLinesIntersect(k,C,P,M,a,r,a,i,!1).length>0)return!0}return!1},e.math.polygonIntersectLine=function(t,r,a,i,n,o,s,l){for(var c,d=[],u=new Array(a.length),p=0;p0){var v=e.math.expandPolygon(u,-l);h=e.math.joinLines(v)}else h=u;for(var g,f,y,m,p=0;pn&&(n=1e-5),[t[0]+n*a[0],t[1]+n*a[1]]},e.math.generateUnitNgonPointsFitToSquare=function(t,r){var a=e.math.generateUnitNgonPoints(t,r);return a=e.math.fitPolygonToSquare(a)},e.math.fitPolygonToSquare=function(e){for(var t,r,a=e.length/2,i=1/0,n=1/0,o=-1/0,s=-1/0,l=0;a>l;l++)t=e[2*l],r=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),n=Math.min(n,r),s=Math.max(s,r);for(var c=2/(o-i),d=2/(s-n),l=0;a>l;l++)t=e[2*l]=e[2*l]*c,r=e[2*l+1]=e[2*l+1]*d,i=Math.min(i,t),o=Math.max(o,t),n=Math.min(n,r),s=Math.max(s,r);if(-1>n)for(var l=0;a>l;l++)r=e[2*l+1]=e[2*l+1]+(-1-n);return e},e.math.generateUnitNgonPoints=function(e,t){var r=1/e*2*Math.PI,a=e%2==0?Math.PI/2+r/2:Math.PI/2;a+=t;for(var i,n,o,s=new Array(2*e),l=0;e>l;l++)i=l*r+a,n=s[2*l]=Math.cos(i),o=s[2*l+1]=Math.sin(-i);return s},e.math.getRoundRectangleRadius=function(e,t){return Math.min(e/2,t/2,10)}}(cytoscape),function(e){"use strict";e.instances=[],e.instanceCounter=0,e.lastInstanceTime,e.registerInstance=function(t,r){var a;e.is.core(t)?a=t:e.is.domElement(t)&&(r=t);var i=e.getRegistrationForInstance(t,r);if(i)return i.cy?e.util.error("Tried to register on a pre-existing registration"):(i.cy=t,i.domElement=r),i;var n,o=+new Date;e.lastInstanceTime&&e.lastInstanceTime!==o?++e.instanceCounter:e.instanceCounter=0,e.lastInstanceTime=o,n=e.instanceCounter;var s="cy-"+o+"-"+n,l={id:s,cy:a,domElement:r,readies:[]};return e.instances.push(l),e.instances[s]=l,l},e.removeRegistrationForInstance=function(t,r){var a;if(e.is.core(t)?a=t:e.is.domElement(t)&&(r=t),e.is.core(a)){var i=a._private.instanceId;delete e.instances[i],e.instances.splice(i,1)}else if(e.is.domElement(r))for(var n=0;n=0;n--){var o=e.instances[n];if(o.domElement===r)return o}}}(cytoscape),function(e){"use strict";function t(t,r,a){var i={};switch(i[r]=a,t){case"core":case"collection":e.fn[t](i)}return e.util.setMap({map:n,keys:[t,r],value:a})}function r(t,r){return e.util.getMap({map:n,keys:[t,r]})}function a(t,r,a,i,n){return e.util.setMap({map:o,keys:[t,r,a,i],value:n})}function i(t,r,a,i){return e.util.getMap({map:o,keys:[t,r,a,i]})}var n={};e.extensions=n;var o={};e.modules=o,e.extension=function(){return 2==arguments.length?r.apply(this,arguments):3==arguments.length?t.apply(this,arguments):4==arguments.length?i.apply(this,arguments):5==arguments.length?a.apply(this,arguments):void $.error("Invalid extension access syntax")}}(cytoscape),function(e,t){"use strict";e&&(e.fn.cytoscape=function(r){var a=e(this);if("get"===r){var i=t.getRegistrationForInstance(a[0]);return i.cy}if(!t.is.fn(r)){if(t.is.plainObject(r))return a.each(function(){var t=e.extend({},r,{container:e(this)[0]});cytoscape(t)});for(var n=a[0],o=[],s=[],l=1;lu;u++)i.canSet(s[u])&&(s[u]._private[i.field][r]=a);i.updateMappers&&n.updateMappers(),i.onSet(n),i.settingTriggersEvent&&n[i.triggerFnName](i.settingEvent)}}}else if(i.allowSetting&&e.is.plainObject(r)){var h,v,g=r;for(h in g){v=g[h];var d=!i.immutableKeys[h];if(d)for(var u=0,p=s.length;p>u;u++)i.canSet(s[u])&&(s[u]._private[i.field][h]=v)}i.updateMappers&&n.updateMappers(),i.onSet(n),i.settingTriggersEvent&&n[i.triggerFnName](i.settingEvent)}else if(i.allowBinding&&e.is.fn(r)){var f=r;n.bind(i.bindingEvent,f)}else if(i.allowGetting&&void 0===r){var c;return l&&(c=l._private[i.field]),c}return n}},batchData:function(t){var r={field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{},updateMappers:!1},a=t=e.util.extend({},r,t);return function(t){var r=this,i=void 0!==r.length,n=i?r:r._private.elements;if(0===n.length)return r;for(var o=i?n[0]._private.cy:r,s=0;sc;c++){var d=s[c];if(!e.is.emptyString(d)){var u=!a.immutableKeys[d];if(u)for(var p=0,h=o.length;h>p;p++)delete o[p]._private[a.field][d]}}a.triggerEvent&&i[a.triggerFnName](a.event)}else if(void 0===r){for(var p=0,h=o.length;h>p;p++){var v=o[p]._private[a.field];for(var d in v){var g=!a.immutableKeys[d];g&&delete v[d]}}a.triggerEvent&&i[a.triggerFnName](a.event)}return i}},event:{regex:/(\w+)(\.\w+)?/,optionalTypeRegex:/(\w+)?(\.\w+)?/,falseCallback:function(){return!1}},on:function(t){var r={unbindSelfOnTrigger:!1,unbindAllBindersOnTrigger:!1};return t=e.util.extend({},r,t),function(r,a,i,n){var o=this,s=void 0!==o.length,l=s?o:[o],c=(s?o[0]:o,e.is.string(r)),d=t;if(e.is.plainObject(a)?(n=i,i=a,a=void 0):(e.is.fn(a)||a===!1)&&(n=a,i=void 0,a=void 0),(e.is.fn(i)||i===!1)&&(n=i,i=void 0),!e.is.fn(n)&&n!==!1&&c)return o;if(c){var u={};u[r]=n,r=u}for(var p in r)if(n=r[p],n===!1&&(n=e.define.event.falseCallback),e.is.fn(n)){p=p.split(/\s+/);for(var h=0;h\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",o="(?:[\\w-]|(?:\\\\"+n+"))+",s="=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",l="\\?|\\!|\\^",c='"(?:\\\\"|[^"])+"|'+"'(?:\\\\'|[^'])+'",d=$$.util.regex.number,u=c+"|"+d,p="degree|indegree|outdegree",h="\\s*,\\s*",v=o,g="\\s+",f="\\s+>\\s+",y="\\$",m=o,b=function(e){return e.replace(new RegExp("\\\\("+n+")","g"),function(e,t){return t})},x=s.split("|"),w=0;w=0;break;case"$=":matches=null!=new RegExp(valStr+"$").exec(fieldStr);break;case"^=":matches=null!=new RegExp("^"+valStr).exec(fieldStr);break;default:if(caseInsensitive){var expr="fieldStr "+operator+" valStr";matches=eval(expr)}else{var expr=params.fieldRef(field)+" "+operator+" "+value;matches=eval(expr)}}}else if(null!=operator)switch(operator){case"?":matches=params.fieldTruthy(field);break;case"!":matches=!params.fieldTruthy(field);break;case"^":matches=params.fieldUndefined(field)}else matches=!params.fieldUndefined(field);if(!matches){allDataMatches=!1;break}}return allDataMatches},allDataMatches=operandsMatch({name:"data",fieldValue:function(e){return element._private.data[e]},fieldRef:function(e){return"element._private.data."+e},fieldUndefined:function(e){return void 0===element._private.data[e]},fieldTruthy:function(e){return element._private.data[e]?!0:!1}});if(!allDataMatches)return!1;var allMetaMatches=operandsMatch({name:"meta",fieldValue:function(e){return element[e]()},fieldRef:function(e){return"element."+e+"()"},fieldUndefined:function(e){return void 0==element[e]()},fieldTruthy:function(e){return element[e]()?!0:!1}});if(!allMetaMatches)return!1;if(null!=query.collection){var matchesAny=null!=query.collection._private.ids[element.id()];if(!matchesAny)return!1}if(null!=query.filter&&0==element.collection().filter(query.filter).size())return!1;var confirmRelations=function(e,t){if(null!=e){var r=!1;t=t();for(var a=0;a "+i),null!=e.ancestor&&(i=r(e.ancestor)+" "+i),null!=e.child&&(i+=" > "+r(e.child)),null!=e.descendant&&(i+=" "+r(e.descendant)),i},a=0;a1&&an.length?l.substr(n.length):""}function i(){o=o.length>s.length?o.substr(s.length):""}var n,o,s,l=""+r;for(l=l.replace(/[/][*](\s|.)+?[*][/]/g,"");;){var c=l.match(/^\s*$/);if(c)break;var d=l.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!d){e.util.error("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+l);break}n=d[0];var u=d[1],p=new e.Selector(u);if(p._private.invalid)e.util.error("Skipping parsing of block: Invalid selector found in string stylesheet: "+u),a();else{var h=d[2],v=!1;o=h;for(var g=[];;){var c=o.match(/^\s*$/);if(c)break;var f=o.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/);if(!f){e.util.error("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+h),v=!0;break}s=f[0];var y=f[1],m=f[2],b=e.style.properties[y];if(b){var x=t.parse(y,m);x?(g.push({name:y,val:m}),i()):(e.util.error("Skipping property: Invalid property definition in: "+s),i())}else e.util.error("Skipping property: Invalid property name in: "+s),i()}if(v){a();break}t.selector(u);for(var w=0;w node").css({width:"auto",height:"auto",shape:"rectangle","background-opacity":.5,"padding-top":10,"padding-right":10,"padding-left":10,"padding-bottom":10}).selector("edge").css({width:1}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}).selector("core").css({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"panning-cursor":"grabbing","active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":r?40:15})},e.styfn.clear=function(){this._private.newStyle=!0;for(var e=0;es.max)return null;var S={name:t,value:r,strValue:""+r+(m?m:""),units:m,bypass:a,pxValue:s.unitless||"%"===m?void 0:"px"!==m&&m?this.getEmSizeInPixels()*r:r};return S}if(s.color){var P=e.util.color2tuple(r);return{name:t,value:P,strValue:r,bypass:a}}if(!s.enums){if(s.regex){var M=new RegExp(s.regex),k=M.exec(r);return k?{name:t,value:k,strValue:r,bypass:a}:null}return s.string?{name:t,value:r,strValue:r,bypass:a}:null}for(var _=0;_0,s=n.properties;if(o){for(var l=0;lo;o++){var u=c[o],p=l[u];if(e.is.array(p))for(var h=0,v=p.length;v>h;h++){var g=p[h],f=e.util.extend({},g,{group:u});n.push(f)}}r=new e.Collection(a,n)}else{var g=t;r=new e.Element(a,g).collection()}return r},remove:function(t){if(e.is.elementOrCollection(t))t=t;else if(e.is.string(t)){var r=t;t=this.$(r)}return t.remove()},load:function(a,i,n){function o(){s.one("layoutready",function(e){s.notifications(!0),s.trigger(e),s.notify({type:"load",collection:s.elements()}),s.one("load",i),s.trigger("load")}).one("layoutstop",function(){s.one("done",n),s.trigger("done")}),s.layout(s._private.options.layout)}var s=this,l=s.elements();return l.length>0&&l.remove(),s.notifications(!1),null!=a&&(e.is.plainObject(a)||e.is.array(a))&&s.add(a),t?r(o):o(),this}})}(cytoscape,"undefined"==typeof window?null:window),function(e){"use strict";e.fn.core({addToAnimationPool:function(e){for(var t=this,r=t._private.aniEles,a=[],i=0;i0?c.shift():null;null!=d&&(d.callTime=+new Date,s.push(d))}for(var u=[],p=0;p0&&o.notify({type:"draw",collection:r});for(var p=0;p0||l.length>0;g||(r.splice(p,1),p--)}}function a(t,r,a){var s,l=o._private.style,c=r.properties,d=r.params,u=r.callTime;if(s=0===r.duration?1:Math.min(1,(a-u)/r.duration),0>s?s=0:s>1&&(s=1),null==c.delay){var p=r.startPosition,h=c.position,v=t._private.position;if(h&&(i(p.x,h.x)&&(v.x=n(p.x,h.x,s)),i(p.y,h.y)&&(v.y=n(p.y,h.y,s))),c.css)for(var g=e.style.properties,f=0;f=1&&(r.done=!0),s}function i(t,r){return null==t||null==r?!1:e.is.number(t)&&e.is.number(r)?!0:t&&r?!0:!1}function n(t,r,a){if(0>a?a=0:a>1&&(a=1),e.is.number(t)&&e.is.number(r))return t+(r-t)*a;if(e.is.number(t[0])&&e.is.number(r[0])){var i=t,n=r,o=function(e,t){var r=t-e,i=e;return Math.round(a*r+i)},s=o(i[0],n[0]),l=o(i[1],n[1]),c=o(i[2],n[2]);return"rgb("+s+", "+l+", "+c+")"}return void 0}var o=this,s=1e3/60,l=!1,c=!0;o._private.aniEles=[];var d="undefined"==typeof window?function(){}:window.requestAnimationFrame||window.mozRequestAnimationFrame||window.webkitRequestAnimationFrame||window.msRequestAnimationFrame;null!=d&&c||(d=function(e){window.setTimeout(function(){e(+new Date)},s)});var u=o.container();t()}})}(cytoscape),function(e){"use strict";e.fn.core({data:e.define.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0}),removeData:e.define.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0}),batchData:e.define.batchData({field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),scratch:e.define.data({field:"scratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeScratch:e.define.removeData({field:"scratch",triggerEvent:!1})})}(cytoscape),function(e){"use strict";e.fn.core({on:e.define.on(),one:e.define.on({unbindSelfOnTrigger:!0}),once:e.define.on({unbindAllBindersOnTrigger:!0}),off:e.define.off(),trigger:e.define.trigger()}),e.corefn.bind=e.corefn.on,e.corefn.unbind=e.corefn.off}(cytoscape),function(e){"use strict";e.fn.core({png:function(e){var t=this._private.renderer;return e=e||{},t.png(e)}})}(cytoscape),function(e){"use strict";e.fn.core({layout:function(e){var t=this;return this._private.layoutRunning?this:(null==e&&(e=this._private.options.layout),this.initLayout(e),t.trigger("layoutstart"),this._private.layoutRunning=!0,this.one("layoutstop",function(){t._private.layoutRunning=!1}),this._private.layout.run(),this)},initLayout:function(t){if(null==t)return void e.util.error("Layout options must be specified to run a layout");if(null==t.name)return void e.util.error("A `name` must be specified to run a layout");var r=t.name,a=e.extension("layout",r);return null==a?void e.util.error("Can not apply layout: No such layout `%s` found; did you include its JS file?",r):(this._private.layout=new a(e.util.extend({},t,{renderer:this._private.renderer,cy:this})),void(this._private.options.layout=t))}})}(cytoscape),function(e){"use strict";e.fn.core({notify:function(t){if(this._private.notificationsEnabled){var r=this.renderer(),a=this;if(e.is.element(t.collection)){var i=t.collection;t.collection=new e.Collection(a,[i])}else if(e.is.array(t.collection)){var n=t.collection;t.collection=new e.Collection(a,n)}r.notify(t)}},notifications:function(e){var t=this._private;return void 0===e?t.notificationsEnabled:void(t.notificationsEnabled=e?!0:!1)},noNotifications:function(e){this.notifications(!1),e(),this.notifications(!0)}})}(cytoscape),function(e){"use strict";e.fn.core({renderTo:function(e,t,r){var a=this._private.renderer;return a.renderTo(e,t,r),this},renderer:function(){return this._private.renderer},forceRender:function(){return this.notify({type:"draw"}),this},initRenderer:function(t){var r=this,a=e.extension("renderer",t.name);return null==a?void e.util.error("Can not initialise: No such renderer `%s` found; did you include its JS file?",t.name):void(this._private.renderer=new a(e.util.extend({},t,{cy:r,style:r._private.style})))},recalculateRenderedStyle:function(){var e=this.renderer();e.recalculateRenderedStyle&&e.recalculateRenderedStyle()}})}(cytoscape),function(e){"use strict";e.fn.core({collection:function(t){return e.is.string(t)?this.$(t):e.is.elementOrCollection(t)?t.collection():new e.Collection(this)},nodes:function(e){var t=this.$("node");return e?t.filter(e):t},edges:function(e){var t=this.$("edge");return e?t.filter(e):t},$:function(t){var r=new e.Collection(this,this._private.elements);return t?r.filter(t):r}}),e.corefn.elements=e.corefn.filter=e.corefn.$}(cytoscape),function(e){"use strict";e.fn.core({style:function(){return this._private.style}})}(cytoscape),function(e){"use strict";e.fn.core({panningEnabled:function(e){return void 0===e?this._private.panningEnabled:(this._private.panningEnabled=e?!0:!1,this)},userPanningEnabled:function(e){return void 0===e?this._private.userPanningEnabled:(this._private.userPanningEnabled=e?!0:!1,this)},zoomingEnabled:function(e){return void 0===e?this._private.zoomingEnabled:(this._private.zoomingEnabled=e?!0:!1,this)},userZoomingEnabled:function(e){return void 0===e?this._private.userZoomingEnabled:(this._private.userZoomingEnabled=e?!0:!1,this)},boxSelectionEnabled:function(e){return void 0===e?this._private.boxSelectionEnabled:(this._private.boxSelectionEnabled=e?!0:!1,this)},pan:function(){var t,r,a,i,n,o=arguments,s=this._private.pan;switch(o.length){case 0:return s;case 1:if(!this._private.panningEnabled)return this;if(e.is.string(o[0]))return t=o[0],s[t];e.is.plainObject(o[0])&&(a=o[0],i=a.x,n=a.y,e.is.number(i)&&(s.x=i),e.is.number(n)&&(s.y=n),this.trigger("pan"));break;case 2:if(!this._private.panningEnabled)return this;t=o[0],r=o[1],"x"!==t&&"y"!==t||!e.is.number(r)||(s[t]=r),this.trigger("pan")}return this.notify({type:"viewport"}),this},panBy:function(){var t,r,a,i,n,o=arguments,s=this._private.pan;if(!this._private.panningEnabled)return this;switch(o.length){case 1:e.is.plainObject(o[0])&&(a=o[0],i=a.x,n=a.y,e.is.number(i)&&(s.x+=i),e.is.number(n)&&(s.y+=n),this.trigger("pan"));break;case 2:t=o[0],r=o[1],"x"!==t&&"y"!==t||!e.is.number(r)||(s[t]+=r),this.trigger("pan")}return this.notify({type:"viewport"}),this},fit:function(t,r){if(e.is.number(t)&&void 0===r&&(r=t,t=void 0),!this._private.panningEnabled||!this._private.zoomingEnabled)return this;if(e.is.string(t)){var a=t;t=this.$(a)}else e.is.elementOrCollection(t)||(t=this.elements());var i,n=t.boundingBox(),o=this.style(),s=parseFloat(o.containerCss("width")),l=parseFloat(o.containerCss("height"));return r=e.is.number(r)?r:0,!isNaN(s)&&!isNaN(l)&&t.length>0&&(i=this._private.zoom=Math.min((s-2*r)/n.w,(l-2*r)/n.h),i=i>this._private.maxZoom?this._private.maxZoom:i,i=ithis._private.maxZoom?this._private.maxZoom:a,a=a1&&this._private.minZoom<1&&this.zoom(1),this.notify({type:"viewport"}),this):this}})}(cytoscape),function(e){"use strict";e.fn.collection=e.fn.eles=function(t){for(var r in t){var a=t[r];e.Collection.prototype[r]=a}};var t={prefix:{nodes:"n",edges:"e"},id:{nodes:0,edges:0},generate:function(t,r,a){var i=e.is.element(r)?r._private:r,n=i.group,o=null!=a?a:this.prefix[n]+this.id[n];if(t.getElementById(o).empty())this.id[n]++;else for(;!t.getElementById(o).empty();)o=this.prefix[n]+ ++this.id[n];return o}};e.Element=function(t,r,a){if(!(this instanceof e.Element))return new e.Element(t,r,a);var i=this;if(a=void 0===a||a?!0:!1,void 0===t||void 0===r||!e.is.core(t))return void e.util.error("An element must have a core reference and parameters set");if("nodes"!==r.group&&"edges"!==r.group)return void e.util.error("An element must be of type `nodes` or `edges`; you specified `"+r.group+"`");if(this.length=1,this[0]=this,this._private={cy:t,single:!0,data:r.data||{},layoutData:{},position:r.position||{},autoWidth:void 0,autoHeight:void 0,listeners:[],group:r.group,style:{},rstyle:{},styleCxts:[],removed:!0,selected:r.selected?!0:!1,selectable:void 0===r.selectable?!0:r.selectable?!0:!1,locked:r.locked?!0:!1,grabbed:!1,grabbable:void 0===r.grabbable?!0:r.grabbable?!0:!1,active:!1,classes:{},animation:{current:[],queue:[]},rscratch:{},scratch:{},edges:[],children:[]},r.renderedPosition){var n=r.renderedPosition,o=t.pan(),s=t.zoom();this._private.position={x:(n.x-o.x)/s,y:(n.y-o.y)/s}}if(e.is.string(r.classes))for(var l=r.classes.split(/\s+/),c=0,d=l.length;d>c;c++){var u=l[c];u&&""!==u&&(i._private.classes[u]=!0)}r.css&&t.style().applyBypass(this,r.css),(void 0===a||a)&&this.restore()},e.Collection=function(r,a){if(!(this instanceof e.Collection))return new e.Collection(r,a);if(void 0===r||!e.is.core(r))return void e.util.error("A collection must have a reference to the core");var i={},n=[],o=!1;if(a){if(a.length>0&&e.is.plainObject(a[0])&&!e.is.element(a[0])){o=!0;for(var s=[],l={},c=0,d=a.length;d>c;c++){var u=a[c];null==u.data&&(u.data={});var p=u.data;if(null==p.id)p.id=t.generate(r,u);else if(0!=r.getElementById(p.id).length||l[p.id])continue;var h=new e.Element(r,u,!1);s.push(h),l[p.id]=!0}a=s}}else a=[];for(var c=0,d=a.length;d>c;c++){var v=a[c];if(v){var g=v._private.data.id;i[g]||(i[g]=v,n.push(v))}}for(var c=0,d=n.length;d>c;c++)this[c]=n[c];this.length=n.length,this._private={cy:r,ids:i},o&&this.restore()},e.elefn=e.elesfn=e.Element.prototype=e.Collection.prototype,e.elesfn.cy=function(){return this._private.cy},e.elesfn.element=function(){return this[0]},e.elesfn.collection=function(){return e.is.collection(this)?this:new e.Collection(this._private.cy,[this])},e.elesfn.json=function(){var t=this.element();if(null==t)return void 0;var r=t._private,a=e.util.copy({data:r.data,position:r.position,group:r.group,bypass:r.bypass,removed:r.removed,selected:r.selected,selectable:r.selectable,locked:r.locked,grabbed:r.grabbed,grabbable:r.grabbable,classes:""}),i=[];for(var n in r.classes)i.push(n);for(var o=0;ou;u++){var h=a[u];h.isNode()?(s.push(h),c++):(l.push(h),d++)}o=s.concat(l);for(var u=0,p=o.length;p>u;u++){var h=o[u];if(h.removed()){var v=h._private,g=v.data;if(void 0===g.id)g.id=t.generate(n,h);else{if(e.is.emptyString(g.id)||!e.is.string(g.id)){e.util.error("Can not create element with invalid string ID `"+g.id+"`");continue}if(0!=n.getElementById(g.id).length){e.util.error("Can not create second element with ID `"+g.id+"`");continue}}{g.id}if(h.isEdge()){for(var f=h,y=["source","target"],m=y.length,b=!1,x=0;m>x;x++){var w=y[x],_=g[w];null==_||""===_?(e.util.error("Can not create edge `"+g.id+"` with unspecified "+w),b=!0):n.getElementById(_).empty()&&(e.util.error("Can not create edge `"+g.id+"` with nonexistant "+w+" `"+_+"`"),b=!0)}if(b)continue;var E=n.getElementById(g.source),S=n.getElementById(g.target);E._private.edges.push(f),S._private.edges.push(f)}v.ids={},v.ids[g.id]=h,v.removed=!1,n.addToPool(h),i.push(h)}}for(var u=0;c>u;u++){var P=o[u],g=P._private.data,M=(g.id,P._private.data.parent),k=null!=M;if(k){var C=n.getElementById(M);if(C.empty())delete g.parent;else{for(var D=!1,N=C;!N.empty();){if(P.same(N)){D=!0,delete g.parent;break}N=N.parent()}D||(C[0]._private.children.push(P),n._private.hasCompoundNodes=!0)}}}if(i=new e.Collection(n,i),i.length>0){var T=i.add(i.connectedNodes()).add(i.parent());T.updateStyle(r),r?i.rtrigger("add"):i.trigger("add")}return a},e.elesfn.removed=function(){var e=this[0];return e&&e._private.removed},e.elesfn.inside=function(){var e=this[0];return e&&!e._private.removed},e.elesfn.remove=function(t){function r(e){for(var t=e._private.edges,r=0;rp;p++){var v=s[p];i(v)}for(var p=0;p0&&(t&&this.cy().notify({type:"remove",collection:b}),b.trigger("remove"));for(var x={},p=0;p0:void 0},clearQueue:function(){for(var e=0;e0&&new e.Collection(this._private.cy,a).updateStyle(),r.trigger("class"),r},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes[e]?!0:!1},toggleClass:function(t,r){for(var a=t.split(/\s+/),i=this,n=[],o=0,s=i.length;s>o;o++)for(var l=i[o],c=0;c0&&new e.Collection(this._private.cy,n).updateStyle(),i.trigger("class"),i},removeClass:function(t){t=t.split(/\s+/);for(var r=this,a=[],i=0;i0&&new e.Collection(r._private.cy,a).updateStyle(),r.trigger("class"),r}})}(cytoscape),function(e){"use strict";e.fn.eles({allAre:function(e){return this.filter(e).length===this.length},is:function(e){return this.filter(e).length>0},same:function(e){return e=this.cy().collection(e),this.length!==e.length?!1:this.intersect(e).length===this.length},anySame:function(e){return e=this.cy().collection(e),this.intersect(e).length>0},allAreNeighbors:function(e){return e=this.cy().collection(e),this.neighborhood().intersect(e).length===e.length}})}(cytoscape),function(e){"use strict";var t=1,r=0;e.fn.eles({data:e.define.data({field:"data",bindingEvent:"data",allowBinding:!0,allowSetting:!0,settingEvent:"data",settingTriggersEvent:!0,triggerFnName:"trigger",allowGetting:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),removeData:e.define.removeData({field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!0,immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),batchData:e.define.batchData({field:"data",event:"data",triggerFnName:"trigger",immutableKeys:{id:!0,source:!0,target:!0,parent:!0},updateMappers:!0}),scratch:e.define.data({field:"scratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeScratch:e.define.removeData({field:"scratch",triggerEvent:!1}),rscratch:e.define.data({field:"rscratch",allowBinding:!1,allowSetting:!0,settingTriggersEvent:!1,allowGetting:!0}),removeRscratch:e.define.removeData({field:"rscratch",triggerEvent:!1}),id:function(){var e=this[0];return e?e._private.data.id:void 0},position:e.define.data({field:"position",bindingEvent:"position",allowBinding:!0,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!0,triggerFnName:"rtrigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){var t=e.updateCompoundBounds();t.rtrigger("position")},canSet:function(e){return!e.locked()}}),silentPosition:e.define.data({field:"position",bindingEvent:"position",allowBinding:!1,allowSetting:!0,settingEvent:"position",settingTriggersEvent:!1,triggerFnName:"trigger",allowGetting:!0,validKeys:["x","y"],onSet:function(e){e.updateCompoundBounds()},canSet:function(e){return!e.locked()}}),positions:function(t){if(e.is.plainObject(t))this.position(t);else if(e.is.fn(t)){for(var r=t,a=0;al?l:a,i=c>i?c:i,n=n>d?d:n,o=u>o?u:o}else if(v.isEdge()&&t.includeEdges){g=!0;var w=v.source()[0]._private.position,_=v.target()[0]._private.position,E=v._private.rstyle||{};if(l=w.x,c=_.x,d=w.y,u=_.y,l>c){var S=l;l=c,c=S}if(d>u){var S=d;d=u,u=S}a=a>l?l:a,i=c>i?c:i,n=n>d?d:n,o=u>o?u:o;for(var P=E.bezierPts||[],y=v._private.style.width.pxValue,M=0;Mi?k.x+y:i,n=k.y-yo?k.y+y:o}}var C=v._private.style,E=v._private.rstyle,D=C.content.strValue,N=C["font-size"],T=C["text-halign"],I=C["text-valign"],z=E.labelWidth,B=E.labelHeight||N.pxValue,X=E.labelX,R=E.labelY;if(g&&t.includeLabels&&D&&N&&void 0!=B&&void 0!=z&&void 0!=X&&void 0!=R&&T&&I){var Y,L,V,A,q=B,O=z;if(v.isEdge())Y=X-O/2,L=X+O/2,V=R-q/2,A=R+q/2;else{switch(T.value){case"left":Y=X-O,L=X;break;case"center":Y=X-O/2,L=X+O/2;break;case"right":Y=X,L=X+O}switch(I.value){case"top":V=R-q,A=R;break;case"center":V=R-q/2,A=R+q/2;break;case"bottom":V=R,A=R+q}}a=a>Y?Y:a,i=L>i?L:i,n=n>V?V:n,o=A>o?A:o}}}return{x1:a,x2:i,y1:n,y2:o,w:i-a,h:o-n}}})}(cytoscape),function(e){"use strict";function t(e){return function(){var t=this;if(0!==t.length&&t.isNode()&&!t.removed()){for(var r=0,a=t[0],i=a._private.edges,n=0;ne}),maxDegree:r("degree",function(e,t){return e>t}),minIndegree:r("indegree",function(e,t){return t>e}),maxIndegree:r("indegree",function(e,t){return e>t}),minOutdegree:r("outdegree",function(e,t){return t>e}),maxOutdegree:r("outdegree",function(e,t){return e>t})}),e.fn.eles({totalDegree:function(){for(var e=0,t=this.nodes(),r=0;rt&&(t=i+t),0>r&&(r=i+r);for(var n=t;n>=0&&r>n&&i>n;n++)a.push(this[n]);return new e.Collection(this.cy(),a)},size:function(){return this.length},eq:function(e){return this[e]},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(t){if(!e.is.fn(t))return this;var r=this.cy(),a=(new e.Collection(r),this.toArray().sort(t));return new e.Collection(r,a)},sortByZIndex:function(){return this.sort(e.Collection.zIndexSort)}}),e.Collection.zIndexSort=function(e,t){var r=function(e){return"nodes"==e._private.group?e.parents().size():"edges"==e._private.group?Math.max(e.source()[0].parents().size(),e.target()[0].parents().size()):0},a=e._private.style["z-index"].value-t._private.style["z-index"].value,i=0,n=0;return e.cy().hasCompoundNodes()&&(i=r(e),n=r(t)),i-n===0?"nodes"===e._private.group&&"edges"===t._private.group?1:"edges"===e._private.group&&"nodes"===t._private.group?-1:0===a?e._private.index-t._private.index:a:i-n}}(cytoscape),function(e){"use strict";e.fn.eles({updateStyle:function(e){var t=this._private.cy,r=t.style();e=e||void 0===e?!0:!1,r.apply(this);var a=this.updateCompoundBounds();return e?this.add(a).rtrigger("style"):this.add(a).trigger("style"),this},updateMappers:function(e){var t=this._private.cy,r=t.style();e=e||void 0===e?!0:!1,r.updateMappers(this);var a=this.updateCompoundBounds();return e?this.add(a).rtrigger("style"):this.add(a).trigger("style"),this},renderedCss:function(e){var t=this[0];if(t){var r=t.cy().style().getRenderedStyle(t);return void 0===e?r:r[e]}},css:function(t,r){var a=this.cy().style();if(e.is.plainObject(t)){var i=t;a.applyBypass(this,i),this.rtrigger("style")}else if(e.is.string(t)){if(void 0===r){var n=this[0];return n?n._private.style[t].strValue:void 0 -}a.applyBypass(this,t,r),this.rtrigger("style")}else if(void 0===t){var n=this[0];return n?a.getRawStyle(n):void 0}return this},removeCss:function(){for(var e=this.cy().style(),t=this,r=0;r0&&a.push(c)}return new e.Collection(n,a).filter(r)}}function r(t){return function(r){var a=[],i=this._private.cy,n=t||{};e.is.string(r)&&(r=i.$(r));for(var o=r.connectedEdges(),s=this._private.ids,l=0;l0;o||a.push(n)}}return new e.Collection(this._private.cy,a).filter(t)},kruskal:function(t){function r(e){for(var t=0;tl&&(n=l,a=s)}return{edge:a,dist:n}};0!==d.length;){var h=u(d),v=d.filter("#"+h);if(0!==v.length){if(d=d.not(v),v.same(t))break;if(o[h]===Math.Infinite)break;for(var g=v.neighborhood().nodes(),c=0;c0&&r.push(d[0]),r.push(c[0])}return new e.Collection(a,r).filter(t)},closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),e.fn.eles({source:t({attr:"source"}),target:t({attr:"target"})}),e.fn.eles({edgesWith:r(),edgesTo:r({thisIs:"source"})}),e.fn.eles({connectedEdges:function(t){for(var r=[],a=this._private.cy,i=this,n=0;n0&&r.push(o)}return new e.Collection(a,r).filter(t)},parents:function(t){for(var r=[],a=this.parent();a.nonempty();){for(var i=0;ie.math.sqDistanceToQuadraticBezier(r,a,f.startX,f.startY,f.cp2ax,f.cp2ay,f.selfEdgeMidX,f.selfEdgeMidY)||e.math.inBezierVicinity(r,a,f.selfEdgeMidX,f.selfEdgeMidY,f.cp2cx,f.cp2cy,f.endX,f.endY,Math.pow(s[h]._private.style.width.pxValue/2,2))&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToQuadraticBezier(r,a,f.selfEdgeMidX,f.selfEdgeMidY,f.cp2cx,f.cp2cy,f.endX,f.endY))&&(v=!0):"straight"==f.edgeType?e.math.inLineVicinity(r,a,f.startX,f.startY,f.endX,f.endY,2*s[h]._private.style.width.pxValue)&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToFiniteLine(r,a,f.startX,f.startY,f.endX,f.endY)&&(v=!0):"bezier"==f.edgeType&&e.math.inBezierVicinity(r,a,f.startX,f.startY,f.cp2x,f.cp2y,f.endX,f.endY,Math.pow(s[h]._private.style.width.pxValue/2,2))&&Math.pow(s[h]._private.style.width.pxValue/2,2)+u>e.math.sqDistanceToQuadraticBezier(r,a,f.startX,f.startY,f.cp2x,f.cp2y,f.endX,f.endY)&&(v=!0),l.length&&l[l.length-1]==s[h]||(t.arrowShapes[s[h]._private.style["source-arrow-shape"].value].roughCollide(r,a,s[h]._private.rscratch.arrowStartX,s[h]._private.rscratch.arrowStartY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowStartX-s[h].source()[0]._private.position.x,s[h]._private.rscratch.arrowStartY-s[h].source()[0]._private.position.y],0)&&t.arrowShapes[s[h]._private.style["source-arrow-shape"].value].collide(r,a,s[h]._private.rscratch.arrowStartX,s[h]._private.rscratch.arrowStartY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowStartX-s[h].source()[0]._private.position.x,s[h]._private.rscratch.arrowStartY-s[h].source()[0]._private.position.y],0)||t.arrowShapes[s[h]._private.style["target-arrow-shape"].value].roughCollide(r,a,s[h]._private.rscratch.arrowEndX,s[h]._private.rscratch.arrowEndY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowEndX-s[h].target()[0]._private.position.x,s[h]._private.rscratch.arrowEndY-s[h].target()[0]._private.position.y],0)&&t.arrowShapes[s[h]._private.style["target-arrow-shape"].value].collide(r,a,s[h]._private.rscratch.arrowEndX,s[h]._private.rscratch.arrowEndY,this.getArrowWidth(s[h]._private.style.width.pxValue),this.getArrowHeight(s[h]._private.style.width.pxValue),[s[h]._private.rscratch.arrowEndX-s[h].target()[0]._private.position.x,s[h]._private.rscratch.arrowEndY-s[h].target()[0]._private.position.y],0))&&(v=!0),v)if(i){var y=n.cy.getElementById(s[h]._private.data.source),m=n.cy.getElementById(s[h]._private.data.target);0!=s[h]._private.style.opacity.value&&"visible"==s[h]._private.style.visibility.value&&"element"==s[h]._private.style.display.value&&0!=y._private.style.opacity.value&&"visible"==y._private.style.visibility.value&&"element"==y._private.style.display.value&&0!=m._private.style.opacity.value&&"visible"==m._private.style.visibility.value&&"element"==m._private.style.display.value&&l.push(s[h])}else l.push(s[h])}return l.sort(this.zOrderSort),l.length>0?l[l.length-1]:null},t.prototype.getAllInBox=function(r,a,i,n){var o=(this.data,this.getCachedNodes()),s=this.getCachedEdges(),l=[],c=Math.min(r,i),d=Math.max(r,i),u=Math.min(a,n),p=Math.max(a,n);r=c,i=d,a=u,n=p;for(var h,v=0;vd?d+"-"+c:c+"-"+d,void 0==i[a]&&(i[a]=[]),i[a].push(l),o.push(a)}}for(var u,p,h,v,g,f,y,m,b,x,w,_,E,S,P,M=0;M1){var k=b.intersectLine(h.x,h.y,g,f,v.x,v.y,w/2),C=x.intersectLine(v.x,v.y,y,m,h.x,h.y,_/2),E={x:(k[0]+C[0])/2,y:(k[1]+C[1])/2},D=C[1]-k[1],N=C[0]-k[0],T=Math.sqrt(N*N+D*D),I={x:N,y:D},z={x:I.x/T,y:I.y/T};S={x:-z.y,y:z.x},(x.checkPoint(k[0],k[1],_/2,y,m,v.x,v.y)||b.checkPoint(C[0],C[1],w/2,g,f,h.x,h.y))&&(S={},P=!0)}for(var l,B,s=0;sdt,pt=e.math.distance({x:B.cp2x,y:B.cp2y},{x:B.endX,y:B.endY}),ht=ct>pt;if("bezier"===B.edgeType){var vt=!1;if(at||it||ut){vt=!0;var gt={x:B.cp2x-h.x,y:B.cp2y-h.y},ft=Math.sqrt(gt.x*gt.x+gt.y*gt.y),yt={x:gt.x/ft,y:gt.y/ft},mt=Math.max(g,f),bt={x:B.cp2x+2*yt.x*mt,y:B.cp2y+2*yt.y*mt},xt=b.intersectLine(h.x,h.y,g,f,bt.x,bt.y,w/2);ut?(B.cp2x=B.cp2x+yt.x*(ct-dt),B.cp2y=B.cp2y+yt.y*(ct-dt)):(B.cp2x=xt[0]+yt.x*ct,B.cp2y=xt[1]+yt.y*ct)}if(nt||ot||ht){vt=!0;var gt={x:B.cp2x-v.x,y:B.cp2y-v.y},ft=Math.sqrt(gt.x*gt.x+gt.y*gt.y),yt={x:gt.x/ft,y:gt.y/ft},mt=Math.max(g,f),bt={x:B.cp2x+2*yt.x*mt,y:B.cp2y+2*yt.y*mt},wt=x.intersectLine(v.x,v.y,y,m,bt.x,bt.y,_/2);ht?(B.cp2x=B.cp2x+yt.x*(ct-pt),B.cp2y=B.cp2y+yt.y*(ct-pt)):(B.cp2x=wt[0]+yt.x*ct,B.cp2y=wt[1]+yt.y*ct)}vt&&this.findEndpoints(l)}this.projectBezier(l)}}}return i},t.prototype.findEndpoints=function(r){var a,i=r.source()[0],n=r.target()[0],o=(i._private.position,n._private.position,r._private.style["target-arrow-shape"].value),s=r._private.style["source-arrow-shape"].value,l=n._private.style["border-width"].pxValue,c=i._private.style["border-width"].pxValue,d=r._private.rscratch; -if("self"==r._private.rscratch.edgeType){var u=[d.cp2cx,d.cp2cy];a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),u[0],u[1],l/2);var p=e.math.shortenIntersection(a,u,t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,u,t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1];var u=[d.cp2ax,d.cp2ay];a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),u[0],u[1],c/2);var v=e.math.shortenIntersection(a,u,t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,u,t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if("straight"==d.edgeType){a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),i.position().x,i.position().y,l/2),d.noArrowPlacement=0==a.length?!0:!1;var p=e.math.shortenIntersection(a,[i.position().x,i.position().y],t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,[i.position().x,i.position().y],t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1],a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),n.position().x,n.position().y,c/2),d.noArrowPlacement=0==a.length?!0:!1;var v=e.math.shortenIntersection(a,[n.position().x,n.position().y],t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,[n.position().x,n.position().y],t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if("bezier"==d.edgeType){var u=[d.cp2x,d.cp2y];a=t.nodeShapes[this.getNodeShape(n)].intersectLine(n._private.position.x,n._private.position.y,this.getNodeWidth(n),this.getNodeHeight(n),u[0],u[1],l/2);var p=e.math.shortenIntersection(a,u,t.arrowShapes[o].spacing(r)),h=e.math.shortenIntersection(a,u,t.arrowShapes[o].gap(r));d.endX=h[0],d.endY=h[1],d.arrowEndX=p[0],d.arrowEndY=p[1],a=t.nodeShapes[this.getNodeShape(i)].intersectLine(i._private.position.x,i._private.position.y,this.getNodeWidth(i),this.getNodeHeight(i),u[0],u[1],c/2);var v=e.math.shortenIntersection(a,u,t.arrowShapes[s].spacing(r)),g=e.math.shortenIntersection(a,u,t.arrowShapes[s].gap(r));d.startX=g[0],d.startY=g[1],d.arrowStartX=v[0],d.arrowStartY=v[1]}else if(d.isArcEdge)return},t.prototype.findEdges=function(e){for(var t=this.getCachedEdges(),r={},a=[],i=0;ip*v+h*g)t._private.rscratch.straightEdgeTooShort=!0;else{var u=t._private.rscratch;this.drawStyledEdge(t,e,[u.startX,u.startY,u.endX,u.endY],d,c),t._private.rscratch.straightEdgeTooShort=!1}}else{var u=t._private.rscratch;this.drawStyledEdge(t,e,[u.startX,u.startY,u.cp2x,u.cp2y,u.endX,u.endY],d,c)}t._private.rscratch.noArrowPlacement!==!0&&void 0!==t._private.rscratch.startX&&this.drawArrowheads(e,t,r)}}}}};var r=function(e,t){var r=Math.sqrt(Math.pow(e[4]-e[0],2)+Math.pow(e[5]-e[1],2));r+=Math.sqrt(Math.pow((e[4]+e[0])/2-e[2],2)+Math.pow((e[5]+e[1])/2-e[3],2));var a,i=Math.ceil(r/t);if(!(i>0))return null;a=new Array(2*i);for(var n=0;i>n;n++){var o=n/i;a[2*n]=e[0]*(1-o)*(1-o)+2*e[2]*(1-o)*o+e[4]*o*o,a[2*n+1]=e[1]*(1-o)*(1-o)+2*e[3]*(1-o)*o+e[5]*o*o}return a},a=function(e,t){var r,a=Math.sqrt(Math.pow(e[2]-e[0],2)+Math.pow(e[3]-e[1],2)),i=Math.ceil(a/t);if(!(i>0))return null;r=new Array(2*i);for(var n=[e[2]-e[0],e[3]-e[1]],o=0;i>o;o++){var s=o/i;r[2*o]=n[0]*s+e[0],r[2*o+1]=n[1]*s+e[1]}return r};t.prototype.drawStyledEdge=function(e,t,i,n,o){var s=this.data.cy,l=s.zoom();if("solid"==n)t.beginPath(),t.moveTo(i[0],i[1]),6==i.length?t.quadraticCurveTo(i[2],i[3],i[4],i[5]):t.lineTo(i[2],i[3]),t.stroke();else if("dotted"==n){var c;if(c=6==i.length?r(i,16,!0):a(i,16,!0),!c)return;var d=Math.max(1.6*o,3.4)*l,u=2*d,p=2*d;u=Math.max(u,1),p=Math.max(p,1);var h=this.createBuffer(u,p),v=h[1];v.setTransform(1,0,0,1,0,0),v.clearRect(0,0,u,p),v.fillStyle=t.strokeStyle,v.beginPath(),v.arc(u/2,p/2,.5*d,0,2*Math.PI,!1),v.fill(),t.beginPath();for(var g=0;gn?s+=Math.PI/2:s=-(Math.PI/2+s),e.translate(a,i),e.moveTo(0,0),e.rotate(-s);var l=this.getArrowWidth(e.lineWidth);e.scale(l,l),e.beginPath(),t.arrowShapes[r].draw(e),e.closePath(),e.fill(),e.scale(1/l,1/l),e.rotate(s),e.translate(-a,-i)}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas"),r={},a=9e3;t.prototype.getCachedImage=function(e,t){if(r[e]&&r[e].image)return r[e].keepTime=a,r[e].image;var i=r[e];return void 0==i&&(r[e]=new Object,r[e].image=new Image,r[e].image.onload=t,r[e].image.src=e,r[e].keepTime=a,i=r[e]),i.image},t.prototype.swapCachedImage=function(e){if(r[e]){if(r[e].image&&r[e].image.complete){var t=r[e].image,a=document.createElement("canvas");return a.width=t.width,a.height=t.height,a.getContext("2d").drawImage(t,0,0),r[e].image=a,r[e].swappedWithCanvas=!0,a}return null}return null},t.prototype.updateImageCaches=function(){for(var e in r)r[e].keepTime<=0?(void 0!=r[e].image&&(r[e].image.src=void 0,r[e].image=void 0),r[e]=void 0):r[e]-=1},t.prototype.drawImage=function(e,t,r,a,i,n,o){o.widthScale=.5,o.heightScale=.5,o.rotate=n;canvas.drawImage(o,t,r)},t.prototype.drawInscribedImage=function(e,r,a){var i=this,n=(this.data.cy._private.zoom,a._private.position.x),o=a._private.position.y,s=this.getNodeWidth(a),l=this.getNodeHeight(a);e.save(),t.nodeShapes[i.getNodeShape(a)].drawPath(e,n,o,s,l),e.clip();var c=[r.width,r.height];e.drawImage(r,n-c[0]/2,o-c[1]/2,c[0],c[1]),e.restore(),a._private.style["border-width"].value>0&&e.stroke()}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawEdgeText=function(e,t){if(t.visible()&&(!this.hideEdgesOnViewport||!(this.dragData.didDrag||this.pinching||this.hoverData.dragging||this.data.wheel||this.swipePanning))){var r=t._private.style["font-size"].pxValue*t.cy().zoom(),a=t._private.style["min-zoomed-font-size"].pxValue;if(!(a>r)){e.textAlign="center",e.textBaseline="middle",this.recalculateEdgeLabelProjection(t);var i=t._private.rscratch;this.drawText(e,t,i.labelX,i.labelY)}}},t.prototype.drawNodeText=function(e,t){if(t.visible()){var r=t._private.style["font-size"].pxValue*t.cy().zoom(),a=t._private.style["min-zoomed-font-size"].pxValue;if(!(a>r)){this.recalculateNodeLabelProjection(t);var i=t._private.style["text-halign"].strValue,n=t._private.style["text-valign"].strValue,o=t._private.rscratch;switch(i){case"left":e.textAlign="right";break;case"right":e.textAlign="left";break;case"center":default:e.textAlign="center"}switch(n){case"top":e.textBaseline="bottom";break;case"bottom":e.textBaseline="top";break;case"center":default:e.textBaseline="middle"}this.drawText(e,t,o.labelX,o.labelY)}}},t.prototype.setupTextStyle=function(e,t){var r=t.effectiveOpacity(),a=t._private.style,i=a["font-style"].strValue,n=a["font-size"].pxValue+"px",o=a["font-family"].strValue,s=(a["font-variant"].strValue,a["font-weight"].strValue);e.font=i+" "+s+" "+n+" "+o;var l=String(a.content.value),c=a["text-transform"].value;return"none"==c||("uppercase"==c?l=l.toUpperCase():"lowercase"==c&&(l=l.toLowerCase())),e.lineJoin="round",e.fillStyle="rgba("+a.color.value[0]+","+a.color.value[1]+","+a.color.value[2]+","+a["text-opacity"].value*a.opacity.value*r+")",e.strokeStyle="rgba("+a["text-outline-color"].value[0]+","+a["text-outline-color"].value[1]+","+a["text-outline-color"].value[2]+","+a["text-opacity"].value*a.opacity.value*r+")",l},t.prototype.drawText=function(e,t,r,a){var i=t._private.style,n=t.effectiveOpacity();if(0!==n){var o=this.setupTextStyle(e,t);if(void 0!=o&&!isNaN(r)&&!isNaN(a)){var s=2*i["text-outline-width"].value;s>0&&(e.lineWidth=s,e.strokeText(o,r,a)),e.fillText(""+o,r,a)}}}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawNode=function(e,r,a){var i,n;if(r.visible()){var o=r.effectiveOpacity();if(0!==o)if(i=this.getNodeWidth(r),n=this.getNodeHeight(r),e.lineWidth=r._private.style["border-width"].pxValue,void 0!==a&&a){var s=r._private.style["overlay-padding"].pxValue,l=r._private.style["overlay-opacity"].value,c=r._private.style["overlay-color"].value;l>0&&(e.fillStyle="rgba( "+c[0]+", "+c[1]+", "+c[2]+", "+l+" )",t.nodeShapes.roundrectangle.draw(e,r._private.position.x,r._private.position.y,i+2*s,n+2*s))}else{e.fillStyle="rgba("+r._private.style["background-color"].value[0]+","+r._private.style["background-color"].value[1]+","+r._private.style["background-color"].value[2]+","+r._private.style["background-opacity"].value*r._private.style.opacity.value*o+")",e.strokeStyle="rgba("+r._private.style["border-color"].value[0]+","+r._private.style["border-color"].value[1]+","+r._private.style["border-color"].value[2]+","+r._private.style["border-opacity"].value*r._private.style.opacity.value*o+")",e.lineJoin="miter";var d=r._private.style["background-image"].value[2]||r._private.style["background-image"].value[1];if(void 0!=d){var u=this,p=this.getCachedImage(d,function(){u.data.canvasNeedsRedraw[t.NODE]=!0,u.data.canvasNeedsRedraw[t.DRAG]=!0,u.swapCachedImage(d),u.redraw()});0==p.complete?(t.nodeShapes[u.getNodeShape(r)].drawPath(e,r._private.position.x,r._private.position.y,i,n),e.stroke(),e.fillStyle="#555555",e.fill()):this.drawInscribedImage(e,p,r)}else t.nodeShapes[this.getNodeShape(r)].draw(e,r._private.position.x,r._private.position.y,i,n);this.drawPie(e,r),r._private.style["border-width"].pxValue>0&&(t.nodeShapes[this.getNodeShape(r)].drawPath(e,r._private.position.x,r._private.position.y,i,n),e.stroke())}}},t.prototype.hasPie=function(t){t=t[0];for(var r=1;r<=e.style.pieBackgroundN;r++){var a=t._private.style["pie-"+r+"-background-size"].value;if(a>0)return!0}return!1},t.prototype.drawPie=function(r,a){if(a=a[0],this.hasPie(a)){var i=this.getNodeWidth(a),n=this.getNodeHeight(a),o=a._private.position.x,s=a._private.position.y,l=Math.min(i,n)/2,c=0;r.save(),t.nodeShapes[this.getNodeShape(a)].drawPath(r,o,s,i,n),r.clip();for(var d=1;d<=e.style.pieBackgroundN;d++){{var u=a._private.style["pie-"+d+"-background-size"].value,p=a._private.style["pie-"+d+"-background-color"],h=u/100,v=1.5*Math.PI+2*Math.PI*c,g=2*Math.PI*h,f=v+g;o+l*Math.cos(v),s+l*Math.sin(v)}0===u||c>=1||c+h>1||(r.beginPath(),r.moveTo(o,s),r.arc(o,s,l,v,f),r.closePath(),r.fillStyle="rgb("+p.value[0]+","+p.value[1]+","+p.value[2]+")",r.fill(),c+=h)}r.restore()}}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.getPixelRatio=function(){var e=this.data.canvases[0],t=e.getContext("2d"),r=t.backingStorePixelRatio||t.webkitBackingStorePixelRatio||t.mozBackingStorePixelRatio||t.msBackingStorePixelRatio||t.oBackingStorePixelRatio||t.backingStorePixelRatio||1,a="undefined"!=typeof InstallTrigger;return a?1:(window.devicePixelRatio||1)/r},t.prototype.matchCanvasSize=function(e){var r,a=this.data,i=e.clientWidth,n=e.clientHeight,o=i,s=n,l=this.getPixelRatio();o*=l,s*=l;var c=a.canvasContainer;c.style.width=i+"px",c.style.height=n+"px";for(var d=0;d0&&(_.strokeStyle="rgba("+E["selection-box-border-color"].value[0]+","+E["selection-box-border-color"].value[1]+","+E["selection-box-border-color"].value[2]+","+E["selection-box-opacity"].value+")",_.strokeRect(d.select[0],d.select[1],d.select[2]-d.select[0],d.select[3]-d.select[1]))}if(d.bgActivePosistion){var p=d.cy.zoom(),P=d.bgActivePosistion;_.fillStyle="rgba("+E["active-bg-color"].value[0]+","+E["active-bg-color"].value[1]+","+E["active-bg-color"].value[2]+","+E["active-bg-opacity"].value+")",_.beginPath(),_.arc(P.x,P.y,E["active-bg-size"].pxValue/p,0,2*Math.PI),_.fill()}i||(d.canvasNeedsRedraw[t.SELECT_BOX]=!1)}var M=+new Date;void 0===s.averageRedrawTime&&(s.averageRedrawTime=M-y),s.averageRedrawTime=s.averageRedrawTime/2+(M-y)/2}e=e||{};var a=e.forcedContext,i=e.drawAllLayers,n=e.forcedZoom,o=e.forcedPan,s=this,l=this.getPixelRatio(),c=s.data.cy,d=s.data;clearTimeout(this.redrawTimeout),void 0===this.averageRedrawTime&&(this.averageRedrawTime=0);var u=1e3/60,p=1e3,h=this.averageRedrawTime;h=Math.max(u,h),h=Math.min(h,p),void 0===this.lastDrawTime&&(this.lastDrawTime=0);var v=+new Date,g=v-this.lastDrawTime,f=g>=h;if(!a){if(!f)return clearTimeout(this.redrawTimeout),void(this.redrawTimeout=setTimeout(function(){s.redraw()},h));this.lastDrawTime=v}var y=v;a?r():setTimeout(r,0),a||s.initrender||(s.initrender=!0,c.trigger("initrender"))}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.drawPolygonPath=function(e,t,r,a,i,n){e.translate(t,r),e.scale(a/2,i/2),e.beginPath(),e.moveTo(n[0],n[1]);for(var o=1;o0&&n>0&&(s.clearRect(0,0,i,n),e.bg&&(s.fillStyle=e.bg,s.rect(0,0,i,n),s.fill()),s.globalCompositeOperation="source-over",this.redraw(e.full?{forcedContext:s,drawAllLayers:!0,forcedZoom:1,forcedPan:{x:-a.x1,y:-a.y1}}:{forcedContext:s,drawAllLayers:!0})),o.toDataURL("image/png")}}(cytoscape),function(e){"use strict";var t=e("renderer","canvas");t.prototype.registerBinding=function(e,t,r,a){this.bindings.push({target:e,event:t,handler:r,useCapture:a}),e.addEventListener(t,r,a)},t.prototype.load=function(){var r=this,a=function(e,t,r){if(!t)for(var a=e.parents(),i=0;io[0]&&a.pageXo[1]&&a.pageY=t.panOrBoxSelectDelay)&&Math.abs(c[3]-c[1])+Math.abs(c[2]-c[0])<4&&s.panningEnabled()&&s.userPanningEnabled())r.hoverData.dragging=!0,c[4]=0;else{if(s.boxSelectionEnabled()&&Math.pow(c[2]-c[0],2)+Math.pow(c[3]-c[1],2)>7&&c[4]&&(clearTimeout(r.bgActiveTimeout),r.data.bgActivePosistion=void 0),p&&p.isEdge()&&p.active()&&p.unactivate(),d!=u&&(u&&u.trigger(new e.Event(a,{type:"mouseout",cyPosition:{x:l[0],y:l[1]}})),d&&d.trigger(new e.Event(a,{type:"mouseover",cyPosition:{x:l[0],y:l[1]}})),r.hoverData.last=d),p&&p.isNode()&&r.nodeIsDraggable(p)){r.dragData.didDrag=!0,r.hoverData.draggingEles=!0;var y=[];new e.Collection(s,v).positions(function(e,t){if(t.isNode()&&r.nodeIsDraggable(t)){var a=t.position();return{x:a.x+h[0],y:a.y+h[1]}}}),new e.Collection(s,y).trigger("drag"),c[2]==c[0]&&c[3]==c[1]&&(r.data.canvasNeedsRedraw[t.NODE]=!0),r.data.canvasNeedsRedraw[t.DRAG]=!0}s.boxSelectionEnabled()&&(r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0),i=!0}return c[2]=l[0],c[3]=l[1],r.redraw(),i?(a.stopPropagation&&a.stopPropagation(),a.preventDefault&&a.preventDefault(),!1):void 0},!1),r.registerBinding(window,"mouseup",function(a){var i=r.hoverData.capture;if(i){r.hoverData.capture=!1;var o=r.data.cy,s=r.projectIntoViewport(a.pageX,a.pageY),l=r.data.select,c=r.findNearestElement(s[0],s[1],!0),d=(r.getCachedNodes(),r.getCachedEdges(),r.dragData.possibleDragElements),u=r.hoverData.down,p=a.shiftKey;if(r.data.bgActivePosistion=void 0,clearTimeout(r.bgActiveTimeout),r.hoverData.cxtStarted=!1,r.hoverData.draggingEles=!1,u&&u.unactivate(),3===r.hoverData.which){var h=new e.Event(a,{type:"cxttapend",cyPosition:{x:s[0],y:s[1]}});if(u?u.trigger(h):o.trigger(h),!r.hoverData.cxtDragged){var v=new e.Event(a,{type:"cxttap",cyPosition:{x:s[0],y:s[1]}});u?u.trigger(v):o.trigger(v)}r.hoverData.cxtDragged=!1,r.hoverData.which=null}else{if(null!=u||r.dragData.didDrag||Math.pow(l[2]-l[0],2)+Math.pow(l[3]-l[1],2)>7&&l[4]||r.hoverData.dragging||(o.$(":selected").unselect(),d.length>0&&(r.data.canvasNeedsRedraw[t.NODE]=!0),r.dragData.possibleDragElements=d=[]),null!=c?c.trigger(new e.Event(a,{type:"mouseup",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tapend",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vmouseup",cyPosition:{x:s[0],y:s[1]}})):null==c&&o.trigger(new e.Event(a,{type:"mouseup",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tapend",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vmouseup",cyPosition:{x:s[0],y:s[1]}})),Math.pow(l[2]-l[0],2)+Math.pow(l[3]-l[1],2)==0&&(null!=c?c.trigger(new e.Event(a,{type:"click",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tap",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vclick",cyPosition:{x:s[0],y:s[1]}})):null==c&&o.trigger(new e.Event(a,{type:"click",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"tap",cyPosition:{x:s[0],y:s[1]}})).trigger(new e.Event(a,{type:"vclick",cyPosition:{x:s[0],y:s[1]}}))),c!=u||r.dragData.didDrag){if(c==u&&null!=c&&c._private.grabbed){for(var g=o.$(":grabbed"),f=0;f7&&l[4]){for(var x=[],w=r.getAllInBox(l[0],l[1],l[2],l[3]),f=(new e.Event(a,{type:"select"}),0);f0&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}if(r.hoverData.dragging=!1,!l[4]){for(var f=0;f=0&&m>=l&&d>=0&&m>=d&&c>=0&&b>=c&&u>=0&&b>=u; -var C=s.pan(),D=s.zoom();if(p=x(l,c,d,u),h=[(l+d)/2,(c+u)/2],v=[(h[0]-C.x)/D,(h[1]-C.y)/D],100>p){var N=r.findNearestElement(E[0],E[1],!0),T=r.findNearestElement(E[2],E[3],!0);return N&&N.isNode()?(N.activate().trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=N):T&&T.isNode()?(T.activate().trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=T):(s.trigger(new e.Event(o,{type:"cxttapstart",cyPosition:{x:E[0],y:E[1]}})),r.touchData.start=null),r.touchData.start&&(r.touchData.start._private.grabbed=!1),r.touchData.cxt=!0,r.touchData.cxtDragged=!1,r.data.bgActivePosistion=void 0,void r.redraw()}}if(o.touches[2]);else if(o.touches[1]);else if(o.touches[0]){var I=r.findNearestElement(E[0],E[1],!0);if(null!=I){if(I.activate(),r.touchData.start=I,"nodes"==I._private.group&&r.nodeIsDraggable(I)){var z=r.dragData.touchDragEles=[];if(i(I,z),I.trigger("grab"),I.selected()){z=r.dragData.touchDragEles=[];for(var B=s.$("node:selected"),X=0;X250&&(r.touchData.start?r.touchData.start.trigger(new e.Event(o,{type:"taphold",cyPosition:{x:E[0],y:E[1]}})):(r.data.cy.trigger(new e.Event(o,{type:"taphold",cyPosition:{x:E[0],y:E[1]}})),s.$(":selected").unselect()))},1e3)}}r.redraw()},!1),r.registerBinding(window,"touchmove",function(a){var i=r.data.select,n=r.touchData.capture;n&&a.preventDefault();var o=r.data.cy,s=(r.getCachedNodes(),r.getCachedEdges(),r.touchData.now),h=r.touchData.earlier;if(a.touches[0]){var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}if(a.touches[1]){var m=r.projectIntoViewport(a.touches[1].pageX,a.touches[1].pageY);s[2]=m[0],s[3]=m[1]}if(a.touches[2]){var m=r.projectIntoViewport(a.touches[2].pageX,a.touches[2].pageY);s[4]=m[0],s[5]=m[1]}for(var b=[],w=0;w=1.5||M>=150){r.touchData.cxt=!1,r.touchData.start&&(r.touchData.start.unactivate(),r.touchData.start=null),r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;var C=new e.Event(a,{type:"cxttapend",cyPosition:{x:s[0],y:s[1]}});r.touchData.start?r.touchData.start.trigger(C):o.trigger(C)}}if(n&&r.touchData.cxt){var C=new e.Event(a,{type:"cxtdrag",cyPosition:{x:s[0],y:s[1]}});r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,r.touchData.start?r.touchData.start.trigger(C):o.trigger(C),r.touchData.start&&(r.touchData.start._private.grabbed=!1),r.touchData.cxtDragged=!0}else if(n&&a.touches[2]&&o.boxSelectionEnabled())r.data.bgActivePosistion=void 0,clearTimeout(this.threeFingerSelectTimeout),this.lastThreeTouch=+new Date,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,i&&0!==i.length&&void 0!==i[0]?(i[2]=(s[0]+s[2]+s[4])/3,i[3]=(s[1]+s[3]+s[5])/3):(i[0]=(s[0]+s[2]+s[4])/3,i[1]=(s[1]+s[3]+s[5])/3,i[2]=(s[0]+s[2]+s[4])/3+1,i[3]=(s[1]+s[3]+s[5])/3+1),i[4]=1;else if(n&&a.touches[1]&&o.zoomingEnabled()&&o.panningEnabled()&&o.userZoomingEnabled()&&o.userPanningEnabled()){r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;var _=a.touches[0].pageX-g,E=a.touches[0].pageY-f,S=a.touches[1].pageX-g,P=a.touches[1].pageY-f,M=x(_,E,S,P),k=M/p;if(1!=k&&y){var D=_-l,N=E-c,T=S-d,I=P-u,z=(D+T)/2,B=(N+I)/2,X=o.zoom(),R=X*k,Y=o.pan(),L=v[0]*X+Y.x,V=v[1]*X+Y.y,A={x:-R/X*(L-Y.x-z)+L,y:-R/X*(V-Y.y-B)+V};o._private.zoom=R,o._private.pan=A,o.trigger("pan zoom").notify("viewport"),p=M,l=_,c=E,d=S,u=P,r.pinching=!0}if(a.touches[0]){var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}if(a.touches[1]){var m=r.projectIntoViewport(a.touches[1].pageX,a.touches[1].pageY);s[2]=m[0],s[3]=m[1]}if(a.touches[2]){var m=r.projectIntoViewport(a.touches[2].pageX,a.touches[2].pageY);s[4]=m[0],s[5]=m[1]}}else if(a.touches[0]){{var q=r.touchData.start;r.touchData.last}if(null!=q&&"nodes"==q._private.group&&r.nodeIsDraggable(q)){var O=r.dragData.touchDragEles,F=new e.Collection(o,O).positions(function(e,t){if(r.nodeIsDraggable(t)){r.dragData.didDrag=!0;var a=t.position();return{x:a.x+b[0],y:a.y+b[1]}}});F.trigger("drag"),r.data.canvasNeedsRedraw[t.DRAG]=!0,r.touchData.startPosition[0]==h[0]&&r.touchData.startPosition[1]==h[1]&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}if(null!=q&&(q.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),q.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),q.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}}))),null==q){var $=r.findNearestElement(s[0],s[1],!0);null!=$&&($.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),$.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),$.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}}))),null==$&&(o.trigger(new e.Event(a,{type:"touchmove",cyPosition:{x:s[0],y:s[1]}})),o.trigger(new e.Event(a,{type:"tapdrag",cyPosition:{x:s[0],y:s[1]}})),o.trigger(new e.Event(a,{type:"vmousemove",cyPosition:{x:s[0],y:s[1]}})))}r.touchData.last=$;for(var j=0;j4&&(r.touchData.singleTouchMoved=!0);if(n&&(null==q||q.isEdge())&&o.panningEnabled()&&o.userPanningEnabled()){q&&(q.unactivate(),r.data.bgActivePosistion||(r.data.bgActivePosistion={x:s[0],y:s[1]}),r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0),o.panBy({x:b[0]*o.zoom(),y:b[1]*o.zoom()}),r.swipePanning=!0;var m=r.projectIntoViewport(a.touches[0].pageX,a.touches[0].pageY);s[0]=m[0],s[1]=m[1]}}for(var w=0;w0&&(r.data.canvasNeedsRedraw[t.NODE]=!0)}a.touches[1]||(r.pinching=!1);var y=!1;if(null!=d&&(d._private.active=!1,y=!0,d.trigger("unactivate")),a.touches[2])r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0;else if(a.touches[1]);else if(a.touches[0]);else if(!a.touches[0]){if(r.data.bgActivePosistion=void 0,r.data.canvasNeedsRedraw[t.SELECT_BOX]=!0,null!=d){1==d._private.grabbed&&(d._private.grabbed=!1,d.trigger("free"),d._private.rscratch.inDragLayer=!1);for(var m=d._private.edges,b=0;b=t||r.drawPolygon(e._private.position.x,e._private.position.y,t,a,nodeSapes.roundrectangle2.points)},intersectLine:function(t,r,i,n,o){return e.math.findPolygonIntersection(t,r,i,n,o,a.square.points)},intersectBox:function(){a.square.points}},a.pentagon={points:e.math.generateUnitNgonPointsFitToSquare(5,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.pentagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.pentagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.pentagon.points,e,t,i/2,n/2,l)},intersectBox:function(t,r,i,n,o,s,l,c,d){var u=a.pentagon.points;return e.math.boxIntersectPolygon(t,r,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.pentagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.pentagon.points,s,l,n,o,[0,-1],i)}},a.hexagon={points:e.math.generateUnitNgonPointsFitToSquare(6,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.hexagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.hexagon.points)},intersectLine:function(t,r,i,n,o,s,l){return e.math.polygonIntersectLine(o,s,a.hexagon.points,t,r,i/2,n/2,l)},intersectBox:function(t,r,i,n,o,s,l,c,d){var u=a.hexagon.points;return e.math.boxIntersectPolygon(t,r,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.hexagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.hexagon.points,s,l,n,o,[0,-1],i)}},a.heptagon={points:e.math.generateUnitNgonPointsFitToSquare(7,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.heptagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.heptagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.heptagon.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.heptagon.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.heptagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.heptagon.points,s,l,n,o,[0,-1],i)}},a.octagon={points:e.math.generateUnitNgonPointsFitToSquare(8,0),draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.octagon.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.octagon.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.octagon.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.octagon.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.octagon.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.octagon.points,s,l,n,o,[0,-1],i)}};var i=new Array(20),n=e.math.generateUnitNgonPoints(5,0),o=e.math.generateUnitNgonPoints(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;ll;l++)i[4*l]=n[2*l],i[4*l+1]=n[2*l+1],i[4*l+2]=o[2*l],i[4*l+3]=o[2*l+1];i=e.math.fitPolygonToSquare(i),a.star5=a.star={points:i,draw:function(e,t,i,n,o){r.drawPolygon(e,t,i,n,o,a.star5.points)},drawPath:function(e,t,i,n,o){r.drawPolygonPath(e,t,i,n,o,a.star5.points)},intersectLine:function(e,t,i,n,o,s,l){return r.polygonIntersectLine(o,s,a.star5.points,e,t,i/2,n/2,l)},intersectBox:function(e,t,i,n,o,s,l,c,d){var u=a.star5.points;return r.boxIntersectPolygon(e,t,i,n,u,o,s,l,c,[0,-1],d)},checkPointRough:function(t,r,i,n,o,s,l){return e.math.checkInBoundingBox(t,r,a.star5.points,i,n,o,s,l)},checkPoint:function(t,r,i,n,o,s,l){return e.math.pointInsidePolygon(t,r,a.star5.points,s,l,n,o,[0,-1],i)}}}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend(!0,{},r,t)}var r={ready:function(){},stop:function(){}};t.prototype.run=function(){var e=this.options,t=e.cy;t.nodes().positions(function(){return{x:0,y:0}}),t.one("layoutready",e.ready),t.trigger("layoutready"),t.one("layoutstop",e.stop),t.trigger("layoutstop")},t.prototype.stop=function(){var e=this.options;cy.one("layoutstop",e.stop),cy.trigger("layoutstop")},e("layout","null",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend(!0,{},r,t)}var r={ready:void 0,stop:void 0,fit:!0,padding:30};t.prototype.run=function(){var e=this.options,t=e.cy,r=t.nodes(),a=(t.edges(),t.container()),i=a.clientWidth,n=a.clientHeight;r.positions(function(e,t){return t.locked()?!1:{x:Math.round(Math.random()*i),y:Math.round(Math.random()*n)}}),t.one("layoutready",e.ready),t.trigger("layoutready"),e.fit&&t.fit(e.padding),t.one("layoutstop",e.stop),t.trigger("layoutstop")},t.prototype.stop=function(){},e("layout","random",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},r,t)}var r={fit:!0,padding:30,rows:void 0,columns:void 0,position:function(){},ready:void 0,stop:void 0};t.prototype.run=function(){var e=this.options,t=e,r=e.cy,a=r.nodes(),i=(r.edges(),r.container()),n=i.clientWidth,o=i.clientHeight;if(0==o||0==n)a.positions(function(){return{x:0,y:0}});else{var s=a.size(),l=Math.sqrt(s*o/n),c=Math.round(l),d=Math.round(n/o*l),u=function(e){if(void 0==e)return Math.min(c,d);var t=Math.min(c,d);t==c?c=e:d=e},p=function(e){if(void 0==e)return Math.max(c,d);var t=Math.max(c,d);t==c?c=e:d=e};if(null!=t.rows&&null!=t.columns)c=t.rows,d=t.columns;else if(null!=t.rows&&null==t.columns)c=t.rows,d=Math.ceil(s/c);else if(null==t.rows&&null!=t.columns)d=t.columns,c=Math.ceil(s/d);else if(d*c>s){var h=u(),v=p();(h-1)*v>=s?u(h-1):(v-1)*h>=s&&p(v-1)}else for(;s>d*c;){var h=u(),v=p();(v+1)*h>=s?p(v+1):u(h+1)}for(var g=n/d,f=o/c,y=0;y=d&&(P=0,S++)},k={},y=0;y0&&i.stableEnergy(t))return void h.stop();clearTimeout(v),v=setTimeout(w,g);var r=[];h.eachNode(function(e,t){var a=(e.name,e.data),i=a.element;null!=i&&(i.locked()||i.grabbed()||(i.silentPosition({x:p.x1+t.x,y:p.y1+t.y}),r.push(i)))});var a=+new Date-y>=16;i.liveUpdate&&r.length>0&&a&&(new e.Collection(n,r).rtrigger("position"),y=+new Date),f||(f=!0,n.one("layoutready",i.ready),n.trigger("layoutready"))}};h.renderer=m,h.screenSize(c,d),h.screenPadding(i.padding[0],i.padding[1],i.padding[2],i.padding[3]),h.screenStep(i.stepSize);var b=function(e){grabbed=this;var t=h.fromScreen(this.position()),r=arbor.Point(t.x,t.y);switch(this.scratch().arbor.p=r,e.type){case"grab":this.scratch().arbor.fixed=!0;break;case"dragstop":this.scratch().arbor.fixed=!1,this.scratch().arbor.tempMass=1e3}};o.bind("grab drag dragstop",b),o.each(function(e,a){if(!this.isFullAutoParent()){var n=this._private.data.id,o=t(this,i.nodeMass),s=this._private.locked;if(!a.isFullAutoParent()){var l=r({x:a.position().x,y:a.position().y});a.locked()||(this.scratch().arbor=h.addNode(n,{element:this,mass:o,fixed:s,x:s?l.x:void 0,y:s?l.y:void 0}))}}}),s.each(function(){var e=(this.id(),this.source().id()),r=this.target().id(),a=t(this,i.edgeLength);this.scratch().arbor=h.addEdge(e,r,{length:a})});var x=o.filter(":grabbable");i.ungrabifyWhileSimulating&&x.ungrabify();var w=function(){function e(){i.liveUpdate||(i.fit&&n.reset(),n.nodes().rtrigger("position")),o.unbind("grab drag dragstop",b),i.ungrabifyWhileSimulating&&x.grabify(),n.one("layoutstop",i.stop),n.trigger("layoutstop")}window.isIE?a(function(){e()}):e()};h.start(),setTimeout(function(){h.stop()},i.maxSimulationTime)},t.prototype.stop=function(){null!=this.system&&system.stop()},e("layout","arbor",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},r,t)}var r={fit:!0,ready:void 0,stop:void 0,rStepSize:10,padding:30,startAngle:1.5*Math.PI,counterclockwise:!1};t.prototype.run=function(){function e(){var e=0,t=d,r={x:l.x+v*Math.cos(e),y:l.y+v*Math.sin(e)},a={x:l.x+v*Math.cos(t),y:l.y+v*Math.sin(t)},i=Math.sqrt((a.x-r.x)*(a.x-r.x)+(a.y-r.y)*(a.y-r.y));return i}for(var t=this.options,r=t,a=t.cy,i=a.nodes().filter(function(){return!this.isFullAutoParent()}),n=(a.edges(),a.container()),o=n.clientWidth,s=n.clientHeight,l={x:o/2,y:s/2},c=r.startAngle,d=2*Math.PI/i.length,u=0,p=0;pm;){for(var b=f.shift(),x=b.neighborhood().nodes(),w=!1,d=0;dd;d++)for(var _=h[d],D=_.length,N=0;D>N;N++){var p=_[N],T=p._private.scratch.BreadthFirstLayout,I=M(p);I&&(T.intEle=I,C.push(p))}for(var d=0;dh.length-1;)h.push([]);h[B].push(p),T.depth=B,T.index=h[B].length-1}S()}for(var X=0,d=0;dl||0===t)&&(a+=s/c,i++)}return i=Math.max(1,i),a/=i,0===i&&(a=void 0),L[e.id()]=a,a},A=0;3>A;A++){for(var d=0;d0&&h[0].length<=3?c/2:0),u=2*Math.PI/h[r].length*i;return 0===r&&1===h[0].length&&(d=1),{x:q.x+d*Math.cos(u),y:q.y+d*Math.sin(u)}}return{x:(i+1)*n,y:(r+1)*o}}),r.fit&&i.fit(a.padding),i.one("layoutready",r.ready),i.trigger("layoutready"),i.one("layoutstop",r.stop),i.trigger("layoutstop")},t.prototype.stop=function(){},e("layout","breadthfirst",t)}(cytoscape),function(e){"use strict";function t(t){this.options=e.util.extend({},a,t)}var r,a={ready:function(){},stop:function(){},refresh:0,fit:!0,padding:30,randomize:!0,debug:!1,nodeRepulsion:1e4,nodeOverlap:10,idealEdgeLength:10,edgeElasticity:100,nestingFactor:5,gravity:250,numIter:100,initialTemp:200,coolingFactor:.95,minTemp:1};t.prototype.run=function(){var e=this.options,t=e.cy;r=1==e.debug?!0:!1;var a=new Date,n=i(t,e);r&&s(n),1==e.randomize&&(l(n,t),0=l;){var h=s[l++],v=r.idToIndex[h],g=r.layoutNodes[v],f=g.children;if(f.length>0){r.graphSet.push(f);for(var i=0;ia.count?0:a.graph},o=function(e,t,r,a){var i=a.graphSet[r];if(-1<$.inArray(e,i)&&-1<$.inArray(t,i))return{count:2,graph:r};for(var n=0,s=0;ss;s++)for(var l=e.layoutNodes[e.idToIndex[n[s]]],c=s+1;o>c;c++){var d=e.layoutNodes[e.idToIndex[n[c]]];p(l,d,e,t,r)}}},p=function(e,t,r,a,i){var n="Node repulsion. Node1: "+e.id+" Node2: "+t.id,o=t.positionX-e.positionX,s=t.positionY-e.positionY;if(n+="\ndirectionX: "+o+", directionY: "+s,0==o&&0==s)return void(n+="\nNodes have the same position.");var l=v(e,t,o,s);if(l>0){n+="\nNodes DO overlap.",n+="\nOverlap: "+l;var c=i.nodeOverlap*l,d=Math.sqrt(o*o+s*s);n+="\nDistance: "+d;var u=c*o/d,p=c*s/d}else{n+="\nNodes do NOT overlap.";var g=h(e,o,s),f=h(t,-1*o,-1*s),y=f.x-g.x,m=f.y-g.y,b=y*y+m*m,d=Math.sqrt(b);n+="\nDistance: "+d;var c=i.nodeRepulsion/b,u=c*y/d,p=c*m/d}e.offsetX-=u,e.offsetY-=p,t.offsetX+=u,t.offsetY+=p,n+="\nForceX: "+u+" ForceY: "+p,w(n)},h=function(e,t,r){var a=e.positionX,i=e.positionY,n=e.height,o=e.width,s=r/t,l=n/o,c="Computing clipping point of node "+e.id+" . Height: "+n+", Width: "+o+"\nDirection "+t+", "+r,d={};do{if(0==t&&r>0){d.x=a,c+="\nUp direction",d.y=i+n/2;break}if(0==t&&0>r){d.x=a,d.y=i+n/2,c+="\nDown direction";break}if(t>0&&s>=-1*l&&l>=s){d.x=a+o/2,d.y=i+o*r/2/t,c+="\nRightborder";break}if(0>t&&s>=-1*l&&l>=s){d.x=a-o/2,d.y=i-o*r/2/t,c+="\nLeftborder";break}if(r>0&&(-1*l>=s||s>=l)){d.x=a+n*t/2/r,d.y=i+n/2,c+="\nTop border";break}if(0>r&&(-1*l>=s||s>=l)){d.x=a-n*t/2/r,d.y=i-n/2,c+="\nBottom border";break}}while(!1);return c+="\nClipping point found at "+d.x+", "+d.y,w(c),d},v=function(e,t,r,a){if(r>0)var i=e.maxX-t.minX;else var i=t.maxX-e.minX;if(a>0)var n=e.maxY-t.minY;else var n=t.maxY-e.minY;return i>=0&&n>=0?Math.sqrt(i*i+n*n):0},g=function(e,t,r){for(var a=0;ap;p++){var h=e.layoutNodes[e.idToIndex[n[p]]];a="Node: "+h.id;var v=l-h.positionX,g=c-h.positionY,f=Math.sqrt(v*v+g*g);if(f>1){var y=r.gravity*v/f,m=r.gravity*g/f;h.offsetX+=y,h.offsetY+=m,a+=": Applied force: "+y+", "+m}else a+=": skypped since it's too close to center";w(a)}}},y=function(e){var t=[],r=0,a=-1;for(w("propagateForces"),t.push.apply(t,e.graphSet[0]),a+=e.graphSet[0].length;a>=r;){var i=t[r++],n=e.idToIndex[i],o=e.layoutNodes[n],s=o.children;if(0r)var n={x:r*e/i,y:r*t/i};else var n={x:e,y:t};return a+=".\nResult: ("+n.x+", "+n.y+")",w(a),n},x=function(e,t){var r="Propagating new position/size of node "+e.id,a=e.parentId;if(void 0==a)return r+=". No parent node.",void w(r);var i=t.layoutNodes[t.idToIndex[a]],n=!1;return(void 0==i.maxX||e.maxX+i.padRight>i.maxX)&&(i.maxX=e.maxX+i.padRight,n=!0,r+="\nNew maxX for parent node "+i.id+": "+i.maxX),(void 0==i.minX||e.minX-i.padLefti.maxY)&&(i.maxY=e.maxY+i.padBottom,n=!0,r+="\nNew maxY for parent node "+i.id+": "+i.maxY),(void 0==i.minY||e.minY-i.padTop=0?a.substring(b):(b=a.length,""),d=[];while(b>0)d.push(a.substring(b-=3,b+3));return d.reverse().join(",")+c}function H(a,b){var c=Math.pow(10,Math.abs(8-b)*3);return{scale:b>8?function(a){return a/c}:function(a){return a*c},symbol:a}}function N(a){return function(b){return b<=0?0:b>=1?1:a(b)}}function O(a){return function(b){return 1-a(1-b)}}function P(a){return function(b){return.5*(b<.5?a(2*b):2-a(2-2*b))}}function Q(a){return a}function R(a){return function(b){return Math.pow(b,a)}}function S(a){return 1-Math.cos(a*Math.PI/2)}function T(a){return Math.pow(2,10*(a-1))}function U(a){return 1-Math.sqrt(1-a*a)}function V(a,b){var c;return arguments.length<2&&(b=.45),arguments.length<1?(a=1,c=b/4):c=b/(2*Math.PI)*Math.asin(1/a),function(d){return 1+a*Math.pow(2,10*-d)*Math.sin((d-c)*2*Math.PI/b)}}function W(a){return a||(a=1.70158),function(b){return b*b*((a+1)*b-a)}}function X(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375}function Y(){d3.event.stopPropagation(),d3.event.preventDefault()}function Z(){var a=d3.event,b;while(b=a.sourceEvent)a=b;return a}function $(a){var b=new z,c=0,d=arguments.length;while(++c360?a-=360:a<0&&(a+=360),a<60?d+(e-d)*a/60:a<180?e:a<240?d+(e-d)*(240-a)/60:d}function g(a){return Math.round(f(a)*255)}var d,e;return a%=360,a<0&&(a+=360),b=b<0?0:b>1?1:b,c=c<0?0:c>1?1:c,e=c<=.5?c*(1+b):c+b-c*b,d=2*c-e,bj(g(a+120),g(a),g(a-120))}function bv(a,b,c){return new bw(a,b,c)}function bw(a,b,c){this.h=a,this.c=b,this.l=c}function bx(a,b,c){return by(c,Math.cos(a*=Math.PI/180)*b,Math.sin(a)*b)}function by(a,b,c){return new bz(a,b,c)}function bz(a,b,c){this.l=a,this.a=b,this.b=c}function bE(a,b,c){var d=(a+16)/116,e=d+b/500,f=d-c/200;return e=bG(e)*bB,d=bG(d)*bC,f=bG(f)*bD,bj(bI(3.2404542*e-1.5371385*d-.4985314*f),bI(-0.969266*e+1.8760108*d+.041556*f),bI(.0556434*e-.2040259*d+1.0572252*f))}function bF(a,b,c){return bv(Math.atan2(c,b)/Math.PI*180,Math.sqrt(b*b+c*c),a)}function bG(a){return a>.206893034?a*a*a:(a-4/29)/7.787037}function bH(a){return a>.008856?Math.pow(a,1/3):7.787037*a+4/29}function bI(a){return Math.round(255*(a<=.00304?12.92*a:1.055*Math.pow(a,1/2.4)-.055))}function bJ(a){return i(a,bP),a}function bQ(a){return function(){return bK(a,this)}}function bR(a){return function(){return bL(a,this)}}function bS(a,b){function c(){this.removeAttribute(a)}function d(){this.removeAttributeNS(a.space,a.local)}function e(){this.setAttribute(a,b)}function f(){this.setAttributeNS(a.space,a.local,b)}function g(){var c=b.apply(this,arguments);c==null?this.removeAttribute(a):this.setAttribute(a,c)}function h(){var c=b.apply(this,arguments);c==null?this.removeAttributeNS(a.space,a.local):this.setAttributeNS(a.space,a.local,c)}return a=d3.ns.qualify(a),b==null?a.local?d:c:typeof b=="function"?a.local?h:g:a.local?f:e}function bT(a){return new RegExp("(?:^|\\s+)"+d3.requote(a)+"(?:\\s+|$)","g")}function bU(a,b){function d(){var d=-1;while(++d0&&(a=a.substring(0,e)),b?g:f}function ca(a,b){for(var c=0,d=a.length;cb?q():(m.active=b,d.forEach(function(b,c){(c=c.call(a,n,h))&&j.push(c)}),e.start.call(a,n,h),p(f)||d3.timer(p,0,c),1)}function p(c){if(m.active!==b)return q();var d=(c-k)/l,g=f(d),i=j.length;while(i>0)j[--i].call(a,g);if(d>=1)return q(),ch=b,e.end.call(a,n,h),ch=0,1}function q(){return--m.count||delete a.__transition__,1}var j=[],k=a.delay,l=a.duration,m=(a=a.node).__transition__||(a.__transition__={active:0,count:0}),n=a.__data__;++m.count,k<=g?o(g):d3.timer(o,k,c)})},0,c),a}function co(a){var b=ch,c=cn,d=cl,e=cm;return ch=this.id,cn=this.ease(),ca(this,function(b,c,d){cl=b.delay,cm=b.duration,a.call(b=b.node,b.__data__,c,d)}),ch=b,cn=c,cl=d,cm=e,this}function cq(a,b,c){return c!=""&&cp}function cr(a,b){return d3.tween(a,bg(b))}function cv(){var a,b=Date.now(),c=cs;while(c)a=b-c.then,a>=c.delay&&(c.flush=c.callback(a)),c=c.next;var d=cw()-b;d>24?(isFinite(d)&&(clearTimeout(cu),cu=setTimeout(cv,d)),ct=0):(ct=1,cx(cv))}function cw(){var a=null,b=cs,c=Infinity;while(b)b.flush?b=a?a.next=b.next:cs=b.next:(c=Math.min(c,b.then+b.delay),b=(a=b).next);return c}function cz(a,b){var c=a.ownerSVGElement||a;if(c.createSVGPoint){var d=c.createSVGPoint();if(cy<0&&(window.scrollX||window.scrollY)){c=d3.select(document.body).append("svg").style("position","absolute").style("top",0).style("left",0);var e=c[0][0].getScreenCTM();cy=!e.f&&!e.e,c.remove()}return cy?(d.x=b.pageX,d.y=b.pageY):(d.x=b.clientX,d.y=b.clientY),d=d.matrixTransform(a.getScreenCTM().inverse()),[d.x,d.y]}var f=a.getBoundingClientRect();return[b.clientX-f.left-a.clientLeft,b.clientY-f.top-a.clientTop]}function cA(){}function cB(a){var b=a[0],c=a[a.length-1];return b2?cM:cL,i=d?bi:bh;return e=g(a,b,i,c),f=g(b,a,i,d3.interpolate),h}function h(a){return e(a)}var e,f;return h.invert=function(a){return f(a)},h.domain=function(b){return arguments.length?(a=b.map(Number),g()):a},h.range=function(a){return arguments.length?(b=a,g()):b},h.rangeRound=function(a){return h.range(a).interpolate(d3.interpolateRound)},h.clamp=function(a){return arguments.length?(d=a,g()):d},h.interpolate=function(a){return arguments.length?(c=a,g()):c},h.ticks=function(b){return cJ(a,b)},h.tickFormat=function(b){return cK(a,b)},h.nice=function(){return cD(a,cH),g()},h.copy=function(){return cF(a,b,c,d)},g()}function cG(a,b){return d3.rebind(a,b,"range","rangeRound","interpolate","clamp")}function cH(a){return a=Math.pow(10,Math.round(Math.log(a)/Math.LN10)-1),a&&{floor:function(b){return Math.floor(b/a)*a},ceil:function(b){return Math.ceil(b/a)*a}}}function cI(a,b){var c=cB(a),d=c[1]-c[0],e=Math.pow(10,Math.floor(Math.log(d/b)/Math.LN10)),f=b/d*e;return f<=.15?e*=10:f<=.35?e*=5:f<=.75&&(e*=2),c[0]=Math.ceil(c[0]/e)*e,c[1]=Math.floor(c[1]/e)*e+e*.5,c[2]=e,c}function cJ(a,b){return d3.range.apply(d3,cI(a,b))}function cK(a,b){return d3.format(",."+Math.max(0,-Math.floor(Math.log(cI(a,b)[2])/Math.LN10+.01))+"f")}function cL(a,b,c,d){var e=c(a[0],a[1]),f=d(b[0],b[1]);return function(a){return f(e(a))}}function cM(a,b,c,d){var e=[],f=[],g=0,h=Math.min(a.length,b.length)-1;a[h]0;j--)e.push(c(f)*j)}else{for(;fi;g--);e=e.slice(f,g)}return e},d.tickFormat=function(a,e){arguments.length<2&&(e=cO);if(arguments.length<1)return e;var f=Math.max(.1,a/d.ticks().length),g=b===cQ?(h=-1e-12,Math.floor):(h=1e-12,Math.ceil),h;return function(a){return a/c(g(b(a)+h))<=f?e(a):""}},d.copy=function(){return cN(a.copy(),b)},cG(d,a)}function cP(a){return Math.log(a<0?0:a)/Math.LN10}function cQ(a){return-Math.log(a>0?0:-a)/Math.LN10}function cR(a,b){function e(b){return a(c(b))}var c=cS(b),d=cS(1/b);return e.invert=function(b){return d(a.invert(b))},e.domain=function(b){return arguments.length?(a.domain(b.map(c)),e):a.domain().map(d)},e.ticks=function(a){return cJ(e.domain(),a)},e.tickFormat=function(a){return cK(e.domain(),a)},e.nice=function(){return e.domain(cD(e.domain(),cH))},e.exponent=function(a){if(!arguments.length)return b;var f=e.domain();return c=cS(b=a),d=cS(1/b),e.domain(f)},e.copy=function(){return cR(a.copy(),b)},cG(e,a)}function cS(a){return function(b){return b<0?-Math.pow(-b,a):Math.pow(b,a)}}function cT(a,b){function f(b){return d[((c.get(b)||c.set(b,a.push(b)))-1)%d.length]}function g(b,c){return d3.range(a.length).map(function(a){return b+c*a})}var c,d,e;return f.domain=function(d){if(!arguments.length)return a;a=[],c=new j;var e=-1,g=d.length,h;while(++e1){h=b[1],f=a[i],i++,d+="C"+(e[0]+g[0])+","+(e[1]+g[1])+","+(f[0]-h[0])+","+(f[1]-h[1])+","+f[0]+","+f[1];for(var j=2;j9&&(f=c*3/Math.sqrt(f),g[h]=f*d,g[h+1]=f*e));h=-1;while(++h<=i)f=(a[Math.min(i,h+1)][0]-a[Math.max(0,h-1)][0])/(6*(1+g[h]*g[h])),b.push([f||0,g[h]*f||0]);return b}function dG(a){return a.length<3?dk(a):a[0]+ds(a,dF(a))}function dH(a){var b,c=-1,d=a.length,e,f;while(++c1){var d=cB(a.domain()),e,f=-1,g=b.length,h=(b[1]-b[0])/++c,i,j;while(++f0;)(j=+b[f]-i*h)>=d[0]&&e.push(j);for(--f,i=0;++id&&(c=b,d=e);return c}function ex(a){return a.reduce(ey,0)}function ey(a,b){return a+b[1]}function ez(a,b){return eA(a,Math.ceil(Math.log(b.length)/Math.LN2+1))}function eA(a,b){var c=-1,d=+a[0],e=(a[1]-d)/b,f=[];while(++c<=b)f[c]=e*c+d;return f}function eB(a){return[d3.min(a),d3.max(a)]}function eC(a,b){return d3.rebind(a,b,"sort","children","value"),a.links=eG,a.nodes=function(b){return eH=!0,(a.nodes=a)(b)},a}function eD(a){return a.children}function eE(a){return a.value}function eF(a,b){return b.value-a.value}function eG(a){return d3.merge(a.map(function(a){return(a.children||[]).map(function(b){return{source:a,target:b}})}))}function eI(a,b){return a.value-b.value}function eJ(a,b){var c=a._pack_next;a._pack_next=b,b._pack_prev=a,b._pack_next=c,c._pack_prev=b}function eK(a,b){a._pack_next=b,b._pack_prev=a}function eL(a,b){var c=b.x-a.x,d=b.y-a.y,e=a.r+b.r;return e*e-c*c-d*d>.001}function eM(a){function n(a){c=Math.min(a.x-a.r,c),d=Math.max(a.x+a.r,d),e=Math.min(a.y-a.r,e),f=Math.max(a.y+a.r,f)}if(!(b=a.children)||!(m=b.length))return;var b,c=Infinity,d=-Infinity,e=Infinity,f=-Infinity,g,h,i,j,k,l,m;b.forEach(eN),g=b[0],g.x=-g.r,g.y=0,n(g);if(m>1){h=b[1],h.x=h.r,h.y=0,n(h);if(m>2){i=b[2],eQ(g,h,i),n(i),eJ(g,i),g._pack_prev=i,eJ(i,h),h=g._pack_next;for(j=3;j0&&(a=d)}return a}function eZ(a,b){return a.x-b.x}function e$(a,b){return b.x-a.x}function e_(a,b){return a.depth-b.depth}function fa(a,b){function c(a,d){var e=a.children;if(e&&(i=e.length)){var f,g=null,h=-1,i;while(++h=0)f=d[e]._tree,f.prelim+=b,f.mod+=b,b+=f.shift+(c+=f.change)}function fc(a,b,c){a=a._tree,b=b._tree;var d=c/(b.number-a.number);a.change+=d,b.change-=d,b.shift+=c,b.prelim+=c,b.mod+=c}function fd(a,b,c){return a._tree.ancestor.parent==b.parent?a._tree.ancestor:c}function fe(a){return{x:a.x,y:a.y,dx:a.dx,dy:a.dy}}function ff(a,b){var c=a.x+b[3],d=a.y+b[0],e=a.dx-b[1]-b[3],f=a.dy-b[0]-b[2];return e<0&&(c+=e/2,e=0),f<0&&(d+=f/2,f=0),{x:c,y:d,dx:e,dy:f}}function fg(a,b){function f(a,c){d3.text(a,b,function(a){c(a&&f.parse(a))})}function g(b){return b.map(h).join(a)}function h(a){return d.test(a)?'"'+a.replace(/\"/g,'""')+'"':a}var c=new RegExp("\r\n|["+a+"\r\n]","g"),d=new RegExp('["'+a+"\n]"),e=a.charCodeAt(0);return f.parse=function(a){var b;return f.parseRows(a,function(a,c){if(c){var d={},e=-1,f=b.length;while(++e=a.length)return f;if(j)return j=!1,d;var b=c.lastIndex;if(a.charCodeAt(b)===34){var g=b;while(g++0}function fC(a,b,c){return(c[0]-b[0])*(a[1]-b[1])<(c[1]-b[1])*(a[0]-b[0])}function fD(a,b,c,d){var e=a[0],f=b[0],g=c[0],h=d[0],i=a[1],j=b[1],k=c[1],l=d[1],m=e-g,n=f-e,o=h-g,p=i-k,q=j-i,r=l-k,s=(o*p-r*m)/(r*n-o*q);return[e+s*n,i+s*q]}function fF(a,b){var c={list:a.map(function(a,b){return{index:b,x:a[0],y:a[1]}}).sort(function(a,b){return a.yb.y?1:a.xb.x?1:0}),bottomSite:null},d={list:[],leftEnd:null,rightEnd:null,init:function(){d.leftEnd=d.createHalfEdge(null,"l"),d.rightEnd=d.createHalfEdge(null,"l"),d.leftEnd.r=d.rightEnd,d.rightEnd.l=d.leftEnd,d.list.unshift(d.leftEnd,d.rightEnd)},createHalfEdge:function(a,b){return{edge:a,side:b,vertex:null,l:null,r:null}},insert:function(a,b){b.l=a,b.r=a.r,a.r.l=b,a.r=b},leftBound:function(a){var b=d.leftEnd;do b=b.r;while(b!=d.rightEnd&&e.rightOf(b,a));return b=b.l,b},del:function(a){a.l.r=a.r,a.r.l=a.l,a.edge=null},right:function(a){return a.r},left:function(a){return a.l},leftRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[a.side]},rightRegion:function(a){return a.edge==null?c.bottomSite:a.edge.region[fE[a.side]]}},e={bisect:function(a,b){var c={region:{l:a,r:b},ep:{l:null,r:null}},d=b.x-a.x,e=b.y-a.y,f=d>0?d:-d,g=e>0?e:-e;return c.c=a.x*d+a.y*e+(d*d+e*e)*.5,f>g?(c.a=1,c.b=e/d,c.c/=d):(c.b=1,c.a=d/e,c.c/=e),c},intersect:function(a,b){var c=a.edge,d=b.edge;if(!c||!d||c.region.r==d.region.r)return null;var e=c.a*d.b-c.b*d.a;if(Math.abs(e)<1e-10)return null;var f=(c.c*d.b-d.c*c.b)/e,g=(d.c*c.a-c.c*d.a)/e,h=c.region.r,i=d.region.r,j,k;h.y=k.region.r.x;return l&&j.side==="l"||!l&&j.side==="r"?null:{x:f,y:g}},rightOf:function(a,b){var c=a.edge,d=c.region.r,e=b.x>d.x;if(e&&a.side==="l")return 1;if(!e&&a.side==="r")return 0;if(c.a===1){var f=b.y-d.y,g=b.x-d.x,h=0,i=0;!e&&c.b<0||e&&c.b>=0?i=h=f>=c.b*g:(i=b.x+b.y*c.b>c.c,c.b<0&&(i=!i),i||(h=1));if(!h){var j=d.x-c.region.l.x;i=c.b*(g*g-f*f)m*m+n*n}return a.side==="l"?i:!i},endPoint:function(a,c,d){a.ep[c]=d;if(!a.ep[fE[c]])return;b(a)},distance:function(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}},f={list:[],insert:function(a,b,c){a.vertex=b,a.ystar=b.y+c;for(var d=0,e=f.list,g=e.length;dh.ystar||a.ystar==h.ystar&&b.x>h.vertex.x)continue;break}e.splice(d,0,a)},del:function(a){for(var b=0,c=f.list,d=c.length;bo.y&&(p=n,n=o,o=p,t="r"),s=e.bisect(n,o),m=d.createHalfEdge(s,t),d.insert(k,m),e.endPoint(s,fE[t],r),q=e.intersect(k,m),q&&(f.del(k),f.insert(k,q,e.distance(q,n))),q=e.intersect(m,l),q&&f.insert(m,q,e.distance(q,n));else break}for(i=d.right(d.leftEnd);i!=d.rightEnd;i=d.right(i))b(i.edge)}function fG(){return{leaf:!0,nodes:[],point:null}}function fH(a,b,c,d,e,f){if(!a(b,c,d,e,f)){var g=(c+e)*.5,h=(d+f)*.5,i=b.nodes;i[0]&&fH(a,i[0],c,d,g,h),i[1]&&fH(a,i[1],g,d,e,h),i[2]&&fH(a,i[2],c,h,g,f),i[3]&&fH(a,i[3],g,h,e,f)}}function fI(a){return{x:a[0],y:a[1]}}function fL(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function fU(a){return a.substring(0,3)}function fV(a,b,c,d){var e,f,g=0,h=b.length,i=c.length;while(g=i)return-1;e=b.charCodeAt(g++);if(e==37){f=gh[b.charAt(g++)];if(!f||(d=f(a,c,d))<0)return-1}else if(e!=c.charCodeAt(d++))return-1}return d}function fW(a){return new RegExp("^(?:"+a.map(d3.requote).join("|")+")","i")}function fX(a){var b=new j,c=-1,d=a.length;while(++c68?1900:2e3)}function gs(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.m=d[0]-1,c+=d[0].length):-1}function gt(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.d=+d[0],c+=d[0].length):-1}function gu(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.H=+d[0],c+=d[0].length):-1}function gv(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.M=+d[0],c+=d[0].length):-1}function gw(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+2));return d?(a.S=+d[0],c+=d[0].length):-1}function gx(a,b,c){gy.lastIndex=0;var d=gy.exec(b.substring(c,c+3));return d?(a.L=+d[0],c+=d[0].length):-1}function gz(a,b,c){var d=gA.get(b.substring(c,c+=2).toLowerCase());return d==null?-1:(a.p=d,c)}function gB(a){var b=a.getTimezoneOffset(),c=b>0?"-":"+",d=~~(Math.abs(b)/60),e=Math.abs(b)%60;return c+fY(d)+fY(e)}function gD(a){return a.toISOString()}function gE(a,b,c){function d(b){var c=a(b),d=f(c,1);return b-c1)while(gb?1:a>=b?0:NaN},d3.descending=function(a,b){return ba?1:b>=a?0:NaN},d3.mean=function(a,b){var c=a.length,d,e=0,f=-1,g=0;if(arguments.length===1)while(++f1&&(a=a.map(b)),a=a.filter(r),a.length?d3.quantile(a.sort(d3.ascending),.5):undefined},d3.min=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++cf&&(e=f)}else{while(++cf&&(e=f)}return e},d3.max=function(a,b){var c=-1,d=a.length,e,f;if(arguments.length===1){while(++ce&&(e=f)}else{while(++ce&&(e=f)}return e},d3.extent=function(a,b){var c=-1,d=a.length,e,f,g;if(arguments.length===1){while(++cf&&(e=f),gf&&(e=f),g1);return a+b*c*Math.sqrt(-2*Math.log(e)/e)}},logNormal:function(a,b){var c=arguments.length;c<2&&(b=1),c<1&&(a=0);var d=d3.random.normal();return function(){return Math.exp(a+b*d())}},irwinHall:function(a){return function(){for(var b=0,c=0;c>>1;a.call(b,b[f],f)>>1;c0&&(e=f);return e},d3.last=function(a,b){var c=0,d=a.length,e=a[0],f;arguments.length===1&&(b=d3.ascending);while(++c=b.length)return e?e.call(a,c):d?c.sort(d):c;var h=-1,i=c.length,k=b[g++],l,m,n=new j,o,p={};while(++h=b.length)return a;var e=[],f=c[d++],h;for(h in a)e.push({key:h,values:g(a[h],d)});return f&&e.sort(function(a,b){return f(a.key,b.key)}),e}var a={},b=[],c=[],d,e;return a.map=function(a){return f(a,0)},a.entries=function(a){return g(f(a,0),0)},a.key=function(c){return b.push(c),a},a.sortKeys=function(d){return c[b.length-1]=d,a},a.sortValues=function(b){return d=b,a},a.rollup=function(b){return e=b,a},a},d3.keys=function(a){var b=[];for(var c in a)b.push(c);return b},d3.values=function(a){var b=[];for(var c in a)b.push(a[c]);return b},d3.entries=function(a){var b=[];for(var c in a)b.push({key:c,value:a[c]});return b},d3.permute=function(a,b){var c=[],d=-1,e=b.length;while(++db)d.push(g/e);else while((g=a+c*++f)=200&&a<300||a===304?d:null)}},d.send(null)},d3.text=function(a,b,c){function d(a){c(a&&a.responseText)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)},d3.json=function(a,b){d3.text(a,"application/json",function(a){b(a?JSON.parse(a):null)})},d3.html=function(a,b){d3.text(a,"text/html",function(a){if(a!=null){var c=document.createRange();c.selectNode(document.body),a=c.createContextualFragment(a)}b(a)})},d3.xml=function(a,b,c){function d(a){c(a&&a.responseXML)}arguments.length<3&&(c=b,b=null),d3.xhr(a,b,d)};var y={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};d3.ns={prefix:y,qualify:function(a){var b=a.indexOf(":"),c=a;return b>=0&&(c=a.substring(0,b),a=a.substring(b+1)),y.hasOwnProperty(c)?{space:y[c],local:a}:a}},d3.dispatch=function(){var a=new z,b=-1,c=arguments.length;while(++b0&&(d=a.substring(c+1),a=a.substring(0,c)),arguments.length<2?this[a].on(d):this[a].on(d,b)},d3.format=function(a){var b=B.exec(a),c=b[1]||" ",d=b[3]||"",e=b[5],f=+b[6],g=b[7],h=b[8],i=b[9],j=1,k="",l=!1;h&&(h=+h.substring(1)),e&&(c="0",g&&(f-=Math.floor((f-1)/4)));switch(i){case"n":g=!0,i="g";break;case"%":j=100,k="%",i="f";break;case"p":j=100,k="%",i="r";break;case"d":l=!0,h=0;break;case"s":j=-1,i="r"}return i=="r"&&!h&&(i="g"),i=C.get(i)||E,function(a){if(l&&a%1)return"";var b=a<0&&(a=-a)?"-":d;if(j<0){var m=d3.formatPrefix(a,h);a=m.scale(a),k=m.symbol}else a*=j;a=i(a,h);if(e){var n=a.length+b.length;n=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,C=d3.map({g:function(a,b){return a.toPrecision(b)},e:function(a,b){return a.toExponential(b)},f:function(a,b){return a.toFixed(b)},r:function(a,b){return d3.round(a,b=D(a,b)).toFixed(Math.max(0,Math.min(20,b)))}}),G=["y","z","a","f","p","n","ÎĽ","m","","k","M","G","T","P","E","Z","Y"].map(H);d3.formatPrefix=function(a,b){var c=0;return a&&(a<0&&(a*=-1),b&&(a=d3.round(a,D(a,b))),c=1+Math.floor(1e-12+Math.log(a)/Math.LN10),c=Math.max(-24,Math.min(24,Math.floor((c<=0?c+1:c-1)/3)*3))),G[8+c/3]};var I=R(2),J=R(3),K=function(){return Q},L=d3.map({linear:K,poly:R,quad:function(){return I},cubic:function(){return J},sin:function(){return S},exp:function(){return T},circle:function(){return U},elastic:V,back:W,bounce:function(){return X}}),M=d3.map({"in":Q,out:O,"in-out":P,"out-in":function(a){return P(O(a))}});d3.ease=function(a){var b=a.indexOf("-"),c=b>=0?a.substring(0,b):a,d=b>=0?a.substring(b+1):"in";return c=L.get(c)||K,d=M.get(d)||Q,N(d(c.apply(null,Array.prototype.slice.call(arguments,1))))},d3.event=null,d3.transform=function(a){var b=document.createElementNS(d3.ns.prefix.svg,"g");return(d3.transform=function(a){b.setAttribute("transform",a);var c=b.transform.baseVal.consolidate();return new _(c?c.matrix:be)})(a)},_.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var bd=180/Math.PI,be={a:1,b:0,c:0,d:1,e:0,f:0};d3.interpolate=function(a,b){var c=d3.interpolators.length,d;while(--c>=0&&!(d=d3.interpolators[c](a,b)));return d},d3.interpolateNumber=function(a,b){return b-=a,function(c){return a+b*c}},d3.interpolateRound=function(a,b){return b-=a,function(c){return Math.round(a+b*c)}},d3.interpolateString=function(a,b){var c,d,e,f=0,g=0,h=[],i=[],j,k;bf.lastIndex=0;for(d=0;c=bf.exec(b);++d)c.index&&h.push(b.substring(f,g=c.index)),i.push({i:h.length,x:c[0]}),h.push(null),f=bf.lastIndex;f180?k+=360:k-j>180&&(j+=360),d.push({i:c.push(c.pop()+"rotate(",null,")")-2,x:d3.interpolateNumber(j,k)})):k&&c.push(c.pop()+"rotate("+k+")"),l!=m?d.push({i:c.push(c.pop()+"skewX(",null,")")-2,x:d3.interpolateNumber(l,m)}):m&&c.push(c.pop()+"skewX("+m+")"),n[0]!=o[0]||n[1]!=o[1]?(e=c.push(c.pop()+"scale(",null,",",null,")"),d.push({i:e-4,x:d3.interpolateNumber(n[0],o[0])},{i:e-2,x:d3.interpolateNumber(n[1],o[1])})):(o[0]!=1||o[1]!=1)&&c.push(c.pop()+"scale("+o+")"),e=d.length,function(a){var b=-1,f;while(++b180?f-=360:f<-180&&(f+=360),function(a){return bu(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateLab=function(a,b){a=d3.lab(a),b=d3.lab(b);var c=a.l,d=a.a,e=a.b,f=b.l-c,g=b.a-d,h=b.b-e;return function(a){return bE(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateHcl=function(a,b){a=d3.hcl(a),b=d3.hcl(b);var c=a.h,d=a.c,e=a.l,f=b.h-c,g=b.c-d,h=b.l-e;return f>180?f-=360:f<-180&&(f+=360),function(a){return bx(c+f*a,d+g*a,e+h*a)+""}},d3.interpolateArray=function(a,b){var c=[],d=[],e=a.length,f=b.length,g=Math.min(a.length,b.length),h;for(h=0;h=0;)if(f=c[d])e&&e!==f.nextSibling&&e.parentNode.insertBefore(f,e),e=f;return this},bP.sort=function(a){a=b$.apply(this,arguments);for(var b=-1,c=this.length;++b=db?e?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+e+"A"+e+","+e+" 0 1,0 0,"+ -e+"A"+e+","+e+" 0 1,0 0,"+e+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+ -f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":e?"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L"+e*m+","+e*n+"A"+e+","+e+" 0 "+j+",0 "+e*k+","+e*l+"Z":"M"+f*k+","+f*l+"A"+f+","+f+" 0 "+j+",1 "+f*m+","+f*n+"L0,0"+"Z"}var a=dc,b=dd,c=de,d=df;return e.innerRadius=function(b){return arguments.length?(a=p(b),e):a},e.outerRadius=function(a){return arguments.length?(b=p(a),e):b},e.startAngle=function(a){return arguments.length?(c=p(a),e):c},e.endAngle=function(a){return arguments.length?(d=p(a),e):d},e.centroid=function(){var e=(a.apply(this,arguments)+b.apply(this,arguments))/2,f=(c.apply(this,arguments)+d.apply(this,arguments))/2+da;return[Math.cos(f)*e,Math.sin(f)*e]},e};var da=-Math.PI/2,db=2*Math.PI-1e-6;d3.svg.line=function(){return dg(m)};var dj=d3.map({linear:dk,"linear-closed":dl,"step-before":dm,"step-after":dn,basis:du,"basis-open":dv,"basis-closed":dw,bundle:dx,cardinal:dr,"cardinal-open":dp,"cardinal-closed":dq,monotone:dG});dj.forEach(function(a,b){b.key=a,b.closed=/-closed$/.test(a)});var dz=[0,2/3,1/3,0],dA=[0,1/3,2/3,0],dB=[0,1/6,2/3,1/6];d3.svg.line.radial=function(){var a=dg(dH);return a.radius=a.x,delete a.x,a.angle=a.y,delete a.y,a},dm.reverse=dn,dn.reverse=dm,d3.svg.area=function(){return dI(m)},d3.svg.area.radial=function(){var a=dI(dH);return a.radius=a.x,delete a.x,a.innerRadius=a.x0,delete a.x0,a.outerRadius=a.x1,delete a.x1,a.angle=a.y,delete a.y,a.startAngle=a.y0,delete a.y0,a.endAngle=a.y1,delete a.y1,a},d3.svg.chord=function(){function f(c,d){var e=g(this,a,c,d),f=g(this,b,c,d);return"M"+e.p0+i(e.r,e.p1,e.a1-e.a0)+(h(e,f)?j(e.r,e.p1,e.r,e.p0):j(e.r,e.p1,f.r,f.p0)+i(f.r,f.p1,f.a1-f.a0)+j(f.r,f.p1,e.r,e.p0))+"Z"}function g(a,b,f,g){var h=b.call(a,f,g),i=c.call(a,h,g),j=d.call(a,h,g)+da,k=e.call(a,h,g)+da;return{r:i,a0:j,a1:k,p0:[i*Math.cos(j),i*Math.sin(j)],p1:[i*Math.cos(k),i*Math.sin(k)]}}function h(a,b){return a.a0==b.a0&&a.a1==b.a1}function i(a,b,c){return"A"+a+","+a+" 0 "+ +(c>Math.PI)+",1 "+b}function j(a,b,c,d){return"Q 0,0 "+d}var a=dJ,b=dK,c=dL,d=de,e=df;return f.radius=function(a){return arguments.length?(c=p(a),f):c},f.source=function(b){return arguments.length?(a=p(b),f):a},f.target=function(a){return arguments.length?(b=p(a),f):b},f.startAngle=function(a){return arguments.length?(d=p(a),f):d},f.endAngle=function(a){return arguments.length?(e=p(a),f):e},f},d3.svg.diagonal=function(){function d(d,e){var f=a.call(this,d,e),g=b.call(this,d,e),h=(f.y+g.y)/2,i=[f,{x:f.x,y:h},{x:g.x,y:h},g];return i=i.map(c),"M"+i[0]+"C"+i[1]+" "+i[2]+" "+i[3]}var a=dJ,b=dK,c=dO;return d.source=function(b){return arguments.length?(a=p(b),d):a},d.target=function(a){return arguments.length?(b=p(a),d):b},d.projection=function(a){return arguments.length?(c=a,d):c},d},d3.svg.diagonal.radial=function(){var a=d3.svg.diagonal(),b=dO,c=a.projection;return a.projection=function(a){return arguments.length?c(dP(b=a)):b},a},d3.svg.mouse=d3.mouse,d3.svg.touches=d3.touches,d3.svg.symbol=function(){function c(c,d){return(dT.get(a.call(this,c,d))||dS)(b.call(this,c,d))}var a=dR,b=dQ;return c.type=function(b){return arguments.length?(a=p(b),c):a},c.size=function(a){return arguments.length?(b=p(a),c):b},c};var dT=d3.map({circle:dS,cross:function(a){var b=Math.sqrt(a/5)/2;return"M"+ -3*b+","+ -b+"H"+ -b+"V"+ -3*b+"H"+b+"V"+ -b+"H"+3*b+"V"+b+"H"+b+"V"+3*b+"H"+ -b+"V"+b+"H"+ -3*b+"Z"},diamond:function(a){var b=Math.sqrt(a/(2*dV)),c=b*dV;return"M0,"+ -b+"L"+c+",0"+" 0,"+b+" "+ -c+",0"+"Z"},square:function(a){var b=Math.sqrt(a)/2;return"M"+ -b+","+ -b+"L"+b+","+ -b+" "+b+","+b+" "+ -b+","+b+"Z"},"triangle-down":function(a){var b=Math.sqrt(a/dU),c=b*dU/2;return"M0,"+c+"L"+b+","+ -c+" "+ -b+","+ -c+"Z"},"triangle-up":function(a){var b=Math.sqrt(a/dU),c=b*dU/2;return"M0,"+ -c+"L"+b+","+c+" "+ -b+","+c+"Z"}});d3.svg.symbolTypes=dT.keys();var dU=Math.sqrt(3),dV=Math.tan(30*Math.PI/180);d3.svg.axis=function(){function k(k){k.each(function(){var k=d3.select(this),l=h==null?a.ticks?a.ticks.apply(a,g):a.domain():h,m=i==null?a.tickFormat?a.tickFormat.apply(a,g):String:i,n=dY(a,l,j),o=k.selectAll(".minor").data(n,String),p=o.enter().insert("line","g").attr("class","tick minor").style("opacity",1e-6),q=d3.transition(o.exit()).style("opacity",1e-6).remove(),r=d3.transition(o).style("opacity",1),s=k.selectAll("g").data(l,String),t=s.enter().insert("g","path").style("opacity",1e-6),u=d3.transition(s.exit()).style("opacity",1e-6).remove(),v=d3.transition(s).style("opacity",1),w,x=cC(a),y=k.selectAll(".domain").data([0]),z=y.enter().append("path").attr("class","domain"),A=d3.transition(y),B=a.copy(),C=this.__chart__||B;this.__chart__=B,t.append("line").attr("class","tick"),t.append("text");var D=t.select("line"),E=v.select("line"),F=s.select("text").text(m),G=t.select("text"),H=v.select("text");switch(b){case"bottom":w=dW,p.attr("y2",d),r.attr("x2",0).attr("y2",d),D.attr("y2",c),G.attr("y",Math.max(c,0)+f),E.attr("x2",0).attr("y2",c),H.attr("x",0).attr("y",Math.max(c,0)+f),F.attr("dy",".71em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+e+"V0H"+x[1]+"V"+e);break;case"top":w=dW,p.attr("y2",-d),r.attr("x2",0).attr("y2",-d),D.attr("y2",-c),G.attr("y",-(Math.max(c,0)+f)),E.attr("x2",0).attr("y2",-c),H.attr("x",0).attr("y",-(Math.max(c,0)+f)),F.attr("dy","0em").attr("text-anchor","middle"),A.attr("d","M"+x[0]+","+ -e+"V0H"+x[1]+"V"+ -e);break;case"left":w=dX,p.attr("x2",-d),r.attr("x2",-d).attr("y2",0),D.attr("x2",-c),G.attr("x",-(Math.max(c,0)+f)),E.attr("x2",-c).attr("y2",0),H.attr("x",-(Math.max(c,0)+f)).attr("y",0),F.attr("dy",".32em").attr("text-anchor","end"),A.attr("d","M"+ -e+","+x[0]+"H0V"+x[1]+"H"+ -e);break;case"right":w=dX,p.attr("x2",d),r.attr("x2",d).attr("y2",0),D.attr("x2",c),G.attr("x",Math.max(c,0)+f),E.attr("x2",c).attr("y2",0),H.attr("x",Math.max(c,0)+f).attr("y",0),F.attr("dy",".32em").attr("text-anchor","start"),A.attr("d","M"+e+","+x[0]+"H0V"+x[1]+"H"+e)}if(a.ticks)t.call(w,C),v.call(w,B),u.call(w,B),p.call(w,C),r.call(w,B),q.call(w,B);else{var I=B.rangeBand()/2,J=function(a){return B(a)+I};t.call(w,J),v.call(w,J)}})}var a=d3.scale.linear(),b="bottom",c=6,d=6,e=6,f=3,g=[10],h=null,i,j=0;return k.scale=function(b){return arguments.length?(a=b,k):a},k.orient=function(a){return arguments.length?(b=a,k):b},k.ticks=function(){return arguments.length?(g=arguments,k):g},k.tickValues=function(a){return arguments.length?(h=a,k):h},k.tickFormat=function(a){return arguments.length?(i=a,k):i},k.tickSize=function(a,b,f){if(!arguments.length)return c;var g=arguments.length-1;return c=+a,d=g>1?+b:c,e=g>0?+arguments[g]:c,k},k.tickPadding=function(a){return arguments.length?(f=+a,k):f},k.tickSubdivide=function(a){return arguments.length?(j=+a,k):j},k},d3.svg.brush=function(){function g(a){a.each(function(){var a=d3.select(this),e=a.selectAll(".background").data([0]),f=a.selectAll(".extent").data([0]),l=a.selectAll(".resize").data(d,String),m;a.style("pointer-events","all").on("mousedown.brush",k).on("touchstart.brush",k),e.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),f.enter().append("rect").attr("class","extent").style("cursor","move"),l.enter().append("g").attr("class",function(a){return"resize "+a}).style("cursor",function(a){return dZ[a]}).append("rect").attr("x",function(a){return/[ew]$/.test(a)?-3:null}).attr("y",function(a){return/^[ns]/.test(a)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),l.style("display",g.empty()?"none":null),l.exit().remove(),b&&(m=cC(b),e.attr("x",m[0]).attr("width",m[1]-m[0]),i(a)),c&&(m=cC(c),e.attr("y",m[0]).attr("height",m[1]-m[0]),j(a)),h(a)})}function h(a){a.selectAll(".resize").attr("transform",function(a){return"translate("+e[+/e$/.test(a)][0]+","+e[+/^s/.test(a)][1]+")"})}function i(a){a.select(".extent").attr("x",e[0][0]),a.selectAll(".extent,.n>rect,.s>rect").attr("width",e[1][0]-e[0][0])}function j(a){a.select(".extent").attr("y",e[0][1]),a.selectAll(".extent,.e>rect,.w>rect").attr("height",e[1][1]-e[0][1])}function k(){function x(){var a=d3.event.changedTouches;return a?d3.touches(d,a)[0]:d3.mouse(d)}function y(){d3.event.keyCode==32&&(q||(r=null,s[0]-=e[1][0],s[1]-=e[1][1],q=2),Y())}function z(){d3.event.keyCode==32&&q==2&&(s[0]+=e[1][0],s[1]+=e[1][1],q=0,Y())}function A(){var a=x(),d=!1;t&&(a[0]+=t[0],a[1]+=t[1]),q||(d3.event.altKey?(r||(r=[(e[0][0]+e[1][0])/2,(e[0][1]+e[1][1])/2]),s[0]=e[+(a[0]0?e=c:e=0:c>0&&(b.start({type:"start",alpha:e=c}),d3.timer(a.tick)),a):e},a.start=function(){function p(a,c){var d=t(b),e=-1,f=d.length,g;while(++ee&&(e=h),d.push(h)}for(g=0;g0){f=-1;while(++f=i[0]&&o<=i[1]&&(k=g[d3.bisect(j,o,1,m)-1],k.y+=n,k.push(e[f]))}return g}var a=!0,b=Number,c=eB,d=ez;return e.value=function(a){return arguments.length?(b=a,e):b},e.range=function(a){return arguments.length?(c=p(a),e):c},e.bins=function(a){return arguments.length?(d=typeof a=="number"?function(b){return eA(b,a)}:p(a),e):d},e.frequency=function(b){return arguments.length?(a=!!b,e):a},e},d3.layout.hierarchy=function(){function d(e,g,h){var i=b.call(f,e,g),j=eH?e:{data:e};j.depth=g,h.push(j);if(i&&(l=i.length)){var k=-1,l,m=j.children=[],n=0,o=g+1,p;while(++k0){var k=b*j/2;fa(g,function(a){a.r+=k}),fa(g,eM),fa(g,function(a){a.r-=k}),j=Math.max(2*g.r/h,2*g.r/i)}return eP(g,h/2,i/2,1/j),f}var a=d3.layout.hierarchy().sort(eI),b=0,c=[1,1];return d.size=function(a){return arguments.length?(c=a,d):c},d.padding=function(a){return arguments.length?(b=+a,d):b},eC(d,a)},d3.layout.cluster=function(){function d(d,e){var f=a.call(this,d,e),g=f[0],h,i=0,j,k;fa(g,function(a){var c=a.children;c&&c.length?(a.x=eS(c),a.y=eR(c)):(a.x=h?i+=b(a,h):0,a.y=0,h=a)});var l=eT(g),m=eU(g),n=l.x-b(l,m)/2,o=m.x+b(m,l)/2;return fa(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=(1-(g.y?a.y/g.y:1))*c[1]}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=eV,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},eC(d,a)},d3.layout.tree=function(){function d(d,e){function h(a,c){var d=a.children,e=a._tree;if(d&&(f=d.length)){var f,g=d[0],i,k=g,l,m=-1;while(++m0&&(fc(fd(g,a,d),a,m),i+=m,j+=m),k+=g._tree.mod,i+=e._tree.mod,l+=h._tree.mod,j+=f._tree.mod;g&&!eX(f)&&(f._tree.thread=g,f._tree.mod+=k-j),e&&!eW(h)&&(h._tree.thread=e,h._tree.mod+=i-l,d=a)}return d}var f=a.call(this,d,e),g=f[0];fa(g,function(a,b){a._tree={ancestor:a,prelim:0,mod:0,change:0,shift:0,number:b?b._tree.number+1:0}}),h(g),i(g,-g._tree.prelim);var k=eY(g,e$),l=eY(g,eZ),m=eY(g,e_),n=k.x-b(k,l)/2,o=l.x+b(l,k)/2,p=m.depth||1;return fa(g,function(a){a.x=(a.x-n)/(o-n)*c[0],a.y=a.depth/p*c[1],delete a._tree}),f}var a=d3.layout.hierarchy().sort(null).value(null),b=eV,c=[1,1];return d.separation=function(a){return arguments.length?(b=a,d):b},d.size=function(a){return arguments.length?(c=a,d):c},eC(d,a)},d3.layout.treemap=function(){function i(a,b){var c=-1,d=a.length,e,f;while(++c0)d.push(g=f[o-1]),d.area+=g.area,(k=l(d,n))<=h?(f.pop(),h=k):(d.area-=d.pop().area,m(d,n,c,!1),n=Math.min(c.dx,c.dy),d.length=d.area=0,h=Infinity);d.length&&(m(d,n,c,!0),d.length=d.area=0),b.forEach(j)}}function k(a){var b=a.children;if(b&&b.length){var c=e(a),d=b.slice(),f,g=[];i(d,c.dx*c.dy/a.value),g.area=0;while(f=d.pop())g.push(f),g.area+=f.area,f.z!=null&&(m(g,f.z?c.dx:c.dy,c,!d.length),g.length=g.area=0);b.forEach(k)}}function l(a,b){var c=a.area,d,e=0,f=Infinity,g=-1,i=a.length;while(++ge&&(e=d)}return c*=c,b*=b,c?Math.max(b*e*h/c,c/(b*f*h)):Infinity}function m(a,c,d,e){var f=-1,g=a.length,h=d.x,i=d.y,j=c?b(a.area/c):0,k;if(c==d.dx){if(e||j>d.dy)j=d.dy;while(++fd.dx)j=d.dx;while(++f50?b:f<-140?c:g<21?d:a)(e)}var a=d3.geo.albers(),b=d3.geo.albers().origin([-160,60]).parallels([55,65]),c=d3.geo.albers().origin([-160,20]).parallels([8,18]),d=d3.geo.albers().origin([-60,10]).parallels([8,18]);return e.scale=function(f){return arguments.length?(a.scale(f),b.scale(f*.6),c.scale(f),d.scale(f*1.5),e.translate(a.translate())):a.scale()},e.translate=function(f){if(!arguments.length)return a.translate();var g=a.scale()/1e3,h=f[0],i=f[1];return a.translate(f),b.translate([h-400*g,i+170*g]),c.translate([h-190*g,i+200*g]),d.translate([h+580*g,i+430*g]),e},e.scale(a.scale())},d3.geo.bonne=function(){function g(g){var h=g[0]*fh-c,i=g[1]*fh-d;if(e){var j=f+e-i,k=h*Math.cos(i)/j;h=j*Math.sin(k),i=j*Math.cos(k)-f}else h*=Math.cos(i),i*=-1;return[a*h+b[0],a*i+b[1]]}var a=200,b=[480,250],c,d,e,f;return g.invert=function(d){var g=(d[0]-b[0])/a,h=(d[1]-b[1])/a;if(e){var i=f+h,j=Math.sqrt(g*g+i*i);h=f+e-j,g=c+j*Math.atan2(g,i)/Math.cos(h)}else h*=-1,g/=Math.cos(h);return[g/fh,h/fh]},g.parallel=function(a){return arguments.length?(f=1/ -Math.tan(e=a*fh),g):e/fh},g.origin=function(a){return arguments.length?(c=a[0]*fh,d=a[1]*fh,g):[c/fh,d/fh]},g.scale=function(b){return arguments.length?(a=+b,g):a},g.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],g):b},g.origin([0,0]).parallel(45)},d3.geo.equirectangular=function(){function c(c){var d=c[0]/360,e=-c[1]/360;return[a*d+b[0],a*e+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,-360*e]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.mercator=function(){function c(c){var d=c[0]/360,e=-(Math.log(Math.tan(Math.PI/4+c[1]*fh/2))/fh)/360;return[a*d+b[0],a*Math.max(-0.5,Math.min(.5,e))+b[1]]}var a=500,b=[480,250];return c.invert=function(c){var d=(c[0]-b[0])/a,e=(c[1]-b[1])/a;return[360*d,2*Math.atan(Math.exp(-360*e*fh))/fh-90]},c.scale=function(b){return arguments.length?(a=+b,c):a},c.translate=function(a){return arguments.length?(b=[+a[0],+a[1]],c):b},c},d3.geo.path=function(){function e(c,e){typeof a=="function"&&(b=fj(a.apply(this,arguments))),g(c);var f=d.length?d.join(""):null;return d=[],f}function f(a){return c(a).join(",")}function i(a){var b=l(a[0]),c=0,d=a.length;while(++c0){d.push("M");while(++h0){d.push("M");while(++kd&&(d=a),fe&&(e=f)}),[[b,c],[d,e]]};var fl={Feature:fm,FeatureCollection:fn,GeometryCollection:fo,LineString:fp,MultiLineString:fq,MultiPoint:fp,MultiPolygon:fr,Point:fs,Polygon:ft};d3.geo.circle=function(){function e(){}function f(a){return d.distance(a)=k*k+l*l?d[f].index=-1:(d[m].index=-1,o=d[f].angle,m=f,n=g)):(o=d[f].angle,m=f,n=g);e.push(h);for(f=0,g=0;f<2;++g)d[g].index!==-1&&(e.push(d[g].index),f++);p=e.length;for(;g=0?(c=a.ep.r,d=a.ep.l):(c=a.ep.l,d=a.ep.r),a.a===1?(g=c?c.y:-1e6,e=a.c-a.b*g,h=d?d.y:1e6,f=a.c-a.b*h):(e=c?c.x:-1e6,g=a.c-a.a*e,f=d?d.x:1e6,h=a.c-a.a*f);var i=[e,g],j=[f,h];b[a.region.l.index].push(i,j),b[a.region.r.index].push(i,j)}),b.map(function(b,c){var d=a[c][0],e=a[c][1];return b.forEach(function(a){a.angle=Math.atan2(a[0]-d,a[1]-e)}),b.sort(function(a,b){return a.angle-b.angle}).filter(function(a,c){return!c||a.angle-b[c-1].angle>1e-10})})};var fE={l:"r",r:"l"};d3.geom.delaunay=function(a){var b=a.map(function(){return[]}),c=[];return fF(a,function(c){b[c.region.l.index].push(a[c.region.r.index])}),b.forEach(function(b,d){var e=a[d],f=e[0],g=e[1];b.forEach(function(a){a.angle=Math.atan2(a[0]-f,a[1]-g)}),b.sort(function(a,b){return a.angle-b.angle});for(var h=0,i=b.length-1;h=g,j=b.y>=h,l=(j<<1)+i;a.leaf=!1,a=a.nodes[l]||(a.nodes[l]=fG()),i?c=g:e=g,j?d=h:f=h,k(a,b,c,d,e,f)}var f,g=-1,h=a.length;h&&isNaN(a[0].x)&&(a=a.map(fI));if(arguments.length<5)if(arguments.length===3)e=d=c,c=b;else{b=c=Infinity,d=e=-Infinity;while(++gd&&(d=f.x),f.y>e&&(e=f.y);var i=d-b,j=e-c;i>j?e=c+i:d=b+j}var m=fG();return m.add=function(a){k(m,a,b,c,d,e)},m.visit=function(a){fH(a,m,b,c,d,e)},a.forEach(m.add),m},d3.time={};var fJ=Date,fK=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];fL.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){fM.setUTCDate.apply(this._,arguments)},setDay:function(){fM.setUTCDay.apply(this._,arguments)},setFullYear:function(){fM.setUTCFullYear.apply(this._,arguments)},setHours:function(){fM.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){fM.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){fM.setUTCMinutes.apply(this._,arguments)},setMonth:function(){fM.setUTCMonth.apply(this._,arguments)},setSeconds:function(){fM.setUTCSeconds.apply(this._,arguments)},setTime:function(){fM.setTime.apply(this._,arguments)}};var fM=Date.prototype,fN="%a %b %e %H:%M:%S %Y",fO="%m/%d/%y",fP="%H:%M:%S",fQ=fK,fR=fQ.map(fU),fS=["January","February","March","April","May","June","July","August","September","October","November","December"],fT=fS.map(fU);d3.time.format=function(a){function c(c){var d=[],e=-1,f=0,g,h;while(++e=12?"PM":"AM"},S:function(a){return fY(a.getSeconds())},U:function(a){return fY(d3.time.sundayOfYear(a))},w:function(a){return a.getDay()},W:function(a){return fY(d3.time.mondayOfYear(a))},x:d3.time.format(fO),X:d3.time.format(fP),y:function(a){return fY(a.getFullYear()%100)},Y:function(a){return f$(a.getFullYear()%1e4)},Z:gB,"%":function(a){return"%"}},gh={a:gi,A:gj,b:gk,B:gl,c:gm,d:gt,e:gt,H:gu,I:gu,L:gx,m:gs,M:gv,p:gz,S:gw,x:gn,X:go,y:gq,Y:gp},gy=/^\s*\d+/,gA=d3.map({am:0,pm:1});d3.time.format.utc=function(a){function c(a){try{fJ=fL;var c=new fJ;return c._=a,b(c)}finally{fJ=Date}}var b=d3.time.format(a);return c.parse=function(a){try{fJ=fL;var c=b.parse(a);return c&&c._}finally{fJ=Date}},c.toString=b.toString,c};var gC=d3.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");d3.time.format.iso=Date.prototype.toISOString?gD:gC,gD.parse=function(a){var b=new Date(a);return isNaN(b)?null:b},gD.toString=gC.toString,d3.time.second=gE(function(a){return new fJ(Math.floor(a/1e3)*1e3)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*1e3)},function(a){return a.getSeconds()}),d3.time.seconds=d3.time.second.range,d3.time.seconds.utc=d3.time.second.utc.range,d3.time.minute=gE(function(a){return new fJ(Math.floor(a/6e4)*6e4)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*6e4)},function(a){return a.getMinutes()}),d3.time.minutes=d3.time.minute.range,d3.time.minutes.utc=d3.time.minute.utc.range,d3.time.hour=gE(function(a){var b=a.getTimezoneOffset()/60;return new fJ((Math.floor(a/36e5-b)+b)*36e5)},function(a,b){a.setTime(a.getTime()+Math.floor(b)*36e5)},function(a){return a.getHours()}),d3.time.hours=d3.time.hour.range,d3.time.hours.utc=d3.time.hour.utc.range,d3.time.day=gE(function(a){var b=new fJ(0,a.getMonth(),a.getDate());return b.setFullYear(a.getFullYear()),b},function(a,b){a.setDate(a.getDate()+b)},function(a){return a.getDate()-1}),d3.time.days=d3.time.day.range,d3.time.days.utc=d3.time.day.utc.range,d3.time.dayOfYear=function(a){var b=d3.time.year(a);return Math.floor((a-b-(a.getTimezoneOffset()-b.getTimezoneOffset())*6e4)/864e5)},fK.forEach(function(a,b){a=a.toLowerCase(),b=7-b;var c=d3.time[a]=gE(function(a){return(a=d3.time.day(a)).setDate(a.getDate()-(a.getDay()+b)%7),a},function(a,b){a.setDate(a.getDate()+Math.floor(b)*7)},function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)-(c!==b)});d3.time[a+"s"]=c.range,d3.time[a+"s"].utc=c.utc.range,d3.time[a+"OfYear"]=function(a){var c=d3.time.year(a).getDay();return Math.floor((d3.time.dayOfYear(a)+(c+b)%7)/7)}}),d3.time.week=d3.time.sunday,d3.time.weeks=d3.time.sunday.range,d3.time.weeks.utc=d3.time.sunday.utc.range,d3.time.weekOfYear=d3.time.sundayOfYear,d3.time.month=gE(function(a){return a=d3.time.day(a),a.setDate(1),a},function(a,b){a.setMonth(a.getMonth()+b)},function(a){return a.getMonth()}),d3.time.months=d3.time.month.range,d3.time.months.utc=d3.time.month.utc.range,d3.time.year=gE(function(a){return a=d3.time.day(a),a.setMonth(0,1),a},function(a,b){a.setFullYear(a.getFullYear()+b)},function(a){return a.getFullYear()}),d3.time.years=d3.time.year.range,d3.time.years.utc=d3.time.year.utc.range;var gM=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],gN=[[d3.time.second,1],[d3.time.second,5],[d3.time.second,15],[d3.time.second,30],[d3.time.minute,1],[d3.time.minute,5],[d3.time.minute,15],[d3.time.minute,30],[d3.time.hour,1],[d3.time.hour,3],[d3.time.hour,6],[d3.time.hour,12],[d3.time.day,1],[d3.time.day,2],[d3.time.week,1],[d3.time.month,1],[d3.time.month,3],[d3.time.year,1]],gO=[[d3.time.format("%Y"),function(a){return!0}],[d3.time.format("%B"),function(a){return a.getMonth()}],[d3.time.format("%b %d"),function(a){return a.getDate()!=1}],[d3.time.format("%a %d"),function(a){return a.getDay()&&a.getDate()!=1}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]],gP=d3.scale.linear(),gQ=gJ(gO);gN.year=function(a,b){return gP.domain(a.map(gL)).ticks(b).map(gK)},d3.time.scale=function(){return gG(d3.scale.linear(),gN,gQ)};var gR=gN.map(function(a){return[a[0].utc,a[1]]}),gS=[[d3.time.format.utc("%Y"),function(a){return!0}],[d3.time.format.utc("%B"),function(a){return a.getUTCMonth()}],[d3.time.format.utc("%b %d"),function(a){return a.getUTCDate()!=1}],[d3.time.format.utc("%a %d"),function(a){return a.getUTCDay()&&a.getUTCDate()!=1}],[d3.time.format.utc("%I %p"),function(a){return a.getUTCHours()}],[d3.time.format.utc("%I:%M"),function(a){return a.getUTCMinutes()}],[d3.time.format.utc(":%S"),function(a){return a.getUTCSeconds()}],[d3.time.format.utc(".%L"),function(a){return a.getUTCMilliseconds()}]],gT=gJ(gS);gR.year=function(a,b){return gP.domain(a.map(gV)).ticks(b).map(gU)},d3.time.scale.utc=function(){return gG(d3.scale.linear(),gR,gT)}})(); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/d3.v3.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/d3.v3.min.js deleted file mode 100755 index 9b153cd780..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/d3.v3.min.js +++ /dev/null @@ -1,4 +0,0 @@ -d3=function(){function t(t){return t.target}function n(t){return t.source}function e(t,n){try{for(var e in n)Object.defineProperty(t.prototype,e,{value:n[e],enumerable:!1})}catch(r){t.prototype=n}}function r(t){for(var n=-1,e=t.length,r=[];e>++n;)r.push(t[n]);return r}function u(t){return Array.prototype.slice.call(t)}function i(){}function a(t){return t}function o(){return!0}function c(t){return"function"==typeof t?t:function(){return t}}function l(t,n,e){return function(){var r=e.apply(n,arguments);return arguments.length?t:r}}function f(t){return null!=t&&!isNaN(t)}function s(t){return t.length}function h(t){return t.trim().replace(/\s+/g," ")}function g(t){for(var n=1;t*n%1;)n*=10;return n}function p(t){return 1===t.length?function(n,e){t(null==n?e:null)}:t}function d(t){return t.responseText}function m(t){return JSON.parse(t.responseText)}function v(t){var n=Di.createRange();return n.selectNode(Di.body),n.createContextualFragment(t.responseText)}function y(t){return t.responseXML}function M(){}function b(t){function n(){for(var n,r=e,u=-1,i=r.length;i>++u;)(n=r[u].on)&&n.apply(this,arguments);return t}var e=[],r=new i;return n.on=function(n,u){var i,a=r.get(n);return 2>arguments.length?a&&a.on:(a&&(a.on=null,e=e.slice(0,i=e.indexOf(a)).concat(e.slice(i+1)),r.remove(n)),u&&e.push(r.set(n,{on:u})),t)},n}function x(t,n){return n-(t?Math.ceil(Math.log(t)/Math.LN10):1)}function _(t){return t+""}function w(t,n){var e=Math.pow(10,3*Math.abs(8-n));return{scale:n>8?function(t){return t/e}:function(t){return t*e},symbol:t}}function S(t){return function(n){return 0>=n?0:n>=1?1:t(n)}}function k(t){return function(n){return 1-t(1-n)}}function E(t){return function(n){return.5*(.5>n?t(2*n):2-t(2-2*n))}}function A(t){return t*t}function N(t){return t*t*t}function T(t){if(0>=t)return 0;if(t>=1)return 1;var n=t*t,e=n*t;return 4*(.5>t?e:3*(t-n)+e-.75)}function q(t){return function(n){return Math.pow(n,t)}}function C(t){return 1-Math.cos(t*Ni/2)}function z(t){return Math.pow(2,10*(t-1))}function D(t){return 1-Math.sqrt(1-t*t)}function L(t,n){var e;return 2>arguments.length&&(n=.45),arguments.length?e=n/(2*Ni)*Math.asin(1/t):(t=1,e=n/4),function(r){return 1+t*Math.pow(2,10*-r)*Math.sin(2*(r-e)*Ni/n)}}function F(t){return t||(t=1.70158),function(n){return n*n*((t+1)*n-t)}}function H(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}function j(){qi.event.stopPropagation(),qi.event.preventDefault()}function P(){for(var t,n=qi.event;t=n.sourceEvent;)n=t;return n}function R(t){for(var n=new M,e=0,r=arguments.length;r>++e;)n[arguments[e]]=b(n);return n.of=function(e,r){return function(u){try{var i=u.sourceEvent=qi.event;u.target=t,qi.event=u,n[u.type].apply(e,r)}finally{qi.event=i}}},n}function O(t){var n=[t.a,t.b],e=[t.c,t.d],r=U(n),u=Y(n,e),i=U(I(e,n,-u))||0;n[0]*e[1]t?"0"+Math.max(0,t).toString(16):Math.min(255,t).toString(16)}function K(t,n,e){var r,u,i,a=0,o=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(t))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return n(nn(u[0]),nn(u[1]),nn(u[2]))}return(i=aa.get(t))?n(i.r,i.g,i.b):(null!=t&&"#"===t.charAt(0)&&(4===t.length?(a=t.charAt(1),a+=a,o=t.charAt(2),o+=o,c=t.charAt(3),c+=c):7===t.length&&(a=t.substring(1,3),o=t.substring(3,5),c=t.substring(5,7)),a=parseInt(a,16),o=parseInt(o,16),c=parseInt(c,16)),n(a,o,c))}function W(t,n,e){var r,u,i=Math.min(t/=255,n/=255,e/=255),a=Math.max(t,n,e),o=a-i,c=(a+i)/2;return o?(u=.5>c?o/(a+i):o/(2-a-i),r=t==a?(n-e)/o+(e>n?6:0):n==a?(e-t)/o+2:(t-n)/o+4,r*=60):u=r=0,en(r,u,c)}function Q(t,n,e){t=tn(t),n=tn(n),e=tn(e);var r=pn((.4124564*t+.3575761*n+.1804375*e)/fa),u=pn((.2126729*t+.7151522*n+.072175*e)/sa),i=pn((.0193339*t+.119192*n+.9503041*e)/ha);return ln(116*u-16,500*(r-u),200*(u-i))}function tn(t){return.04045>=(t/=255)?t/12.92:Math.pow((t+.055)/1.055,2.4)}function nn(t){var n=parseFloat(t);return"%"===t.charAt(t.length-1)?Math.round(2.55*n):n}function en(t,n,e){return new rn(t,n,e)}function rn(t,n,e){this.h=t,this.s=n,this.l=e}function un(t,n,e){function r(t){return t>360?t-=360:0>t&&(t+=360),60>t?i+(a-i)*t/60:180>t?a:240>t?i+(a-i)*(240-t)/60:i}function u(t){return Math.round(255*r(t))}var i,a;return t%=360,0>t&&(t+=360),n=0>n?0:n>1?1:n,e=0>e?0:e>1?1:e,a=.5>=e?e*(1+n):e+n-e*n,i=2*e-a,$(u(t+120),u(t),u(t-120))}function an(t,n,e){return new on(t,n,e)}function on(t,n,e){this.h=t,this.c=n,this.l=e}function cn(t,n,e){return ln(e,Math.cos(t*=Ci)*n,Math.sin(t)*n)}function ln(t,n,e){return new fn(t,n,e)}function fn(t,n,e){this.l=t,this.a=n,this.b=e}function sn(t,n,e){var r=(t+16)/116,u=r+n/500,i=r-e/200;return u=gn(u)*fa,r=gn(r)*sa,i=gn(i)*ha,$(dn(3.2404542*u-1.5371385*r-.4985314*i),dn(-.969266*u+1.8760108*r+.041556*i),dn(.0556434*u-.2040259*r+1.0572252*i))}function hn(t,n,e){return an(180*(Math.atan2(e,n)/Ni),Math.sqrt(n*n+e*e),t)}function gn(t){return t>.206893034?t*t*t:(t-4/29)/7.787037}function pn(t){return t>.008856?Math.pow(t,1/3):7.787037*t+4/29}function dn(t){return Math.round(255*(.00304>=t?12.92*t:1.055*Math.pow(t,1/2.4)-.055))}function mn(t){return Ii(t,Ma),t}function vn(t){return function(){return pa(t,this)}}function yn(t){return function(){return da(t,this)}}function Mn(t,n){function e(){this.removeAttribute(t)}function r(){this.removeAttributeNS(t.space,t.local)}function u(){this.setAttribute(t,n)}function i(){this.setAttributeNS(t.space,t.local,n)}function a(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}function o(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}return t=qi.ns.qualify(t),null==n?t.local?r:e:"function"==typeof n?t.local?o:a:t.local?i:u}function bn(t){return RegExp("(?:^|\\s+)"+qi.requote(t)+"(?:\\s+|$)","g")}function xn(t,n){function e(){for(var e=-1;u>++e;)t[e](this,n)}function r(){for(var e=-1,r=n.apply(this,arguments);u>++e;)t[e](this,r)}t=t.trim().split(/\s+/).map(_n);var u=t.length;return"function"==typeof n?r:e}function _n(t){var n=bn(t);return function(e,r){if(u=e.classList)return r?u.add(t):u.remove(t);var u=e.className,i=null!=u.baseVal,a=i?u.baseVal:u;r?(n.lastIndex=0,n.test(a)||(a=h(a+" "+t),i?u.baseVal=a:e.className=a)):a&&(a=h(a.replace(n," ")),i?u.baseVal=a:e.className=a)}}function wn(t,n,e){function r(){this.style.removeProperty(t)}function u(){this.style.setProperty(t,n,e)}function i(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}return null==n?r:"function"==typeof n?i:u}function Sn(t,n){function e(){delete this[t]}function r(){this[t]=n}function u(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}return null==n?e:"function"==typeof n?u:r}function kn(t){return{__data__:t}}function En(t){return function(){return ya(this,t)}}function An(t){return arguments.length||(t=qi.ascending),function(n,e){return!n-!e||t(n.__data__,e.__data__)}}function Nn(t,n,e){function r(){var n=this[i];n&&(this.removeEventListener(t,n,n.$),delete this[i])}function u(){function u(t){var e=qi.event;qi.event=t,o[0]=a.__data__;try{n.apply(a,o)}finally{qi.event=e}}var a=this,o=Yi(arguments);r.call(this),this.addEventListener(t,this[i]=u,u.$=e),u._=n}var i="__on"+t,a=t.indexOf(".");return a>0&&(t=t.substring(0,a)),n?u:r}function Tn(t,n){for(var e=0,r=t.length;r>e;e++)for(var u,i=t[e],a=0,o=i.length;o>a;a++)(u=i[a])&&n(u,a,e);return t}function qn(t){return Ii(t,xa),t}function Cn(t,n){return Ii(t,wa),t.id=n,t}function zn(t,n,e,r){var u=t.__transition__||(t.__transition__={active:0,count:0}),a=u[e];if(!a){var o=r.time;return a=u[e]={tween:new i,event:qi.dispatch("start","end"),time:o,ease:r.ease,delay:r.delay,duration:r.duration},++u.count,qi.timer(function(r){function i(r){return u.active>e?l():(u.active=e,h.start.call(t,f,n),a.tween.forEach(function(e,r){(r=r.call(t,f,n))&&d.push(r)}),c(r)||qi.timer(c,0,o),1)}function c(r){if(u.active!==e)return l();for(var i=(r-g)/p,a=s(i),o=d.length;o>0;)d[--o].call(t,a);return i>=1?(l(),h.end.call(t,f,n),1):void 0}function l(){return--u.count?delete u[e]:delete t.__transition__,1}var f=t.__data__,s=a.ease,h=a.event,g=a.delay,p=a.duration,d=[];return r>=g?i(r):qi.timer(i,g,o),1},0,o),a}}function Dn(t){return null==t&&(t=""),function(){this.textContent=t}}function Ln(t,n,e,r){var u=t.id;return Tn(t,"function"==typeof e?function(t,i,a){t.__transition__[u].tween.set(n,r(e.call(t,t.__data__,i,a)))}:(e=r(e),function(t){t.__transition__[u].tween.set(n,e)}))}function Fn(){for(var t,n=Date.now(),e=qa;e;)t=n-e.then,t>=e.delay&&(e.flush=e.callback(t)),e=e.next;var r=Hn()-n;r>24?(isFinite(r)&&(clearTimeout(Aa),Aa=setTimeout(Fn,r)),Ea=0):(Ea=1,Ca(Fn))}function Hn(){for(var t=null,n=qa,e=1/0;n;)n.flush?(delete Ta[n.callback.id],n=t?t.next=n.next:qa=n.next):(e=Math.min(e,n.then+n.delay),n=(t=n).next);return e}function jn(t,n){var e=t.ownerSVGElement||t;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>za&&(Li.scrollX||Li.scrollY)){e=qi.select(Di.body).append("svg").style("position","absolute").style("top",0).style("left",0);var u=e[0][0].getScreenCTM();za=!(u.f||u.e),e.remove()}return za?(r.x=n.pageX,r.y=n.pageY):(r.x=n.clientX,r.y=n.clientY),r=r.matrixTransform(t.getScreenCTM().inverse()),[r.x,r.y]}var i=t.getBoundingClientRect();return[n.clientX-i.left-t.clientLeft,n.clientY-i.top-t.clientTop]}function Pn(){}function Rn(t){var n=t[0],e=t[t.length-1];return e>n?[n,e]:[e,n]}function On(t){return t.rangeExtent?t.rangeExtent():Rn(t.range())}function Yn(t,n){var e,r=0,u=t.length-1,i=t[r],a=t[u];return i>a&&(e=r,r=u,u=e,e=i,i=a,a=e),(n=n(a-i))&&(t[r]=n.floor(i),t[u]=n.ceil(a)),t}function Un(){return Math}function In(t,n,e,r){function u(){var u=Math.min(t.length,n.length)>2?Gn:Jn,c=r?Z:X;return a=u(t,n,c,e),o=u(n,t,c,qi.interpolate),i}function i(t){return a(t)}var a,o;return i.invert=function(t){return o(t)},i.domain=function(n){return arguments.length?(t=n.map(Number),u()):t},i.range=function(t){return arguments.length?(n=t,u()):n},i.rangeRound=function(t){return i.range(t).interpolate(qi.interpolateRound)},i.clamp=function(t){return arguments.length?(r=t,u()):r},i.interpolate=function(t){return arguments.length?(e=t,u()):e},i.ticks=function(n){return Bn(t,n)},i.tickFormat=function(n){return $n(t,n)},i.nice=function(){return Yn(t,Xn),u()},i.copy=function(){return In(t,n,e,r)},u()}function Vn(t,n){return qi.rebind(t,n,"range","rangeRound","interpolate","clamp")}function Xn(t){return t=Math.pow(10,Math.round(Math.log(t)/Math.LN10)-1),t&&{floor:function(n){return Math.floor(n/t)*t},ceil:function(n){return Math.ceil(n/t)*t}}}function Zn(t,n){var e=Rn(t),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/n)/Math.LN10)),i=n/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Bn(t,n){return qi.range.apply(qi,Zn(t,n))}function $n(t,n){return qi.format(",."+Math.max(0,-Math.floor(Math.log(Zn(t,n)[2])/Math.LN10+.01))+"f")}function Jn(t,n,e,r){var u=e(t[0],t[1]),i=r(n[0],n[1]);return function(t){return i(u(t))}}function Gn(t,n,e,r){var u=[],i=[],a=0,o=Math.min(t.length,n.length)-1;for(t[o]=++a;)u.push(e(t[a-1],t[a])),i.push(r(n[a-1],n[a]));return function(n){var e=qi.bisect(t,n,1,o)-1;return i[e](u[e](n))}}function Kn(t,n){function e(e){return t(n(e))}var r=n.pow;return e.invert=function(n){return r(t.invert(n))},e.domain=function(u){return arguments.length?(n=0>u[0]?Qn:Wn,r=n.pow,t.domain(u.map(n)),e):t.domain().map(r)},e.nice=function(){return t.domain(Yn(t.domain(),Un)),e},e.ticks=function(){var e=Rn(t.domain()),u=[];if(e.every(isFinite)){var i=Math.floor(e[0]),a=Math.ceil(e[1]),o=r(e[0]),c=r(e[1]);if(n===Qn)for(u.push(r(i));a>i++;)for(var l=9;l>0;l--)u.push(r(i)*l);else{for(;a>i;i++)for(var l=1;10>l;l++)u.push(r(i)*l);u.push(r(i))}for(i=0;o>u[i];i++);for(a=u.length;u[a-1]>c;a--);u=u.slice(i,a)}return u},e.tickFormat=function(t,u){if(2>arguments.length&&(u=Da),!arguments.length)return u;var i,a=Math.max(.1,t/e.ticks().length),o=n===Qn?(i=-1e-12,Math.floor):(i=1e-12,Math.ceil);return function(t){return a>=t/r(o(n(t)+i))?u(t):""}},e.copy=function(){return Kn(t.copy(),n)},Vn(e,t)}function Wn(t){return Math.log(0>t?0:t)/Math.LN10}function Qn(t){return-Math.log(t>0?0:-t)/Math.LN10}function te(t,n){function e(n){return t(r(n))}var r=ne(n),u=ne(1/n);return e.invert=function(n){return u(t.invert(n))},e.domain=function(n){return arguments.length?(t.domain(n.map(r)),e):t.domain().map(u)},e.ticks=function(t){return Bn(e.domain(),t)},e.tickFormat=function(t){return $n(e.domain(),t)},e.nice=function(){return e.domain(Yn(e.domain(),Xn))},e.exponent=function(t){if(!arguments.length)return n;var i=e.domain();return r=ne(n=t),u=ne(1/n),e.domain(i)},e.copy=function(){return te(t.copy(),n)},Vn(e,t)}function ne(t){return function(n){return 0>n?-Math.pow(-n,t):Math.pow(n,t)}}function ee(t,n){function e(n){return a[((u.get(n)||u.set(n,t.push(n)))-1)%a.length]}function r(n,e){return qi.range(t.length).map(function(t){return n+e*t})}var u,a,o;return e.domain=function(r){if(!arguments.length)return t;t=[],u=new i;for(var a,o=-1,c=r.length;c>++o;)u.has(a=r[o])||u.set(a,t.push(a));return e[n.t].apply(e,n.a)},e.range=function(t){return arguments.length?(a=t,o=0,n={t:"range",a:arguments},e):a},e.rangePoints=function(u,i){2>arguments.length&&(i=0);var c=u[0],l=u[1],f=(l-c)/(Math.max(1,t.length-1)+i);return a=r(2>t.length?(c+l)/2:c+f*i/2,f),o=0,n={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){2>arguments.length&&(i=0),3>arguments.length&&(c=i);var l=u[1]arguments.length&&(i=0),3>arguments.length&&(c=i);var l=u[1]++e;)u[e-1]=qi.quantile(t,e/i);return r}function r(t){return isNaN(t=+t)?0/0:n[qi.bisect(u,t)]}var u;return r.domain=function(n){return arguments.length?(t=n.filter(function(t){return!isNaN(t)}).sort(qi.ascending),e()):t},r.range=function(t){return arguments.length?(n=t,e()):n},r.quantiles=function(){return u},r.copy=function(){return re(t,n)},e()}function ue(t,n,e){function r(n){return e[Math.max(0,Math.min(a,Math.floor(i*(n-t))))]}function u(){return i=e.length/(n-t),a=e.length-1,r}var i,a;return r.domain=function(e){return arguments.length?(t=+e[0],n=+e[e.length-1],u()):[t,n]},r.range=function(t){return arguments.length?(e=t,u()):e},r.copy=function(){return ue(t,n,e)},u()}function ie(t,n){function e(e){return n[qi.bisect(t,e)]}return e.domain=function(n){return arguments.length?(t=n,e):t},e.range=function(t){return arguments.length?(n=t,e):n},e.copy=function(){return ie(t,n)},e}function ae(t){function n(t){return+t}return n.invert=n,n.domain=n.range=function(e){return arguments.length?(t=e.map(n),n):t},n.ticks=function(n){return Bn(t,n)},n.tickFormat=function(n){return $n(t,n)},n.copy=function(){return ae(t)},n}function oe(t){return t.innerRadius}function ce(t){return t.outerRadius}function le(t){return t.startAngle}function fe(t){return t.endAngle}function se(t){function n(n){function a(){f.push("M",i(t(s),l))}for(var o,f=[],s=[],h=-1,g=n.length,p=c(e),d=c(r);g>++h;)u.call(this,o=n[h],h)?s.push([+p.call(this,o,h),+d.call(this,o,h)]):s.length&&(a(),s=[]);return s.length&&a(),f.length?f.join(""):null}var e=he,r=ge,u=o,i=pe,a=i.key,l=.7;return n.x=function(t){return arguments.length?(e=t,n):e},n.y=function(t){return arguments.length?(r=t,n):r},n.defined=function(t){return arguments.length?(u=t,n):u},n.interpolate=function(t){return arguments.length?(a="function"==typeof t?i=t:(i=Oa.get(t)||pe).key,n):a},n.tension=function(t){return arguments.length?(l=t,n):l},n}function he(t){return t[0]}function ge(t){return t[1]}function pe(t){return t.join("L")}function de(t){return pe(t)+"Z"}function me(t){for(var n=0,e=t.length,r=t[0],u=[r[0],",",r[1]];e>++n;)u.push("V",(r=t[n])[1],"H",r[0]);return u.join("")}function ve(t){for(var n=0,e=t.length,r=t[0],u=[r[0],",",r[1]];e>++n;)u.push("H",(r=t[n])[0],"V",r[1]);return u.join("")}function ye(t,n){return 4>t.length?pe(t):t[1]+xe(t.slice(1,t.length-1),_e(t,n))}function Me(t,n){return 3>t.length?pe(t):t[0]+xe((t.push(t[0]),t),_e([t[t.length-2]].concat(t,[t[1]]),n))}function be(t,n){return 3>t.length?pe(t):t[0]+xe(t,_e(t,n))}function xe(t,n){if(1>n.length||t.length!=n.length&&t.length!=n.length+2)return pe(t);var e=t.length!=n.length,r="",u=t[0],i=t[1],a=n[0],o=a,c=1;if(e&&(r+="Q"+(i[0]-2*a[0]/3)+","+(i[1]-2*a[1]/3)+","+i[0]+","+i[1],u=t[1],c=2),n.length>1){o=n[1],i=t[c],c++,r+="C"+(u[0]+a[0])+","+(u[1]+a[1])+","+(i[0]-o[0])+","+(i[1]-o[1])+","+i[0]+","+i[1];for(var l=2;n.length>l;l++,c++)i=t[c],o=n[l],r+="S"+(i[0]-o[0])+","+(i[1]-o[1])+","+i[0]+","+i[1]}if(e){var f=t[c];r+="Q"+(i[0]+2*o[0]/3)+","+(i[1]+2*o[1]/3)+","+f[0]+","+f[1]}return r}function _e(t,n){for(var e,r=[],u=(1-n)/2,i=t[0],a=t[1],o=1,c=t.length;c>++o;)e=i,i=a,a=t[o],r.push([u*(a[0]-e[0]),u*(a[1]-e[1])]);return r}function we(t){if(3>t.length)return pe(t);var n=1,e=t.length,r=t[0],u=r[0],i=r[1],a=[u,u,u,(r=t[1])[0]],o=[i,i,i,r[1]],c=[u,",",i];for(Ne(c,a,o);e>++n;)r=t[n],a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Ne(c,a,o);for(n=-1;2>++n;)a.shift(),a.push(r[0]),o.shift(),o.push(r[1]),Ne(c,a,o);return c.join("")}function Se(t){if(4>t.length)return pe(t);for(var n,e=[],r=-1,u=t.length,i=[0],a=[0];3>++r;)n=t[r],i.push(n[0]),a.push(n[1]);for(e.push(Ae(Ia,i)+","+Ae(Ia,a)),--r;u>++r;)n=t[r],i.shift(),i.push(n[0]),a.shift(),a.push(n[1]),Ne(e,i,a);return e.join("")}function ke(t){for(var n,e,r=-1,u=t.length,i=u+4,a=[],o=[];4>++r;)e=t[r%u],a.push(e[0]),o.push(e[1]);for(n=[Ae(Ia,a),",",Ae(Ia,o)],--r;i>++r;)e=t[r%u],a.shift(),a.push(e[0]),o.shift(),o.push(e[1]),Ne(n,a,o);return n.join("")}function Ee(t,n){var e=t.length-1;if(e)for(var r,u,i=t[0][0],a=t[0][1],o=t[e][0]-i,c=t[e][1]-a,l=-1;e>=++l;)r=t[l],u=l/e,r[0]=n*r[0]+(1-n)*(i+u*o),r[1]=n*r[1]+(1-n)*(a+u*c);return we(t)}function Ae(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]}function Ne(t,n,e){t.push("C",Ae(Ya,n),",",Ae(Ya,e),",",Ae(Ua,n),",",Ae(Ua,e),",",Ae(Ia,n),",",Ae(Ia,e))}function Te(t,n){return(n[1]-t[1])/(n[0]-t[0])}function qe(t){for(var n=0,e=t.length-1,r=[],u=t[0],i=t[1],a=r[0]=Te(u,i);e>++n;)r[n]=(a+(a=Te(u=i,i=t[n+1])))/2;return r[n]=a,r}function Ce(t){for(var n,e,r,u,i=[],a=qe(t),o=-1,c=t.length-1;c>++o;)n=Te(t[o],t[o+1]),1e-6>Math.abs(n)?a[o]=a[o+1]=0:(e=a[o]/n,r=a[o+1]/n,u=e*e+r*r,u>9&&(u=3*n/Math.sqrt(u),a[o]=u*e,a[o+1]=u*r));for(o=-1;c>=++o;)u=(t[Math.min(c,o+1)][0]-t[Math.max(0,o-1)][0])/(6*(1+a[o]*a[o])),i.push([u||0,a[o]*u||0]);return i}function ze(t){return 3>t.length?pe(t):t[0]+xe(t,Ce(t))}function De(t){for(var n,e,r,u=-1,i=t.length;i>++u;)n=t[u],e=n[0],r=n[1]+Pa,n[0]=e*Math.cos(r),n[1]=e*Math.sin(r);return t}function Le(t){function n(n){function o(){m.push("M",l(t(y),g),h,s(t(v.reverse()),g),"Z")}for(var f,p,d,m=[],v=[],y=[],M=-1,b=n.length,x=c(e),_=c(u),w=e===r?function(){return p}:c(r),S=u===i?function(){return d}:c(i);b>++M;)a.call(this,f=n[M],M)?(v.push([p=+x.call(this,f,M),d=+_.call(this,f,M)]),y.push([+w.call(this,f,M),+S.call(this,f,M)])):v.length&&(o(),v=[],y=[]);return v.length&&o(),m.length?m.join(""):null}var e=he,r=he,u=0,i=ge,a=o,l=pe,f=l.key,s=l,h="L",g=.7;return n.x=function(t){return arguments.length?(e=r=t,n):r},n.x0=function(t){return arguments.length?(e=t,n):e},n.x1=function(t){return arguments.length?(r=t,n):r},n.y=function(t){return arguments.length?(u=i=t,n):i},n.y0=function(t){return arguments.length?(u=t,n):u},n.y1=function(t){return arguments.length?(i=t,n):i},n.defined=function(t){return arguments.length?(a=t,n):a},n.interpolate=function(t){return arguments.length?(f="function"==typeof t?l=t:(l=Oa.get(t)||pe).key,s=l.reverse||l,h=l.closed?"M":"L",n):f},n.tension=function(t){return arguments.length?(g=t,n):g},n}function Fe(t){return t.radius}function He(t){return[t.x,t.y]}function je(t){return function(){var n=t.apply(this,arguments),e=n[0],r=n[1]+Pa;return[e*Math.cos(r),e*Math.sin(r)]}}function Pe(){return 64}function Re(){return"circle"}function Oe(t){var n=Math.sqrt(t/Ni);return"M0,"+n+"A"+n+","+n+" 0 1,1 0,"+-n+"A"+n+","+n+" 0 1,1 0,"+n+"Z"}function Ye(t,n){t.attr("transform",function(t){return"translate("+n(t)+",0)"})}function Ue(t,n){t.attr("transform",function(t){return"translate(0,"+n(t)+")"})}function Ie(t,n,e){if(r=[],e&&n.length>1){for(var r,u,i,a=Rn(t.domain()),o=-1,c=n.length,l=(n[1]-n[0])/++e;c>++o;)for(u=e;--u>0;)(i=+n[o]-u*l)>=a[0]&&r.push(i);for(--o,u=0;e>++u&&(i=+n[o]+u*l)++c;)i=a[c],null!=i&&(Ke(i,n,e),t.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(t.point){t.leaf||(t.point.x+=Math.random()-.5,t.point.y+=Math.random()-.5);var l=n*e[t.point.index];t.charge+=t.pointCharge=l,r+=l*t.point.x,u+=l*t.point.y}t.cx=r/t.charge,t.cy=u/t.charge}function We(t){return t.x}function Qe(t){return t.y}function tr(t,n,e){t.y0=n,t.y=e}function nr(t){return qi.range(t.length)}function er(t){for(var n=-1,e=t[0].length,r=[];e>++n;)r[n]=0;return r}function rr(t){for(var n,e=1,r=0,u=t[0][1],i=t.length;i>e;++e)(n=t[e][1])>u&&(r=e,u=n);return r}function ur(t){return t.reduce(ir,0)}function ir(t,n){return t+n[1]}function ar(t,n){return or(t,Math.ceil(Math.log(n.length)/Math.LN2+1))}function or(t,n){for(var e=-1,r=+t[0],u=(t[1]-r)/n,i=[];n>=++e;)i[e]=u*e+r;return i}function cr(t){return[qi.min(t),qi.max(t)]}function lr(t,n){return qi.rebind(t,n,"sort","children","value"),t.nodes=t,t.links=gr,t}function fr(t){return t.children}function sr(t){return t.value}function hr(t,n){return n.value-t.value}function gr(t){return qi.merge(t.map(function(t){return(t.children||[]).map(function(n){return{source:t,target:n}})}))}function pr(t,n){return t.value-n.value}function dr(t,n){var e=t._pack_next;t._pack_next=n,n._pack_prev=t,n._pack_next=e,e._pack_prev=n}function mr(t,n){t._pack_next=n,n._pack_prev=t}function vr(t,n){var e=n.x-t.x,r=n.y-t.y,u=t.r+n.r;return u*u-e*e-r*r>.001}function yr(t){function n(t){f=Math.min(t.x-t.r,f),s=Math.max(t.x+t.r,s),h=Math.min(t.y-t.r,h),g=Math.max(t.y+t.r,g)}if((e=t.children)&&(l=e.length)){var e,r,u,i,a,o,c,l,f=1/0,s=-1/0,h=1/0,g=-1/0;if(e.forEach(Mr),r=e[0],r.x=-r.r,r.y=0,n(r),l>1&&(u=e[1],u.x=u.r,u.y=0,n(u),l>2))for(i=e[2],_r(r,u,i),n(i),dr(r,i),r._pack_prev=i,dr(i,u),u=r._pack_next,a=3;l>a;a++){_r(r,u,i=e[a]);var p=0,d=1,m=1;for(o=u._pack_next;o!==u;o=o._pack_next,d++)if(vr(o,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==o._pack_prev&&!vr(c,i);c=c._pack_prev,m++);p?(m>d||d==m&&u.ra;a++)i=e[a],i.x-=v,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));t.r=M,e.forEach(br)}}function Mr(t){t._pack_next=t._pack_prev=t}function br(t){delete t._pack_next,delete t._pack_prev}function xr(t,n,e,r){var u=t.children;if(t.x=n+=r*t.x,t.y=e+=r*t.y,t.r*=r,u)for(var i=-1,a=u.length;a>++i;)xr(u[i],n,e,r)}function _r(t,n,e){var r=t.r+e.r,u=n.x-t.x,i=n.y-t.y;if(r&&(u||i)){var a=n.r+e.r,o=u*u+i*i;a*=a,r*=r;var c=.5+(r-a)/(2*o),l=Math.sqrt(Math.max(0,2*a*(r+o)-(r-=o)*r-a*a))/(2*o);e.x=t.x+c*u+l*i,e.y=t.y+c*i-l*u}else e.x=t.x+r,e.y=t.y}function wr(t){return 1+qi.max(t,function(t){return t.y})}function Sr(t){return t.reduce(function(t,n){return t+n.x},0)/t.length}function kr(t){var n=t.children;return n&&n.length?kr(n[0]):t}function Er(t){var n,e=t.children;return e&&(n=e.length)?Er(e[n-1]):t}function Ar(t,n){return t.parent==n.parent?1:2}function Nr(t){var n=t.children;return n&&n.length?n[0]:t._tree.thread}function Tr(t){var n,e=t.children;return e&&(n=e.length)?e[n-1]:t._tree.thread}function qr(t,n){var e=t.children;if(e&&(u=e.length))for(var r,u,i=-1;u>++i;)n(r=qr(e[i],n),t)>0&&(t=r);return t}function Cr(t,n){return t.x-n.x}function zr(t,n){return n.x-t.x}function Dr(t,n){return t.depth-n.depth}function Lr(t,n){function e(t,r){var u=t.children;if(u&&(a=u.length))for(var i,a,o=null,c=-1;a>++c;)i=u[c],e(i,o),o=i;n(t,r)}e(t,null)}function Fr(t){for(var n,e=0,r=0,u=t.children,i=u.length;--i>=0;)n=u[i]._tree,n.prelim+=e,n.mod+=e,e+=n.shift+(r+=n.change)}function Hr(t,n,e){t=t._tree,n=n._tree;var r=e/(n.number-t.number);t.change+=r,n.change-=r,n.shift+=e,n.prelim+=e,n.mod+=e}function jr(t,n,e){return t._tree.ancestor.parent==n.parent?t._tree.ancestor:e}function Pr(t){return{x:t.x,y:t.y,dx:t.dx,dy:t.dy}}function Rr(t,n){var e=t.x+n[3],r=t.y+n[0],u=t.dx-n[1]-n[3],i=t.dy-n[0]-n[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Or(t,n){function e(t,e){return qi.xhr(t,n,e).response(r)}function r(t){return e.parse(t.responseText)}function u(n){return n.map(i).join(t)}function i(t){return a.test(t)?'"'+t.replace(/\"/g,'""')+'"':t}var a=RegExp('["'+t+"\n]"),o=t.charCodeAt(0);return e.parse=function(t){var n;return e.parseRows(t,function(t){return n?n(t):(n=Function("d","return {"+t.map(function(t,n){return JSON.stringify(t)+": d["+n+"]"}).join(",")+"}"),void 0)})},e.parseRows=function(t,n){function e(){if(f>=l)return a;if(u)return u=!1,i;var n=f;if(34===t.charCodeAt(n)){for(var e=n;l>e++;)if(34===t.charCodeAt(e)){if(34!==t.charCodeAt(e+1))break;++e}f=e+2;var r=t.charCodeAt(e+1);return 13===r?(u=!0,10===t.charCodeAt(e+2)&&++f):10===r&&(u=!0),t.substring(n+1,e).replace(/""/g,'"')}for(;l>f;){var r=t.charCodeAt(f++),c=1;if(10===r)u=!0;else if(13===r)u=!0,10===t.charCodeAt(f)&&(++f,++c);else if(r!==o)continue;return t.substring(n,f-c)}return t.substring(n)}for(var r,u,i={},a={},c=[],l=t.length,f=0,s=0;(r=e())!==a;){for(var h=[];r!==i&&r!==a;)h.push(r),r=e();(!n||(h=n(h,s++)))&&c.push(h)}return c},e.format=function(t){return t.map(u).join("\n")},e}function Yr(t,n){ao.hasOwnProperty(t.type)&&ao[t.type](t,n)}function Ur(t,n,e){var r,u=-1,i=t.length-e;for(n.lineStart();i>++u;)r=t[u],n.point(r[0],r[1]);n.lineEnd()}function Ir(t,n){var e=-1,r=t.length;for(n.polygonStart();r>++e;)Ur(t[e],n,1);n.polygonEnd()}function Vr(t){return[Math.atan2(t[1],t[0]),Math.asin(Math.max(-1,Math.min(1,t[2])))]}function Xr(t,n){return Ti>Math.abs(t[0]-n[0])&&Ti>Math.abs(t[1]-n[1])}function Zr(t){var n=t[0],e=t[1],r=Math.cos(e);return[r*Math.cos(n),r*Math.sin(n),Math.sin(e)]}function Br(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]}function $r(t,n){return[t[1]*n[2]-t[2]*n[1],t[2]*n[0]-t[0]*n[2],t[0]*n[1]-t[1]*n[0]]}function Jr(t,n){t[0]+=n[0],t[1]+=n[1],t[2]+=n[2]}function Gr(t,n){return[t[0]*n,t[1]*n,t[2]*n]}function Kr(t){var n=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=n,t[1]/=n,t[2]/=n}function Wr(t){function n(n){function r(e,r){e=t(e,r),n.point(e[0],e[1])}function i(){f=0/0,d.point=a,n.lineStart()}function a(r,i){var a=Zr([r,i]),o=t(r,i);e(f,s,l,h,g,p,f=o[0],s=o[1],l=r,h=a[0],g=a[1],p=a[2],u,n),n.point(f,s)}function o(){d.point=r,n.lineEnd()}function c(){var t,r,c,m,v,y,M;i(),d.point=function(n,e){a(t=n,r=e),c=f,m=s,v=h,y=g,M=p,d.point=a},d.lineEnd=function(){e(f,s,l,h,g,p,c,m,t,v,y,M,u,n),d.lineEnd=o,o()}}var l,f,s,h,g,p,d={point:r,lineStart:i,lineEnd:o,polygonStart:function(){n.polygonStart(),d.lineStart=c},polygonEnd:function(){n.polygonEnd(),d.lineStart=i}};return d}function e(n,u,i,a,o,c,l,f,s,h,g,p,d,m){var v=l-n,y=f-u,M=v*v+y*y;if(M>4*r&&d--){var b=a+h,x=o+g,_=c+p,w=Math.sqrt(b*b+x*x+_*_),S=Math.asin(_/=w),k=Ti>Math.abs(Math.abs(_)-1)?(i+s)/2:Math.atan2(x,b),E=t(k,S),A=E[0],N=E[1],T=A-n,q=N-u,C=y*T-v*q;(C*C/M>r||Math.abs((v*T+y*q)/M-.5)>.3)&&(e(n,u,i,a,o,c,A,N,k,b/=w,x/=w,_,d,m),m.point(A,N),e(A,N,k,b,x,_,l,f,s,h,g,p,d,m))}}var r=.5,u=16;return n.precision=function(t){return arguments.length?(u=(r=t*t)>0&&16,n):Math.sqrt(r)},n}function Qr(t,n){function e(t,n){var e=Math.sqrt(i-2*u*Math.sin(n))/u;return[e*Math.sin(t*=u),a-e*Math.cos(t)]}var r=Math.sin(t),u=(r+Math.sin(n))/2,i=1+r*(2*u-r),a=Math.sqrt(i)/u;return e.invert=function(t,n){var e=a-n;return[Math.atan2(t,e)/u,Math.asin((i-(t*t+e*e)*u*u)/(2*u))]},e}function tu(t){function n(t,n){r>t&&(r=t),t>i&&(i=t),u>n&&(u=n),n>a&&(a=n)}function e(){o.point=o.lineEnd=Pn}var r,u,i,a,o={point:n,lineStart:Pn,lineEnd:Pn,polygonStart:function(){o.lineEnd=e},polygonEnd:function(){o.point=n}};return function(n){return a=i=-(r=u=1/0),qi.geo.stream(n,t(o)),[[r,u],[i,a]]}}function nu(t,n){if(!lo){++fo,t*=Ci;var e=Math.cos(n*=Ci);so+=(e*Math.cos(t)-so)/fo,ho+=(e*Math.sin(t)-ho)/fo,go+=(Math.sin(n)-go)/fo}}function eu(){var t,n;lo=1,ru(),lo=2;var e=po.point;po.point=function(r,u){e(t=r,n=u)},po.lineEnd=function(){po.point(t,n),uu(),po.lineEnd=uu}}function ru(){function t(t,u){t*=Ci;var i=Math.cos(u*=Ci),a=i*Math.cos(t),o=i*Math.sin(t),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*o)*l+(l=r*a-n*c)*l+(l=n*o-e*a)*l),n*a+e*o+r*c);fo+=l,so+=l*(n+(n=a)),ho+=l*(e+(e=o)),go+=l*(r+(r=c))}var n,e,r;lo>1||(1>lo&&(lo=1,fo=so=ho=go=0),po.point=function(u,i){u*=Ci;var a=Math.cos(i*=Ci);n=a*Math.cos(u),e=a*Math.sin(u),r=Math.sin(i),po.point=t})}function uu(){po.point=nu}function iu(t,n){var e=Math.cos(t),r=Math.sin(t);return function(u,i,a,o){null!=u?(u=au(e,u),i=au(e,i),(a>0?i>u:u>i)&&(u+=2*a*Ni)):(u=t+2*a*Ni,i=t);for(var c,l=a*n,f=u;a>0?f>i:i>f;f-=l)o.point((c=Vr([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function au(t,n){var e=Zr(n);e[0]-=t,Kr(e);var r=Math.acos(Math.max(-1,Math.min(1,-e[1])));return((0>-e[2]?-r:r)+2*Math.PI-Ti)%(2*Math.PI)}function ou(t,n,e){return function(r){function u(n,e){t(n,e)&&r.point(n,e)}function i(t,n){m.point(t,n)}function a(){v.point=i,m.lineStart()}function o(){v.point=u,m.lineEnd()}function c(t,n){M.point(t,n),d.push([t,n])}function l(){M.lineStart(),d=[]}function f(){c(d[0][0],d[0][1]),M.lineEnd();var t,n=M.clean(),e=y.buffer(),u=e.length;if(!u)return p=!0,g+=gu(d,-1),d=null,void 0;if(d=null,1&n){t=e[0],h+=gu(t,1);var i,u=t.length-1,a=-1;for(r.lineStart();u>++a;)r.point((i=t[a])[0],i[1]);return r.lineEnd(),void 0}u>1&&2&n&&e.push(e.pop().concat(e.shift())),s.push(e.filter(su))}var s,h,g,p,d,m=n(r),v={point:u,lineStart:a,lineEnd:o,polygonStart:function(){v.point=c,v.lineStart=l,v.lineEnd=f,p=!1,g=h=0,s=[],r.polygonStart()},polygonEnd:function(){v.point=u,v.lineStart=a,v.lineEnd=o,s=qi.merge(s),s.length?cu(s,e,r):(-Ti>h||p&&-Ti>g)&&(r.lineStart(),e(null,null,1,r),r.lineEnd()),r.polygonEnd(),s=null},sphere:function(){r.polygonStart(),r.lineStart(),e(null,null,1,r),r.lineEnd(),r.polygonEnd()}},y=hu(),M=n(y);return v}}function cu(t,n,e){var r=[],u=[];if(t.forEach(function(t){var n=t.length;if(!(1>=n)){var e=t[0],i=t[n-1],a={point:e,points:t,other:null,visited:!1,entry:!0,subject:!0},o={point:e,points:[e],other:a,visited:!1,entry:!1,subject:!1}; -a.other=o,r.push(a),u.push(o),a={point:i,points:[i],other:null,visited:!1,entry:!1,subject:!0},o={point:i,points:[i],other:a,visited:!1,entry:!0,subject:!1},a.other=o,r.push(a),u.push(o)}}),u.sort(fu),lu(r),lu(u),r.length)for(var i,a,o,c=r[0];;){for(i=c;i.visited;)if((i=i.next)===c)return;a=i.points,e.lineStart();do{if(i.visited=i.other.visited=!0,i.entry){if(i.subject)for(var l=0;a.length>l;l++)e.point((o=a[l])[0],o[1]);else n(i.point,i.next.point,1,e);i=i.next}else{if(i.subject){a=i.prev.points;for(var l=a.length;--l>=0;)e.point((o=a[l])[0],o[1])}else n(i.point,i.prev.point,-1,e);i=i.prev}i=i.other,a=i.points}while(!i.visited);e.lineEnd()}}function lu(t){if(n=t.length){for(var n,e,r=0,u=t[0];n>++r;)u.next=e=t[r],e.prev=u,u=e;u.next=e=t[0],e.prev=u}}function fu(t,n){return(0>(t=t.point)[0]?t[1]-Ni/2-Ti:Ni/2-t[1])-(0>(n=n.point)[0]?n[1]-Ni/2-Ti:Ni/2-n[1])}function su(t){return t.length>1}function hu(){var t,n=[];return{lineStart:function(){n.push(t=[])},point:function(n,e){t.push([n,e])},lineEnd:Pn,buffer:function(){var e=n;return n=[],t=null,e}}}function gu(t,n){if(!(e=t.length))return 0;for(var e,r,u,i=0,a=0,o=t[0],c=o[0],l=o[1],f=Math.cos(l),s=Math.atan2(n*Math.sin(c)*f,Math.sin(l)),h=1-n*Math.cos(c)*f,g=s;e>++i;)o=t[i],f=Math.cos(l=o[1]),r=Math.atan2(n*Math.sin(c=o[0])*f,Math.sin(l)),u=1-n*Math.cos(c)*f,Ti>Math.abs(h-2)&&Ti>Math.abs(u-2)||(Ti>Math.abs(u)||Ti>Math.abs(h)||(Ti>Math.abs(Math.abs(r-s)-Ni)?u+h>2&&(a+=4*(r-s)):a+=Ti>Math.abs(h-2)?4*(r-g):((3*Ni+r-s)%(2*Ni)-Ni)*(h+u)),g=s,s=r,h=u);return a}function pu(t){var n,e=0/0,r=0/0,u=0/0;return{lineStart:function(){t.lineStart(),n=1},point:function(i,a){var o=i>0?Ni:-Ni,c=Math.abs(i-e);Ti>Math.abs(c-Ni)?(t.point(e,r=(r+a)/2>0?Ni/2:-Ni/2),t.point(u,r),t.lineEnd(),t.lineStart(),t.point(o,r),t.point(i,r),n=0):u!==o&&c>=Ni&&(Ti>Math.abs(e-u)&&(e-=u*Ti),Ti>Math.abs(i-o)&&(i-=o*Ti),r=du(e,r,i,a),t.point(u,r),t.lineEnd(),t.lineStart(),t.point(o,r),n=0),t.point(e=i,r=a),u=o},lineEnd:function(){t.lineEnd(),e=r=0/0},clean:function(){return 2-n}}}function du(t,n,e,r){var u,i,a=Math.sin(t-e);return Math.abs(a)>Ti?Math.atan((Math.sin(n)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(n))*Math.sin(t))/(u*i*a)):(n+r)/2}function mu(t,n,e,r){var u;if(null==t)u=e*Ni/2,r.point(-Ni,u),r.point(0,u),r.point(Ni,u),r.point(Ni,0),r.point(Ni,-u),r.point(0,-u),r.point(-Ni,-u),r.point(-Ni,0),r.point(-Ni,u);else if(Math.abs(t[0]-n[0])>Ti){var i=(t[0]i}function e(t){var e,u,i,a;return{lineStart:function(){i=u=!1,a=1},point:function(o,c){var l,f=[o,c],s=n(o,c);!e&&(i=u=s)&&t.lineStart(),s!==u&&(l=r(e,f),(Xr(e,l)||Xr(f,l))&&(f[0]+=Ti,f[1]+=Ti,s=n(f[0],f[1]))),s!==u&&(a=0,(u=s)?(t.lineStart(),l=r(f,e),t.point(l[0],l[1])):(l=r(e,f),t.point(l[0],l[1]),t.lineEnd()),e=l),!s||e&&Xr(e,f)||t.point(f[0],f[1]),e=f},lineEnd:function(){u&&t.lineEnd(),e=null},clean:function(){return a|(i&&u)<<1}}}function r(t,n){var e=Zr(t,0),r=Zr(n,0),u=[1,0,0],a=$r(e,r),o=Br(a,a),c=a[0],l=o-c*c;if(!l)return t;var f=i*o/l,s=-i*c/l,h=$r(u,a),g=Gr(u,f),p=Gr(a,s);Jr(g,p);var d=h,m=Br(g,d),v=Br(d,d),y=Math.sqrt(m*m-v*(Br(g,g)-1)),M=Gr(d,(-m-y)/v);return Jr(M,g),Vr(M)}var u=t*Ci,i=Math.cos(u),a=iu(u,6*Ci);return ou(n,e,a)}function yu(t,n){function e(e,r){return e=t(e,r),n(e[0],e[1])}return t.invert&&n.invert&&(e.invert=function(e,r){return e=n.invert(e,r),e&&t.invert(e[0],e[1])}),e}function Mu(t,n){return[t,n]}function bu(t,n,e){var r=qi.range(t,n-Ti,e).concat(n);return function(t){return r.map(function(n){return[t,n]})}}function xu(t,n,e){var r=qi.range(t,n-Ti,e).concat(n);return function(t){return r.map(function(n){return[n,t]})}}function _u(t,n,e,r){function u(t){var n=Math.sin(t*=g)*p,e=Math.sin(g-t)*p,r=e*l+n*s,u=e*f+n*h,i=e*a+n*c;return[Math.atan2(u,r)/Ci,Math.atan2(i,Math.sqrt(r*r+u*u))/Ci]}var i=Math.cos(n),a=Math.sin(n),o=Math.cos(r),c=Math.sin(r),l=i*Math.cos(t),f=i*Math.sin(t),s=o*Math.cos(e),h=o*Math.sin(e),g=Math.acos(Math.max(-1,Math.min(1,a*c+i*o*Math.cos(e-t)))),p=1/Math.sin(g);return u.distance=g,u}function wu(t,n){return[t/(2*Ni),Math.max(-.5,Math.min(.5,Math.log(Math.tan(Ni/4+n/2))/(2*Ni)))]}function Su(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}function ku(t){var n=Wr(function(n,e){return t([n*zi,e*zi])});return function(t){return t=n(t),{point:function(n,e){t.point(n*Ci,e*Ci)},sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}}function Eu(){function t(t,n){a.push("M",t,",",n,i)}function n(t,n){a.push("M",t,",",n),o.point=e}function e(t,n){a.push("L",t,",",n)}function r(){o.point=t}function u(){a.push("Z")}var i=Su(4.5),a=[],o={point:t,lineStart:function(){o.point=n},lineEnd:r,polygonStart:function(){o.lineEnd=u},polygonEnd:function(){o.lineEnd=r,o.point=t},pointRadius:function(t){return i=Su(t),o},result:function(){if(a.length){var t=a.join("");return a=[],t}}};return o}function Au(t){function n(n,e){t.moveTo(n,e),t.arc(n,e,a,0,2*Ni)}function e(n,e){t.moveTo(n,e),o.point=r}function r(n,e){t.lineTo(n,e)}function u(){o.point=n}function i(){t.closePath()}var a=4.5,o={point:n,lineStart:function(){o.point=e},lineEnd:u,polygonStart:function(){o.lineEnd=i},polygonEnd:function(){o.lineEnd=u,o.point=n},pointRadius:function(t){return a=t,o},result:Pn};return o}function Nu(){function t(t,n){bo+=u*t-r*n,r=t,u=n}var n,e,r,u;xo.point=function(i,a){xo.point=t,n=r=i,e=u=a},xo.lineEnd=function(){t(n,e)}}function Tu(t,n){lo||(so+=t,ho+=n,++go)}function qu(){function t(t,r){var u=t-n,i=r-e,a=Math.sqrt(u*u+i*i);so+=a*(n+t)/2,ho+=a*(e+r)/2,go+=a,n=t,e=r}var n,e;if(1!==lo){if(!(1>lo))return;lo=1,so=ho=go=0}_o.point=function(r,u){_o.point=t,n=r,e=u}}function Cu(){_o.point=Tu}function zu(){function t(t,n){var e=u*t-r*n;so+=e*(r+t),ho+=e*(u+n),go+=3*e,r=t,u=n}var n,e,r,u;2>lo&&(lo=2,so=ho=go=0),_o.point=function(i,a){_o.point=t,n=r=i,e=u=a},_o.lineEnd=function(){t(n,e)}}function Du(){function t(t,n){t*=Ci,n=n*Ci/2+Ni/4;var e=t-r,a=Math.cos(n),o=Math.sin(n),c=i*o,l=So,f=ko,s=u*a+c*Math.cos(e),h=c*Math.sin(e);So=l*s-f*h,ko=f*s+l*h,r=t,u=a,i=o}var n,e,r,u,i;Eo.point=function(a,o){Eo.point=t,r=(n=a)*Ci,u=Math.cos(o=(e=o)*Ci/2+Ni/4),i=Math.sin(o)},Eo.lineEnd=function(){t(n,e)}}function Lu(t){return Fu(function(){return t})()}function Fu(t){function n(t){return t=a(t[0]*Ci,t[1]*Ci),[t[0]*f+o,c-t[1]*f]}function e(t){return t=a.invert((t[0]-o)/f,(c-t[1])/f),t&&[t[0]*zi,t[1]*zi]}function r(){a=yu(i=ju(d,m,v),u);var t=u(g,p);return o=s-t[0]*f,c=h+t[1]*f,n}var u,i,a,o,c,l=Wr(function(t,n){return t=u(t,n),[t[0]*f+o,c-t[1]*f]}),f=150,s=480,h=250,g=0,p=0,d=0,m=0,v=0,y=mo,M=null;return n.stream=function(t){return Hu(i,y(l(t)))},n.clipAngle=function(t){return arguments.length?(y=null==t?(M=t,mo):vu(M=+t),n):M},n.scale=function(t){return arguments.length?(f=+t,r()):f},n.translate=function(t){return arguments.length?(s=+t[0],h=+t[1],r()):[s,h]},n.center=function(t){return arguments.length?(g=t[0]%360*Ci,p=t[1]%360*Ci,r()):[g*zi,p*zi]},n.rotate=function(t){return arguments.length?(d=t[0]%360*Ci,m=t[1]%360*Ci,v=t.length>2?t[2]%360*Ci:0,r()):[d*zi,m*zi,v*zi]},qi.rebind(n,l,"precision"),function(){return u=t.apply(this,arguments),n.invert=u.invert&&e,r()}}function Hu(t,n){return{point:function(e,r){r=t(e*Ci,r*Ci),e=r[0],n.point(e>Ni?e-2*Ni:-Ni>e?e+2*Ni:e,r[1])},sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ju(t,n,e){return t?n||e?yu(Ru(t),Ou(n,e)):Ru(t):n||e?Ou(n,e):Mu}function Pu(t){return function(n,e){return n+=t,[n>Ni?n-2*Ni:-Ni>n?n+2*Ni:n,e]}}function Ru(t){var n=Pu(t);return n.invert=Pu(-t),n}function Ou(t,n){function e(t,n){var e=Math.cos(n),o=Math.cos(t)*e,c=Math.sin(t)*e,l=Math.sin(n),f=l*r+o*u;return[Math.atan2(c*i-f*a,o*r-l*u),Math.asin(Math.max(-1,Math.min(1,f*i+c*a)))]}var r=Math.cos(t),u=Math.sin(t),i=Math.cos(n),a=Math.sin(n);return e.invert=function(t,n){var e=Math.cos(n),o=Math.cos(t)*e,c=Math.sin(t)*e,l=Math.sin(n),f=l*i-c*a;return[Math.atan2(c*i+l*a,o*r+f*u),Math.asin(Math.max(-1,Math.min(1,f*r-o*u)))]},e}function Yu(t,n){function e(n,e){var r=Math.cos(n),u=Math.cos(e),i=t(r*u);return[i*u*Math.sin(n),i*Math.sin(e)]}return e.invert=function(t,e){var r=Math.sqrt(t*t+e*e),u=n(r),i=Math.sin(u),a=Math.cos(u);return[Math.atan2(t*i,r*a),Math.asin(r&&e*i/r)]},e}function Uu(t,n,e,r){var u,i,a,o,c,l,f;return u=r[t],i=u[0],a=u[1],u=r[n],o=u[0],c=u[1],u=r[e],l=u[0],f=u[1],(f-a)*(o-i)-(c-a)*(l-i)>0}function Iu(t,n,e){return(e[0]-n[0])*(t[1]-n[1])<(e[1]-n[1])*(t[0]-n[0])}function Vu(t,n,e,r){var u=t[0],i=e[0],a=n[0]-u,o=r[0]-i,c=t[1],l=e[1],f=n[1]-c,s=r[1]-l,h=(o*(c-l)-s*(u-i))/(s*a-o*f);return[u+h*a,c+h*f]}function Xu(t,n){var e={list:t.map(function(t,n){return{index:n,x:t[0],y:t[1]}}).sort(function(t,n){return t.yn.y?1:t.xn.x?1:0}),bottomSite:null},r={list:[],leftEnd:null,rightEnd:null,init:function(){r.leftEnd=r.createHalfEdge(null,"l"),r.rightEnd=r.createHalfEdge(null,"l"),r.leftEnd.r=r.rightEnd,r.rightEnd.l=r.leftEnd,r.list.unshift(r.leftEnd,r.rightEnd)},createHalfEdge:function(t,n){return{edge:t,side:n,vertex:null,l:null,r:null}},insert:function(t,n){n.l=t,n.r=t.r,t.r.l=n,t.r=n},leftBound:function(t){var n=r.leftEnd;do n=n.r;while(n!=r.rightEnd&&u.rightOf(n,t));return n=n.l},del:function(t){t.l.r=t.r,t.r.l=t.l,t.edge=null},right:function(t){return t.r},left:function(t){return t.l},leftRegion:function(t){return null==t.edge?e.bottomSite:t.edge.region[t.side]},rightRegion:function(t){return null==t.edge?e.bottomSite:t.edge.region[No[t.side]]}},u={bisect:function(t,n){var e={region:{l:t,r:n},ep:{l:null,r:null}},r=n.x-t.x,u=n.y-t.y,i=r>0?r:-r,a=u>0?u:-u;return e.c=t.x*r+t.y*u+.5*(r*r+u*u),i>a?(e.a=1,e.b=u/r,e.c/=r):(e.b=1,e.a=r/u,e.c/=u),e},intersect:function(t,n){var e=t.edge,r=n.edge;if(!e||!r||e.region.r==r.region.r)return null;var u=e.a*r.b-e.b*r.a;if(1e-10>Math.abs(u))return null;var i,a,o=(e.c*r.b-r.c*e.b)/u,c=(r.c*e.a-e.c*r.a)/u,l=e.region.r,f=r.region.r;l.y=a.region.r.x;return s&&"l"===i.side||!s&&"r"===i.side?null:{x:o,y:c}},rightOf:function(t,n){var e=t.edge,r=e.region.r,u=n.x>r.x;if(u&&"l"===t.side)return 1;if(!u&&"r"===t.side)return 0;if(1===e.a){var i=n.y-r.y,a=n.x-r.x,o=0,c=0;if(!u&&0>e.b||u&&e.b>=0?c=o=i>=e.b*a:(c=n.x+n.y*e.b>e.c,0>e.b&&(c=!c),c||(o=1)),!o){var l=r.x-e.region.l.x;c=e.b*(a*a-i*i)e.b&&(c=!c)}}else{var f=e.c-e.a*n.x,s=n.y-f,h=n.x-r.x,g=f-r.y;c=s*s>h*h+g*g}return"l"===t.side?c:!c},endPoint:function(t,e,r){t.ep[e]=r,t.ep[No[e]]&&n(t)},distance:function(t,n){var e=t.x-n.x,r=t.y-n.y;return Math.sqrt(e*e+r*r)}},i={list:[],insert:function(t,n,e){t.vertex=n,t.ystar=n.y+e;for(var r=0,u=i.list,a=u.length;a>r;r++){var o=u[r];if(!(t.ystar>o.ystar||t.ystar==o.ystar&&n.x>o.vertex.x))break}u.splice(r,0,t)},del:function(t){for(var n=0,e=i.list,r=e.length;r>n&&e[n]!=t;++n);e.splice(n,1)},empty:function(){return 0===i.list.length},nextEvent:function(t){for(var n=0,e=i.list,r=e.length;r>n;++n)if(e[n]==t)return e[n+1];return null},min:function(){var t=i.list[0];return{x:t.vertex.x,y:t.ystar}},extractMin:function(){return i.list.shift()}};r.init(),e.bottomSite=e.list.shift();for(var a,o,c,l,f,s,h,g,p,d,m,v,y,M=e.list.shift();;)if(i.empty()||(a=i.min()),M&&(i.empty()||M.yg.y&&(p=h,h=g,g=p,y="r"),v=u.bisect(h,g),s=r.createHalfEdge(v,y),r.insert(l,s),u.endPoint(v,No[y],m),d=u.intersect(l,s),d&&(i.del(l),i.insert(l,d,u.distance(d,h))),d=u.intersect(s,f),d&&i.insert(s,d,u.distance(d,h))}for(o=r.right(r.leftEnd);o!=r.rightEnd;o=r.right(o))n(o.edge)}function Zu(){return{leaf:!0,nodes:[],point:null}}function Bu(t,n,e,r,u,i){if(!t(n,e,r,u,i)){var a=.5*(e+u),o=.5*(r+i),c=n.nodes;c[0]&&Bu(t,c[0],e,r,a,o),c[1]&&Bu(t,c[1],a,r,u,o),c[2]&&Bu(t,c[2],e,o,a,i),c[3]&&Bu(t,c[3],a,o,u,i)}}function $u(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ju(t,n,e,r){for(var u,i,a=0,o=n.length,c=e.length;o>a;){if(r>=c)return-1;if(u=n.charCodeAt(a++),37===u){if(i=Bo[n.charAt(a++)],!i||0>(r=i(t,e,r)))return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function Gu(t){return RegExp("^(?:"+t.map(qi.requote).join("|")+")","i")}function Ku(t){for(var n=new i,e=-1,r=t.length;r>++e;)n.set(t[e].toLowerCase(),e);return n}function Wu(t,n,e){t+="";var r=t.length;return e>r?Array(e-r+1).join(n)+t:t}function Qu(t,n,e){Oo.lastIndex=0;var r=Oo.exec(n.substring(e));return r?e+=r[0].length:-1}function ti(t,n,e){Ro.lastIndex=0;var r=Ro.exec(n.substring(e));return r?e+=r[0].length:-1}function ni(t,n,e){Io.lastIndex=0;var r=Io.exec(n.substring(e));return r?(t.m=Vo.get(r[0].toLowerCase()),e+=r[0].length):-1}function ei(t,n,e){Yo.lastIndex=0;var r=Yo.exec(n.substring(e));return r?(t.m=Uo.get(r[0].toLowerCase()),e+=r[0].length):-1}function ri(t,n,e){return Ju(t,""+Zo.c,n,e)}function ui(t,n,e){return Ju(t,""+Zo.x,n,e)}function ii(t,n,e){return Ju(t,""+Zo.X,n,e)}function ai(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+4));return r?(t.y=+r[0],e+=r[0].length):-1}function oi(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.y=ci(+r[0]),e+=r[0].length):-1}function ci(t){return t+(t>68?1900:2e3)}function li(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.m=r[0]-1,e+=r[0].length):-1}function fi(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.d=+r[0],e+=r[0].length):-1}function si(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.H=+r[0],e+=r[0].length):-1}function hi(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.M=+r[0],e+=r[0].length):-1}function gi(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+2));return r?(t.S=+r[0],e+=r[0].length):-1}function pi(t,n,e){$o.lastIndex=0;var r=$o.exec(n.substring(e,e+3));return r?(t.L=+r[0],e+=r[0].length):-1}function di(t,n,e){var r=Jo.get(n.substring(e,e+=2).toLowerCase());return null==r?-1:(t.p=r,e)}function mi(t){var n=t.getTimezoneOffset(),e=n>0?"-":"+",r=~~(Math.abs(n)/60),u=Math.abs(n)%60;return e+Wu(r,"0",2)+Wu(u,"0",2)}function vi(t){return t.toISOString()}function yi(t,n,e){function r(n){var e=t(n),r=i(e,1);return r-n>n-e?e:r}function u(e){return n(e=t(new To(e-1)),1),e}function i(t,e){return n(t=new To(+t),e),t}function a(t,r,i){var a=u(t),o=[];if(i>1)for(;r>a;)e(a)%i||o.push(new Date(+a)),n(a,1);else for(;r>a;)o.push(new Date(+a)),n(a,1);return o}function o(t,n,e){try{To=$u;var r=new $u;return r._=t,a(r,n,e)}finally{To=Date}}t.floor=t,t.round=r,t.ceil=u,t.offset=i,t.range=a;var c=t.utc=Mi(t);return c.floor=c,c.round=Mi(r),c.ceil=Mi(u),c.offset=Mi(i),c.range=o,t}function Mi(t){return function(n,e){try{To=$u;var r=new $u;return r._=n,t(r,e)._}finally{To=Date}}}function bi(t,n,e){function r(n){return t(n)}return r.invert=function(n){return _i(t.invert(n))},r.domain=function(n){return arguments.length?(t.domain(n),r):t.domain().map(_i)},r.nice=function(t){return r.domain(Yn(r.domain(),function(){return t}))},r.ticks=function(e,u){var i=xi(r.domain());if("function"!=typeof e){var a=i[1]-i[0],o=a/e,c=qi.bisect(Ko,o);if(c==Ko.length)return n.year(i,e);if(!c)return t.ticks(e).map(_i);Math.log(o/Ko[c-1])n?[n,e]:[e,n]}function _i(t){return new Date(t)}function wi(t){return function(n){for(var e=t.length-1,r=t[e];!r[1](n);)r=t[--e];return r[0](n)}}function Si(t){var n=new Date(t,0,1);return n.setFullYear(t),n}function ki(t){var n=t.getFullYear(),e=Si(n),r=Si(n+1);return n+(t-e)/(r-e)}function Ei(t){var n=new Date(Date.UTC(t,0,1));return n.setUTCFullYear(t),n}function Ai(t){var n=t.getUTCFullYear(),e=Ei(n),r=Ei(n+1);return n+(t-e)/(r-e)}var Ni=Math.PI,Ti=1e-6,qi={version:"3.0.6"},Ci=Ni/180,zi=180/Ni,Di=document,Li=window,Fi=".",Hi=",",ji=[3,3];Date.now||(Date.now=function(){return+new Date});try{Di.createElement("div").style.setProperty("opacity",0,"")}catch(Pi){var Ri=Li.CSSStyleDeclaration.prototype,Oi=Ri.setProperty;Ri.setProperty=function(t,n,e){Oi.call(this,t,n+"",e)}}var Yi=u;try{Yi(Di.documentElement.childNodes)[0].nodeType}catch(Ui){Yi=r}var Ii=[].__proto__?function(t,n){t.__proto__=n}:function(t,n){for(var e in n)t[e]=n[e]};qi.map=function(t){var n=new i;for(var e in t)n.set(e,t[e]);return n},e(i,{has:function(t){return Vi+t in this},get:function(t){return this[Vi+t]},set:function(t,n){return this[Vi+t]=n},remove:function(t){return t=Vi+t,t in this&&delete this[t]},keys:function(){var t=[];return this.forEach(function(n){t.push(n)}),t},values:function(){var t=[];return this.forEach(function(n,e){t.push(e)}),t},entries:function(){var t=[];return this.forEach(function(n,e){t.push({key:n,value:e})}),t},forEach:function(t){for(var n in this)n.charCodeAt(0)===Xi&&t.call(this,n.substring(1),this[n])}});var Vi="\0",Xi=Vi.charCodeAt(0);qi.functor=c,qi.rebind=function(t,n){for(var e,r=1,u=arguments.length;u>++r;)t[e=arguments[r]]=l(t,n,n[e]);return t},qi.ascending=function(t,n){return n>t?-1:t>n?1:t>=n?0:0/0},qi.descending=function(t,n){return t>n?-1:n>t?1:n>=t?0:0/0},qi.mean=function(t,n){var e,r=t.length,u=0,i=-1,a=0;if(1===arguments.length)for(;r>++i;)f(e=t[i])&&(u+=(e-u)/++a);else for(;r>++i;)f(e=n.call(t,t[i],i))&&(u+=(e-u)/++a);return a?u:void 0},qi.median=function(t,n){return arguments.length>1&&(t=t.map(n)),t=t.filter(f),t.length?qi.quantile(t.sort(qi.ascending),.5):void 0},qi.min=function(t,n){var e,r,u=-1,i=t.length;if(1===arguments.length){for(;i>++u&&(null==(e=t[u])||e!=e);)e=void 0;for(;i>++u;)null!=(r=t[u])&&e>r&&(e=r)}else{for(;i>++u&&(null==(e=n.call(t,t[u],u))||e!=e);)e=void 0;for(;i>++u;)null!=(r=n.call(t,t[u],u))&&e>r&&(e=r)}return e},qi.max=function(t,n){var e,r,u=-1,i=t.length;if(1===arguments.length){for(;i>++u&&(null==(e=t[u])||e!=e);)e=void 0;for(;i>++u;)null!=(r=t[u])&&r>e&&(e=r)}else{for(;i>++u&&(null==(e=n.call(t,t[u],u))||e!=e);)e=void 0;for(;i>++u;)null!=(r=n.call(t,t[u],u))&&r>e&&(e=r)}return e},qi.extent=function(t,n){var e,r,u,i=-1,a=t.length;if(1===arguments.length){for(;a>++i&&(null==(e=u=t[i])||e!=e);)e=u=void 0;for(;a>++i;)null!=(r=t[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;a>++i&&(null==(e=u=n.call(t,t[i],i))||e!=e);)e=void 0;for(;a>++i;)null!=(r=n.call(t,t[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},qi.random={normal:function(t,n){var e=arguments.length;return 2>e&&(n=1),1>e&&(t=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return t+n*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var t=qi.random.normal.apply(qi,arguments);return function(){return Math.exp(t())}},irwinHall:function(t){return function(){for(var n=0,e=0;t>e;e++)n+=Math.random();return n/t}}},qi.sum=function(t,n){var e,r=0,u=t.length,i=-1;if(1===arguments.length)for(;u>++i;)isNaN(e=+t[i])||(r+=e);else for(;u>++i;)isNaN(e=+n.call(t,t[i],i))||(r+=e);return r},qi.quantile=function(t,n){var e=(t.length-1)*n+1,r=Math.floor(e),u=+t[r-1],i=e-r;return i?u+i*(t[r]-u):u},qi.shuffle=function(t){for(var n,e,r=t.length;r;)e=0|Math.random()*r--,n=t[r],t[r]=t[e],t[e]=n;return t},qi.transpose=function(t){return qi.zip.apply(qi,t)},qi.zip=function(){if(!(r=arguments.length))return[];for(var t=-1,n=qi.min(arguments,s),e=Array(n);n>++t;)for(var r,u=-1,i=e[t]=Array(r);r>++u;)i[u]=arguments[u][t];return e},qi.bisector=function(t){return{left:function(n,e,r,u){for(3>arguments.length&&(r=0),4>arguments.length&&(u=n.length);u>r;){var i=r+u>>>1;e>t.call(n,n[i],i)?r=i+1:u=i}return r},right:function(n,e,r,u){for(3>arguments.length&&(r=0),4>arguments.length&&(u=n.length);u>r;){var i=r+u>>>1;t.call(n,n[i],i)>e?u=i:r=i+1}return r}}};var Zi=qi.bisector(function(t){return t});qi.bisectLeft=Zi.left,qi.bisect=qi.bisectRight=Zi.right,qi.nest=function(){function t(n,o){if(o>=a.length)return r?r.call(u,n):e?n.sort(e):n;for(var c,l,f,s=-1,h=n.length,g=a[o++],p=new i,d={};h>++s;)(f=p.get(c=g(l=n[s])))?f.push(l):p.set(c,[l]);return p.forEach(function(n,e){d[n]=t(e,o)}),d}function n(t,e){if(e>=a.length)return t;var r,u=[],i=o[e++];for(r in t)u.push({key:r,values:n(t[r],e)});return i&&u.sort(function(t,n){return i(t.key,n.key)}),u}var e,r,u={},a=[],o=[];return u.map=function(n){return t(n,0)},u.entries=function(e){return n(t(e,0),0)},u.key=function(t){return a.push(t),u},u.sortKeys=function(t){return o[a.length-1]=t,u},u.sortValues=function(t){return e=t,u},u.rollup=function(t){return r=t,u},u},qi.keys=function(t){var n=[];for(var e in t)n.push(e);return n},qi.values=function(t){var n=[];for(var e in t)n.push(t[e]);return n},qi.entries=function(t){var n=[];for(var e in t)n.push({key:e,value:t[e]});return n},qi.permute=function(t,n){for(var e=[],r=-1,u=n.length;u>++r;)e[r]=t[n[r]];return e},qi.merge=function(t){return Array.prototype.concat.apply([],t)},qi.range=function(t,n,e){if(3>arguments.length&&(e=1,2>arguments.length&&(n=t,t=0)),1/0===(n-t)/e)throw Error("infinite range");var r,u=[],i=g(Math.abs(e)),a=-1;if(t*=i,n*=i,e*=i,0>e)for(;(r=t+e*++a)>n;)u.push(r/i);else for(;n>(r=t+e*++a);)u.push(r/i);return u},qi.requote=function(t){return t.replace(Bi,"\\$&")};var Bi=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;qi.round=function(t,n){return n?Math.round(t*(n=Math.pow(10,n)))/n:Math.round(t)},qi.xhr=function(t,n,e){function r(){var t=l.status;!t&&l.responseText||t>=200&&300>t||304===t?i.load.call(u,c.call(u,l)):i.error.call(u,l)}var u={},i=qi.dispatch("progress","load","error"),o={},c=a,l=new(Li.XDomainRequest&&/^(http(s)?:)?\/\//.test(t)?XDomainRequest:XMLHttpRequest);return"onload"in l?l.onload=l.onerror=r:l.onreadystatechange=function(){l.readyState>3&&r()},l.onprogress=function(t){var n=qi.event;qi.event=t;try{i.progress.call(u,l)}finally{qi.event=n}},u.header=function(t,n){return t=(t+"").toLowerCase(),2>arguments.length?o[t]:(null==n?delete o[t]:o[t]=n+"",u)},u.mimeType=function(t){return arguments.length?(n=null==t?null:t+"",u):n},u.response=function(t){return c=t,u},["get","post"].forEach(function(t){u[t]=function(){return u.send.apply(u,[t].concat(Yi(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,t,!0),null==n||"accept"in o||(o.accept=n+",*/*"),l.setRequestHeader)for(var a in o)l.setRequestHeader(a,o[a]);return null!=n&&l.overrideMimeType&&l.overrideMimeType(n),null!=i&&u.on("error",i).on("load",function(t){i(null,t)}),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},qi.rebind(u,i,"on"),2===arguments.length&&"function"==typeof n&&(e=n,n=null),null==e?u:u.get(p(e))},qi.text=function(){return qi.xhr.apply(qi,arguments).response(d)},qi.json=function(t,n){return qi.xhr(t,"application/json",n).response(m)},qi.html=function(t,n){return qi.xhr(t,"text/html",n).response(v)},qi.xml=function(){return qi.xhr.apply(qi,arguments).response(y)};var $i={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};qi.ns={prefix:$i,qualify:function(t){var n=t.indexOf(":"),e=t;return n>=0&&(e=t.substring(0,n),t=t.substring(n+1)),$i.hasOwnProperty(e)?{space:$i[e],local:t}:t}},qi.dispatch=function(){for(var t=new M,n=-1,e=arguments.length;e>++n;)t[arguments[n]]=b(t);return t},M.prototype.on=function(t,n){var e=t.indexOf("."),r="";return e>0&&(r=t.substring(e+1),t=t.substring(0,e)),2>arguments.length?this[t].on(r):this[t].on(r,n)},qi.format=function(t){var n=Ji.exec(t),e=n[1]||" ",r=n[2]||">",u=n[3]||"",i=n[4]||"",a=n[5],o=+n[6],c=n[7],l=n[8],f=n[9],s=1,h="",g=!1;switch(l&&(l=+l.substring(1)),(a||"0"===e&&"="===r)&&(a=e="0",r="=",c&&(o-=Math.floor((o-1)/4))),f){case"n":c=!0,f="g";break;case"%":s=100,h="%",f="f";break;case"p":s=100,h="%",f="r";break;case"b":case"o":case"x":case"X":i&&(i="0"+f.toLowerCase());case"c":case"d":g=!0,l=0;break;case"s":s=-1,f="r"}"#"===i&&(i=""),"r"!=f||l||(f="g"),f=Gi.get(f)||_;var p=a&&c;return function(t){if(g&&t%1)return"";var n=0>t||0===t&&0>1/t?(t=-t,"-"):u;if(0>s){var d=qi.formatPrefix(t,l);t=d.scale(t),h=d.symbol}else t*=s;t=f(t,l),!a&&c&&(t=Ki(t));var m=i.length+t.length+(p?0:n.length),v=o>m?Array(m=o-m+1).join(e):"";return p&&(t=Ki(v+t)),Fi&&t.replace(".",Fi),n+=i,("<"===r?n+t+v:">"===r?v+n+t:"^"===r?v.substring(0,m>>=1)+n+t+v.substring(m):n+(p?t:v+t))+h}};var Ji=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,Gi=qi.map({b:function(t){return t.toString(2)},c:function(t){return String.fromCharCode(t)},o:function(t){return t.toString(8)},x:function(t){return t.toString(16)},X:function(t){return t.toString(16).toUpperCase()},g:function(t,n){return t.toPrecision(n)},e:function(t,n){return t.toExponential(n)},f:function(t,n){return t.toFixed(n)},r:function(t,n){return(t=qi.round(t,x(t,n))).toFixed(Math.max(0,Math.min(20,x(t*(1+1e-15),n))))}}),Ki=a;if(ji){var Wi=ji.length;Ki=function(t){for(var n=t.lastIndexOf("."),e=n>=0?"."+t.substring(n+1):(n=t.length,""),r=[],u=0,i=ji[0];n>0&&i>0;)r.push(t.substring(n-=i,n+i)),i=ji[u=(u+1)%Wi];return r.reverse().join(Hi||"")+e}}var Qi=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"].map(w);qi.formatPrefix=function(t,n){var e=0;return t&&(0>t&&(t*=-1),n&&(t=qi.round(t,x(t,n))),e=1+Math.floor(1e-12+Math.log(t)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Qi[8+e/3]};var ta=function(){return a},na=qi.map({linear:ta,poly:q,quad:function(){return A},cubic:function(){return N},sin:function(){return C},exp:function(){return z},circle:function(){return D},elastic:L,back:F,bounce:function(){return H}}),ea=qi.map({"in":a,out:k,"in-out":E,"out-in":function(t){return E(k(t))}});qi.ease=function(t){var n=t.indexOf("-"),e=n>=0?t.substring(0,n):t,r=n>=0?t.substring(n+1):"in";return e=na.get(e)||ta,r=ea.get(r)||a,S(r(e.apply(null,Array.prototype.slice.call(arguments,1))))},qi.event=null,qi.transform=function(t){var n=Di.createElementNS(qi.ns.prefix.svg,"g");return(qi.transform=function(t){n.setAttribute("transform",t);var e=n.transform.baseVal.consolidate();return new O(e?e.matrix:ra)})(t)},O.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var ra={a:1,b:0,c:0,d:1,e:0,f:0};qi.interpolate=function(t,n){for(var e,r=qi.interpolators.length;--r>=0&&!(e=qi.interpolators[r](t,n)););return e},qi.interpolateNumber=function(t,n){return n-=t,function(e){return t+n*e}},qi.interpolateRound=function(t,n){return n-=t,function(e){return Math.round(t+n*e)}},qi.interpolateString=function(t,n){var e,r,u,i,a,o=0,c=0,l=[],f=[];for(ua.lastIndex=0,r=0;e=ua.exec(n);++r)e.index&&l.push(n.substring(o,c=e.index)),f.push({i:l.length,x:e[0]}),l.push(null),o=ua.lastIndex;for(n.length>o&&l.push(n.substring(o)),r=0,i=f.length;(e=ua.exec(t))&&i>r;++r)if(a=f[r],a.x==e[0]){if(a.i)if(null==l[a.i+1])for(l[a.i-1]+=a.x,l.splice(a.i,1),u=r+1;i>u;++u)f[u].i--;else for(l[a.i-1]+=a.x+l[a.i+1],l.splice(a.i,2),u=r+1;i>u;++u)f[u].i-=2;else if(null==l[a.i+1])l[a.i]=a.x;else for(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1),u=r+1;i>u;++u)f[u].i--;f.splice(r,1),i--,r--}else a.x=qi.interpolateNumber(parseFloat(e[0]),parseFloat(a.x));for(;i>r;)a=f.pop(),null==l[a.i+1]?l[a.i]=a.x:(l[a.i]=a.x+l[a.i+1],l.splice(a.i+1,1)),i--;return 1===l.length?null==l[0]?f[0].x:function(){return n}:function(t){for(r=0;i>r;++r)l[(a=f[r]).i]=a.x(t);return l.join("")}},qi.interpolateTransform=function(t,n){var e,r=[],u=[],i=qi.transform(t),a=qi.transform(n),o=i.translate,c=a.translate,l=i.rotate,f=a.rotate,s=i.skew,h=a.skew,g=i.scale,p=a.scale;return o[0]!=c[0]||o[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:qi.interpolateNumber(o[0],c[0])},{i:3,x:qi.interpolateNumber(o[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),l!=f?(l-f>180?f+=360:f-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:qi.interpolateNumber(l,f)})):f&&r.push(r.pop()+"rotate("+f+")"),s!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:qi.interpolateNumber(s,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:qi.interpolateNumber(g[0],p[0])},{i:e-2,x:qi.interpolateNumber(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(t){for(var n,i=-1;e>++i;)r[(n=u[i]).i]=n.x(t);return r.join("")}},qi.interpolateRgb=function(t,n){t=qi.rgb(t),n=qi.rgb(n);var e=t.r,r=t.g,u=t.b,i=n.r-e,a=n.g-r,o=n.b-u;return function(t){return"#"+G(Math.round(e+i*t))+G(Math.round(r+a*t))+G(Math.round(u+o*t))}},qi.interpolateHsl=function(t,n){t=qi.hsl(t),n=qi.hsl(n);var e=t.h,r=t.s,u=t.l,i=n.h-e,a=n.s-r,o=n.l-u;return i>180?i-=360:-180>i&&(i+=360),function(t){return un(e+i*t,r+a*t,u+o*t)+""}},qi.interpolateLab=function(t,n){t=qi.lab(t),n=qi.lab(n);var e=t.l,r=t.a,u=t.b,i=n.l-e,a=n.a-r,o=n.b-u;return function(t){return sn(e+i*t,r+a*t,u+o*t)+""}},qi.interpolateHcl=function(t,n){t=qi.hcl(t),n=qi.hcl(n);var e=t.h,r=t.c,u=t.l,i=n.h-e,a=n.c-r,o=n.l-u;return i>180?i-=360:-180>i&&(i+=360),function(t){return cn(e+i*t,r+a*t,u+o*t)+""}},qi.interpolateArray=function(t,n){var e,r=[],u=[],i=t.length,a=n.length,o=Math.min(t.length,n.length);for(e=0;o>e;++e)r.push(qi.interpolate(t[e],n[e]));for(;i>e;++e)u[e]=t[e];for(;a>e;++e)u[e]=n[e];return function(t){for(e=0;o>e;++e)u[e]=r[e](t);return u}},qi.interpolateObject=function(t,n){var e,r={},u={};for(e in t)e in n?r[e]=V(e)(t[e],n[e]):u[e]=t[e];for(e in n)e in t||(u[e]=n[e]);return function(t){for(e in r)u[e]=r[e](t);return u}};var ua=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;qi.interpolators=[qi.interpolateObject,function(t,n){return n instanceof Array&&qi.interpolateArray(t,n)},function(t,n){return("string"==typeof t||"string"==typeof n)&&qi.interpolateString(t+"",n+"")},function(t,n){return("string"==typeof n?aa.has(n)||/^(#|rgb\(|hsl\()/.test(n):n instanceof B)&&qi.interpolateRgb(t,n)},function(t,n){return!isNaN(t=+t)&&!isNaN(n=+n)&&qi.interpolateNumber(t,n)}],B.prototype.toString=function(){return this.rgb()+""},qi.rgb=function(t,n,e){return 1===arguments.length?t instanceof J?$(t.r,t.g,t.b):K(""+t,$,un):$(~~t,~~n,~~e)};var ia=J.prototype=new B;ia.brighter=function(t){t=Math.pow(.7,arguments.length?t:1);var n=this.r,e=this.g,r=this.b,u=30;return n||e||r?(n&&u>n&&(n=u),e&&u>e&&(e=u),r&&u>r&&(r=u),$(Math.min(255,Math.floor(n/t)),Math.min(255,Math.floor(e/t)),Math.min(255,Math.floor(r/t)))):$(u,u,u)},ia.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),$(Math.floor(t*this.r),Math.floor(t*this.g),Math.floor(t*this.b))},ia.hsl=function(){return W(this.r,this.g,this.b)},ia.toString=function(){return"#"+G(this.r)+G(this.g)+G(this.b)};var aa=qi.map({aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"}); -aa.forEach(function(t,n){aa.set(t,K(n,$,un))}),qi.hsl=function(t,n,e){return 1===arguments.length?t instanceof rn?en(t.h,t.s,t.l):K(""+t,W,en):en(+t,+n,+e)};var oa=rn.prototype=new B;oa.brighter=function(t){return t=Math.pow(.7,arguments.length?t:1),en(this.h,this.s,this.l/t)},oa.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),en(this.h,this.s,t*this.l)},oa.rgb=function(){return un(this.h,this.s,this.l)},qi.hcl=function(t,n,e){return 1===arguments.length?t instanceof on?an(t.h,t.c,t.l):t instanceof fn?hn(t.l,t.a,t.b):hn((t=Q((t=qi.rgb(t)).r,t.g,t.b)).l,t.a,t.b):an(+t,+n,+e)};var ca=on.prototype=new B;ca.brighter=function(t){return an(this.h,this.c,Math.min(100,this.l+la*(arguments.length?t:1)))},ca.darker=function(t){return an(this.h,this.c,Math.max(0,this.l-la*(arguments.length?t:1)))},ca.rgb=function(){return cn(this.h,this.c,this.l).rgb()},qi.lab=function(t,n,e){return 1===arguments.length?t instanceof fn?ln(t.l,t.a,t.b):t instanceof on?cn(t.l,t.c,t.h):Q((t=qi.rgb(t)).r,t.g,t.b):ln(+t,+n,+e)};var la=18,fa=.95047,sa=1,ha=1.08883,ga=fn.prototype=new B;ga.brighter=function(t){return ln(Math.min(100,this.l+la*(arguments.length?t:1)),this.a,this.b)},ga.darker=function(t){return ln(Math.max(0,this.l-la*(arguments.length?t:1)),this.a,this.b)},ga.rgb=function(){return sn(this.l,this.a,this.b)};var pa=function(t,n){return n.querySelector(t)},da=function(t,n){return n.querySelectorAll(t)},ma=Di.documentElement,va=ma.matchesSelector||ma.webkitMatchesSelector||ma.mozMatchesSelector||ma.msMatchesSelector||ma.oMatchesSelector,ya=function(t,n){return va.call(t,n)};"function"==typeof Sizzle&&(pa=function(t,n){return Sizzle(t,n)[0]||null},da=function(t,n){return Sizzle.uniqueSort(Sizzle(t,n))},ya=Sizzle.matchesSelector);var Ma=[];qi.selection=function(){return ba},qi.selection.prototype=Ma,Ma.select=function(t){var n,e,r,u,i=[];"function"!=typeof t&&(t=vn(t));for(var a=-1,o=this.length;o>++a;){i.push(n=[]),n.parentNode=(r=this[a]).parentNode;for(var c=-1,l=r.length;l>++c;)(u=r[c])?(n.push(e=t.call(u,u.__data__,c)),e&&"__data__"in u&&(e.__data__=u.__data__)):n.push(null)}return mn(i)},Ma.selectAll=function(t){var n,e,r=[];"function"!=typeof t&&(t=yn(t));for(var u=-1,i=this.length;i>++u;)for(var a=this[u],o=-1,c=a.length;c>++o;)(e=a[o])&&(r.push(n=Yi(t.call(e,e.__data__,o))),n.parentNode=e);return mn(r)},Ma.attr=function(t,n){if(2>arguments.length){if("string"==typeof t){var e=this.node();return t=qi.ns.qualify(t),t.local?e.getAttributeNS(t.space,t.local):e.getAttribute(t)}for(n in t)this.each(Mn(n,t[n]));return this}return this.each(Mn(t,n))},Ma.classed=function(t,n){if(2>arguments.length){if("string"==typeof t){var e=this.node(),r=(t=t.trim().split(/^|\s+/g)).length,u=-1;if(n=e.classList){for(;r>++u;)if(!n.contains(t[u]))return!1}else for(n=e.className,null!=n.baseVal&&(n=n.baseVal);r>++u;)if(!bn(t[u]).test(n))return!1;return!0}for(n in t)this.each(xn(n,t[n]));return this}return this.each(xn(t,n))},Ma.style=function(t,n,e){var r=arguments.length;if(3>r){if("string"!=typeof t){2>r&&(n="");for(e in t)this.each(wn(e,t[e],n));return this}if(2>r)return Li.getComputedStyle(this.node(),null).getPropertyValue(t);e=""}return this.each(wn(t,n,e))},Ma.property=function(t,n){if(2>arguments.length){if("string"==typeof t)return this.node()[t];for(n in t)this.each(Sn(n,t[n]));return this}return this.each(Sn(t,n))},Ma.text=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.textContent=null==n?"":n}:null==t?function(){this.textContent=""}:function(){this.textContent=t}):this.node().textContent},Ma.html=function(t){return arguments.length?this.each("function"==typeof t?function(){var n=t.apply(this,arguments);this.innerHTML=null==n?"":n}:null==t?function(){this.innerHTML=""}:function(){this.innerHTML=t}):this.node().innerHTML},Ma.append=function(t){function n(){return this.appendChild(Di.createElementNS(this.namespaceURI,t))}function e(){return this.appendChild(Di.createElementNS(t.space,t.local))}return t=qi.ns.qualify(t),this.select(t.local?e:n)},Ma.insert=function(t,n){function e(){return this.insertBefore(Di.createElementNS(this.namespaceURI,t),pa(n,this))}function r(){return this.insertBefore(Di.createElementNS(t.space,t.local),pa(n,this))}return t=qi.ns.qualify(t),this.select(t.local?r:e)},Ma.remove=function(){return this.each(function(){var t=this.parentNode;t&&t.removeChild(this)})},Ma.data=function(t,n){function e(t,e){var r,u,a,o=t.length,s=e.length,h=Math.min(o,s),g=Array(s),p=Array(s),d=Array(o);if(n){var m,v=new i,y=new i,M=[];for(r=-1;o>++r;)m=n.call(u=t[r],u.__data__,r),v.has(m)?d[r]=u:v.set(m,u),M.push(m);for(r=-1;s>++r;)m=n.call(e,a=e[r],r),(u=v.get(m))?(g[r]=u,u.__data__=a):y.has(m)||(p[r]=kn(a)),y.set(m,a),v.remove(m);for(r=-1;o>++r;)v.has(M[r])&&(d[r]=t[r])}else{for(r=-1;h>++r;)u=t[r],a=e[r],u?(u.__data__=a,g[r]=u):p[r]=kn(a);for(;s>r;++r)p[r]=kn(e[r]);for(;o>r;++r)d[r]=t[r]}p.update=g,p.parentNode=g.parentNode=d.parentNode=t.parentNode,c.push(p),l.push(g),f.push(d)}var r,u,a=-1,o=this.length;if(!arguments.length){for(t=Array(o=(r=this[0]).length);o>++a;)(u=r[a])&&(t[a]=u.__data__);return t}var c=qn([]),l=mn([]),f=mn([]);if("function"==typeof t)for(;o>++a;)e(r=this[a],t.call(r,r.parentNode.__data__,a));else for(;o>++a;)e(r=this[a],t);return l.enter=function(){return c},l.exit=function(){return f},l},Ma.datum=function(t){return arguments.length?this.property("__data__",t):this.property("__data__")},Ma.filter=function(t){var n,e,r,u=[];"function"!=typeof t&&(t=En(t));for(var i=0,a=this.length;a>i;i++){u.push(n=[]),n.parentNode=(e=this[i]).parentNode;for(var o=0,c=e.length;c>o;o++)(r=e[o])&&t.call(r,r.__data__,o)&&n.push(r)}return mn(u)},Ma.order=function(){for(var t=-1,n=this.length;n>++t;)for(var e,r=this[t],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},Ma.sort=function(t){t=An.apply(this,arguments);for(var n=-1,e=this.length;e>++n;)this[n].sort(t);return this.order()},Ma.on=function(t,n,e){var r=arguments.length;if(3>r){if("string"!=typeof t){2>r&&(n=!1);for(e in t)this.each(Nn(e,t[e],n));return this}if(2>r)return(r=this.node()["__on"+t])&&r._;e=!1}return this.each(Nn(t,n,e))},Ma.each=function(t){return Tn(this,function(n,e,r){t.call(n,n.__data__,e,r)})},Ma.call=function(t){var n=Yi(arguments);return t.apply(n[0]=this,n),this},Ma.empty=function(){return!this.node()},Ma.node=function(){for(var t=0,n=this.length;n>t;t++)for(var e=this[t],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},Ma.transition=function(){var t,n,e=_a||++Sa,r=[],u=Object.create(ka);u.time=Date.now();for(var i=-1,a=this.length;a>++i;){r.push(t=[]);for(var o=this[i],c=-1,l=o.length;l>++c;)(n=o[c])&&zn(n,c,e,u),t.push(n)}return Cn(r,e)};var ba=mn([[Di]]);ba[0].parentNode=ma,qi.select=function(t){return"string"==typeof t?ba.select(t):mn([[t]])},qi.selectAll=function(t){return"string"==typeof t?ba.selectAll(t):mn([Yi(t)])};var xa=[];qi.selection.enter=qn,qi.selection.enter.prototype=xa,xa.append=Ma.append,xa.insert=Ma.insert,xa.empty=Ma.empty,xa.node=Ma.node,xa.select=function(t){for(var n,e,r,u,i,a=[],o=-1,c=this.length;c>++o;){r=(u=this[o]).update,a.push(n=[]),n.parentNode=u.parentNode;for(var l=-1,f=u.length;f>++l;)(i=u[l])?(n.push(r[l]=e=t.call(u.parentNode,i.__data__,l)),e.__data__=i.__data__):n.push(null)}return mn(a)};var _a,wa=[],Sa=0,ka={ease:T,delay:0,duration:250};wa.call=Ma.call,wa.empty=Ma.empty,wa.node=Ma.node,qi.transition=function(t){return arguments.length?_a?t.transition():t:ba.transition()},qi.transition.prototype=wa,wa.select=function(t){var n,e,r,u=this.id,i=[];"function"!=typeof t&&(t=vn(t));for(var a=-1,o=this.length;o>++a;){i.push(n=[]);for(var c=this[a],l=-1,f=c.length;f>++l;)(r=c[l])&&(e=t.call(r,r.__data__,l))?("__data__"in r&&(e.__data__=r.__data__),zn(e,l,u,r.__transition__[u]),n.push(e)):n.push(null)}return Cn(i,u)},wa.selectAll=function(t){var n,e,r,u,i,a=this.id,o=[];"function"!=typeof t&&(t=yn(t));for(var c=-1,l=this.length;l>++c;)for(var f=this[c],s=-1,h=f.length;h>++s;)if(r=f[s]){i=r.__transition__[a],e=t.call(r,r.__data__,s),o.push(n=[]);for(var g=-1,p=e.length;p>++g;)zn(u=e[g],g,a,i),n.push(u)}return Cn(o,a)},wa.filter=function(t){var n,e,r,u=[];"function"!=typeof t&&(t=En(t));for(var i=0,a=this.length;a>i;i++){u.push(n=[]);for(var e=this[i],o=0,c=e.length;c>o;o++)(r=e[o])&&t.call(r,r.__data__,o)&&n.push(r)}return Cn(u,this.id,this.time).ease(this.ease())},wa.attr=function(t,n){function e(){this.removeAttribute(i)}function r(){this.removeAttributeNS(i.space,i.local)}if(2>arguments.length){for(n in t)this.attr(n,t[n]);return this}var u=V(t),i=qi.ns.qualify(t);return Ln(this,"attr."+t,n,function(t){function n(){var n,e=this.getAttribute(i);return e!==t&&(n=u(e,t),function(t){this.setAttribute(i,n(t))})}function a(){var n,e=this.getAttributeNS(i.space,i.local);return e!==t&&(n=u(e,t),function(t){this.setAttributeNS(i.space,i.local,n(t))})}return null==t?i.local?r:e:(t+="",i.local?a:n)})},wa.attrTween=function(t,n){function e(t,e){var r=n.call(this,t,e,this.getAttribute(u));return r&&function(t){this.setAttribute(u,r(t))}}function r(t,e){var r=n.call(this,t,e,this.getAttributeNS(u.space,u.local));return r&&function(t){this.setAttributeNS(u.space,u.local,r(t))}}var u=qi.ns.qualify(t);return this.tween("attr."+t,u.local?r:e)},wa.style=function(t,n,e){function r(){this.style.removeProperty(t)}var u=arguments.length;if(3>u){if("string"!=typeof t){2>u&&(n="");for(e in t)this.style(e,t[e],n);return this}e=""}var i=V(t);return Ln(this,"style."+t,n,function(n){function u(){var r,u=Li.getComputedStyle(this,null).getPropertyValue(t);return u!==n&&(r=i(u,n),function(n){this.style.setProperty(t,r(n),e)})}return null==n?r:(n+="",u)})},wa.styleTween=function(t,n,e){return 3>arguments.length&&(e=""),this.tween("style."+t,function(r,u){var i=n.call(this,r,u,Li.getComputedStyle(this,null).getPropertyValue(t));return i&&function(n){this.style.setProperty(t,i(n),e)}})},wa.text=function(t){return Ln(this,"text",t,Dn)},wa.remove=function(){return this.each("end.transition",function(){var t;!this.__transition__&&(t=this.parentNode)&&t.removeChild(this)})},wa.ease=function(t){var n=this.id;return 1>arguments.length?this.node().__transition__[n].ease:("function"!=typeof t&&(t=qi.ease.apply(qi,arguments)),Tn(this,function(e){e.__transition__[n].ease=t}))},wa.delay=function(t){var n=this.id;return Tn(this,"function"==typeof t?function(e,r,u){e.__transition__[n].delay=0|t.call(e,e.__data__,r,u)}:(t|=0,function(e){e.__transition__[n].delay=t}))},wa.duration=function(t){var n=this.id;return Tn(this,"function"==typeof t?function(e,r,u){e.__transition__[n].duration=Math.max(1,0|t.call(e,e.__data__,r,u))}:(t=Math.max(1,0|t),function(e){e.__transition__[n].duration=t}))},wa.each=function(t,n){var e=this.id;if(2>arguments.length){var r=ka,u=_a;_a=e,Tn(this,function(n,r,u){ka=n.__transition__[e],t.call(n,n.__data__,r,u)}),ka=r,_a=u}else Tn(this,function(r){r.__transition__[e].event.on(t,n)});return this},wa.transition=function(){for(var t,n,e,r,u=this.id,i=++Sa,a=[],o=0,c=this.length;c>o;o++){a.push(t=[]);for(var n=this[o],l=0,f=n.length;f>l;l++)(e=n[l])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,zn(e,l,i,r)),t.push(e)}return Cn(a,i)},wa.tween=function(t,n){var e=this.id;return 2>arguments.length?this.node().__transition__[e].tween.get(t):Tn(this,null==n?function(n){n.__transition__[e].tween.remove(t)}:function(r){r.__transition__[e].tween.set(t,n)})};var Ea,Aa,Na=0,Ta={},qa=null;qi.timer=function(t,n,e){if(3>arguments.length){if(2>arguments.length)n=0;else if(!isFinite(n))return;e=Date.now()}var r=Ta[t.id];r&&r.callback===t?(r.then=e,r.delay=n):Ta[t.id=++Na]=qa={callback:t,then:e,delay:n,next:qa},Ea||(Aa=clearTimeout(Aa),Ea=1,Ca(Fn))},qi.timer.flush=function(){for(var t,n=Date.now(),e=qa;e;)t=n-e.then,e.delay||(e.flush=e.callback(t)),e=e.next;Hn()};var Ca=Li.requestAnimationFrame||Li.webkitRequestAnimationFrame||Li.mozRequestAnimationFrame||Li.oRequestAnimationFrame||Li.msRequestAnimationFrame||function(t){setTimeout(t,17)};qi.mouse=function(t){return jn(t,P())};var za=/WebKit/.test(Li.navigator.userAgent)?-1:0;qi.touches=function(t,n){return 2>arguments.length&&(n=P().touches),n?Yi(n).map(function(n){var e=jn(t,n);return e.identifier=n.identifier,e}):[]},qi.scale={},qi.scale.linear=function(){return In([0,1],[0,1],qi.interpolate,!1)},qi.scale.log=function(){return Kn(qi.scale.linear(),Wn)};var Da=qi.format(".0e");Wn.pow=function(t){return Math.pow(10,t)},Qn.pow=function(t){return-Math.pow(10,-t)},qi.scale.pow=function(){return te(qi.scale.linear(),1)},qi.scale.sqrt=function(){return qi.scale.pow().exponent(.5)},qi.scale.ordinal=function(){return ee([],{t:"range",a:[[]]})},qi.scale.category10=function(){return qi.scale.ordinal().range(La)},qi.scale.category20=function(){return qi.scale.ordinal().range(Fa)},qi.scale.category20b=function(){return qi.scale.ordinal().range(Ha)},qi.scale.category20c=function(){return qi.scale.ordinal().range(ja)};var La=["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],Fa=["#1f77b4","#aec7e8","#ff7f0e","#ffbb78","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5","#8c564b","#c49c94","#e377c2","#f7b6d2","#7f7f7f","#c7c7c7","#bcbd22","#dbdb8d","#17becf","#9edae5"],Ha=["#393b79","#5254a3","#6b6ecf","#9c9ede","#637939","#8ca252","#b5cf6b","#cedb9c","#8c6d31","#bd9e39","#e7ba52","#e7cb94","#843c39","#ad494a","#d6616b","#e7969c","#7b4173","#a55194","#ce6dbd","#de9ed6"],ja=["#3182bd","#6baed6","#9ecae1","#c6dbef","#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];qi.scale.quantile=function(){return re([],[])},qi.scale.quantize=function(){return ue(0,1,[0,1])},qi.scale.threshold=function(){return ie([.5],[0,1])},qi.scale.identity=function(){return ae([0,1])},qi.svg={},qi.svg.arc=function(){function t(){var t=n.apply(this,arguments),i=e.apply(this,arguments),a=r.apply(this,arguments)+Pa,o=u.apply(this,arguments)+Pa,c=(a>o&&(c=a,a=o,o=c),o-a),l=Ni>c?"0":"1",f=Math.cos(a),s=Math.sin(a),h=Math.cos(o),g=Math.sin(o);return c>=Ra?t?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+t+"A"+t+","+t+" 0 1,0 0,"+-t+"A"+t+","+t+" 0 1,0 0,"+t+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":t?"M"+i*f+","+i*s+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L"+t*h+","+t*g+"A"+t+","+t+" 0 "+l+",0 "+t*f+","+t*s+"Z":"M"+i*f+","+i*s+"A"+i+","+i+" 0 "+l+",1 "+i*h+","+i*g+"L0,0"+"Z"}var n=oe,e=ce,r=le,u=fe;return t.innerRadius=function(e){return arguments.length?(n=c(e),t):n},t.outerRadius=function(n){return arguments.length?(e=c(n),t):e},t.startAngle=function(n){return arguments.length?(r=c(n),t):r},t.endAngle=function(n){return arguments.length?(u=c(n),t):u},t.centroid=function(){var t=(n.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+Pa;return[Math.cos(i)*t,Math.sin(i)*t]},t};var Pa=-Ni/2,Ra=2*Ni-1e-6;qi.svg.line=function(){return se(a)};var Oa=qi.map({linear:pe,"linear-closed":de,"step-before":me,"step-after":ve,basis:we,"basis-open":Se,"basis-closed":ke,bundle:Ee,cardinal:be,"cardinal-open":ye,"cardinal-closed":Me,monotone:ze});Oa.forEach(function(t,n){n.key=t,n.closed=/-closed$/.test(t)});var Ya=[0,2/3,1/3,0],Ua=[0,1/3,2/3,0],Ia=[0,1/6,2/3,1/6];qi.svg.line.radial=function(){var t=se(De);return t.radius=t.x,delete t.x,t.angle=t.y,delete t.y,t},me.reverse=ve,ve.reverse=me,qi.svg.area=function(){return Le(a)},qi.svg.area.radial=function(){var t=Le(De);return t.radius=t.x,delete t.x,t.innerRadius=t.x0,delete t.x0,t.outerRadius=t.x1,delete t.x1,t.angle=t.y,delete t.y,t.startAngle=t.y0,delete t.y0,t.endAngle=t.y1,delete t.y1,t},qi.svg.chord=function(){function e(t,n){var e=r(this,o,t,n),c=r(this,l,t,n);return"M"+e.p0+i(e.r,e.p1,e.a1-e.a0)+(u(e,c)?a(e.r,e.p1,e.r,e.p0):a(e.r,e.p1,c.r,c.p0)+i(c.r,c.p1,c.a1-c.a0)+a(c.r,c.p1,e.r,e.p0))+"Z"}function r(t,n,e,r){var u=n.call(t,e,r),i=f.call(t,u,r),a=s.call(t,u,r)+Pa,o=h.call(t,u,r)+Pa;return{r:i,a0:a,a1:o,p0:[i*Math.cos(a),i*Math.sin(a)],p1:[i*Math.cos(o),i*Math.sin(o)]}}function u(t,n){return t.a0==n.a0&&t.a1==n.a1}function i(t,n,e){return"A"+t+","+t+" 0 "+ +(e>Ni)+",1 "+n}function a(t,n,e,r){return"Q 0,0 "+r}var o=n,l=t,f=Fe,s=le,h=fe;return e.radius=function(t){return arguments.length?(f=c(t),e):f},e.source=function(t){return arguments.length?(o=c(t),e):o},e.target=function(t){return arguments.length?(l=c(t),e):l},e.startAngle=function(t){return arguments.length?(s=c(t),e):s},e.endAngle=function(t){return arguments.length?(h=c(t),e):h},e},qi.svg.diagonal=function(){function e(t,n){var e=r.call(this,t,n),a=u.call(this,t,n),o=(e.y+a.y)/2,c=[e,{x:e.x,y:o},{x:a.x,y:o},a];return c=c.map(i),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var r=n,u=t,i=He;return e.source=function(t){return arguments.length?(r=c(t),e):r},e.target=function(t){return arguments.length?(u=c(t),e):u},e.projection=function(t){return arguments.length?(i=t,e):i},e},qi.svg.diagonal.radial=function(){var t=qi.svg.diagonal(),n=He,e=t.projection;return t.projection=function(t){return arguments.length?e(je(n=t)):n},t},qi.svg.symbol=function(){function t(t,r){return(Va.get(n.call(this,t,r))||Oe)(e.call(this,t,r))}var n=Re,e=Pe;return t.type=function(e){return arguments.length?(n=c(e),t):n},t.size=function(n){return arguments.length?(e=c(n),t):e},t};var Va=qi.map({circle:Oe,cross:function(t){var n=Math.sqrt(t/5)/2;return"M"+-3*n+","+-n+"H"+-n+"V"+-3*n+"H"+n+"V"+-n+"H"+3*n+"V"+n+"H"+n+"V"+3*n+"H"+-n+"V"+n+"H"+-3*n+"Z"},diamond:function(t){var n=Math.sqrt(t/(2*Za)),e=n*Za;return"M0,"+-n+"L"+e+",0"+" 0,"+n+" "+-e+",0"+"Z"},square:function(t){var n=Math.sqrt(t)/2;return"M"+-n+","+-n+"L"+n+","+-n+" "+n+","+n+" "+-n+","+n+"Z"},"triangle-down":function(t){var n=Math.sqrt(t/Xa),e=n*Xa/2;return"M0,"+e+"L"+n+","+-e+" "+-n+","+-e+"Z"},"triangle-up":function(t){var n=Math.sqrt(t/Xa),e=n*Xa/2;return"M0,"+-e+"L"+n+","+e+" "+-n+","+e+"Z"}});qi.svg.symbolTypes=Va.keys();var Xa=Math.sqrt(3),Za=Math.tan(30*Ci);qi.svg.axis=function(){function t(t){t.each(function(){var t,s=qi.select(this),h=null==l?e.ticks?e.ticks.apply(e,c):e.domain():l,g=null==n?e.tickFormat?e.tickFormat.apply(e,c):String:n,p=Ie(e,h,f),d=s.selectAll(".tick.minor").data(p,String),m=d.enter().insert("line",".tick").attr("class","tick minor").style("opacity",1e-6),v=qi.transition(d.exit()).style("opacity",1e-6).remove(),y=qi.transition(d).style("opacity",1),M=s.selectAll(".tick.major").data(h,String),b=M.enter().insert("g","path").attr("class","tick major").style("opacity",1e-6),x=qi.transition(M.exit()).style("opacity",1e-6).remove(),_=qi.transition(M).style("opacity",1),w=On(e),S=s.selectAll(".domain").data([0]),k=(S.enter().append("path").attr("class","domain"),qi.transition(S)),E=e.copy(),A=this.__chart__||E;this.__chart__=E,b.append("line"),b.append("text");var N=b.select("line"),T=_.select("line"),q=M.select("text").text(g),C=b.select("text"),z=_.select("text");switch(r){case"bottom":t=Ye,m.attr("y2",i),y.attr("x2",0).attr("y2",i),N.attr("y2",u),C.attr("y",Math.max(u,0)+o),T.attr("x2",0).attr("y2",u),z.attr("x",0).attr("y",Math.max(u,0)+o),q.attr("dy",".71em").style("text-anchor","middle"),k.attr("d","M"+w[0]+","+a+"V0H"+w[1]+"V"+a);break;case"top":t=Ye,m.attr("y2",-i),y.attr("x2",0).attr("y2",-i),N.attr("y2",-u),C.attr("y",-(Math.max(u,0)+o)),T.attr("x2",0).attr("y2",-u),z.attr("x",0).attr("y",-(Math.max(u,0)+o)),q.attr("dy","0em").style("text-anchor","middle"),k.attr("d","M"+w[0]+","+-a+"V0H"+w[1]+"V"+-a);break;case"left":t=Ue,m.attr("x2",-i),y.attr("x2",-i).attr("y2",0),N.attr("x2",-u),C.attr("x",-(Math.max(u,0)+o)),T.attr("x2",-u).attr("y2",0),z.attr("x",-(Math.max(u,0)+o)).attr("y",0),q.attr("dy",".32em").style("text-anchor","end"),k.attr("d","M"+-a+","+w[0]+"H0V"+w[1]+"H"+-a);break;case"right":t=Ue,m.attr("x2",i),y.attr("x2",i).attr("y2",0),N.attr("x2",u),C.attr("x",Math.max(u,0)+o),T.attr("x2",u).attr("y2",0),z.attr("x",Math.max(u,0)+o).attr("y",0),q.attr("dy",".32em").style("text-anchor","start"),k.attr("d","M"+a+","+w[0]+"H0V"+w[1]+"H"+a)}if(e.ticks)b.call(t,A),_.call(t,E),x.call(t,E),m.call(t,A),y.call(t,E),v.call(t,E);else{var D=E.rangeBand()/2,L=function(t){return E(t)+D};b.call(t,L),_.call(t,L)}})}var n,e=qi.scale.linear(),r=Ba,u=6,i=6,a=6,o=3,c=[10],l=null,f=0;return t.scale=function(n){return arguments.length?(e=n,t):e},t.orient=function(n){return arguments.length?(r=n in $a?n+"":Ba,t):r},t.ticks=function(){return arguments.length?(c=arguments,t):c},t.tickValues=function(n){return arguments.length?(l=n,t):l},t.tickFormat=function(e){return arguments.length?(n=e,t):n},t.tickSize=function(n,e){if(!arguments.length)return u;var r=arguments.length-1;return u=+n,i=r>1?+e:u,a=r>0?+arguments[r]:u,t},t.tickPadding=function(n){return arguments.length?(o=+n,t):o},t.tickSubdivide=function(n){return arguments.length?(f=+n,t):f},t};var Ba="bottom",$a={top:1,right:1,bottom:1,left:1};qi.svg.brush=function(){function t(i){i.each(function(){var i,a=qi.select(this),f=a.selectAll(".background").data([0]),s=a.selectAll(".extent").data([0]),h=a.selectAll(".resize").data(l,String);a.style("pointer-events","all").on("mousedown.brush",u).on("touchstart.brush",u),f.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),s.enter().append("rect").attr("class","extent").style("cursor","move"),h.enter().append("g").attr("class",function(t){return"resize "+t}).style("cursor",function(t){return Ja[t]}).append("rect").attr("x",function(t){return/[ew]$/.test(t)?-3:null}).attr("y",function(t){return/^[ns]/.test(t)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),h.style("display",t.empty()?"none":null),h.exit().remove(),o&&(i=On(o),f.attr("x",i[0]).attr("width",i[1]-i[0]),e(a)),c&&(i=On(c),f.attr("y",i[0]).attr("height",i[1]-i[0]),r(a)),n(a)})}function n(t){t.selectAll(".resize").attr("transform",function(t){return"translate("+f[+/e$/.test(t)][0]+","+f[+/^s/.test(t)][1]+")"})}function e(t){t.select(".extent").attr("x",f[0][0]),t.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1][0]-f[0][0])}function r(t){t.select(".extent").attr("y",f[0][1]),t.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1][1]-f[0][1])}function u(){function u(){var t=qi.event.changedTouches;return t?qi.touches(v,t)[0]:qi.mouse(v)}function l(){32==qi.event.keyCode&&(S||(d=null,k[0]-=f[1][0],k[1]-=f[1][1],S=2),j())}function s(){32==qi.event.keyCode&&2==S&&(k[0]+=f[1][0],k[1]+=f[1][1],S=0,j())}function h(){var t=u(),i=!1;m&&(t[0]+=m[0],t[1]+=m[1]),S||(qi.event.altKey?(d||(d=[(f[0][0]+f[1][0])/2,(f[0][1]+f[1][1])/2]),k[0]=f[+(t[0]l?(u=r,r=l):u=l),f[0][e]!==r||f[1][e]!==u?(i=null,f[0][e]=r,f[1][e]=u,!0):void 0}function p(){h(),b.style("pointer-events","all").selectAll(".resize").style("display",t.empty()?"none":null),qi.select("body").style("cursor",null),E.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),M({type:"brushend"}),j()}var d,m,v=this,y=qi.select(qi.event.target),M=a.of(v,arguments),b=qi.select(v),x=y.datum(),_=!/^(n|s)$/.test(x)&&o,w=!/^(e|w)$/.test(x)&&c,S=y.classed("extent"),k=u(),E=qi.select(Li).on("mousemove.brush",h).on("mouseup.brush",p).on("touchmove.brush",h).on("touchend.brush",p).on("keydown.brush",l).on("keyup.brush",s);if(S)k[0]=f[0][0]-k[0],k[1]=f[0][1]-k[1];else if(x){var A=+/w$/.test(x),N=+/^n/.test(x);m=[f[1-A][0]-k[0],f[1-N][1]-k[1]],k[0]=f[A][0],k[1]=f[N][1]}else qi.event.altKey&&(d=k.slice());b.style("pointer-events","none").selectAll(".resize").style("display",null),qi.select("body").style("cursor",y.style("cursor")),M({type:"brushstart"}),h(),j()}var i,a=R(t,"brushstart","brush","brushend"),o=null,c=null,l=Ga[0],f=[[0,0],[0,0]];return t.x=function(n){return arguments.length?(o=n,l=Ga[!o<<1|!c],t):o},t.y=function(n){return arguments.length?(c=n,l=Ga[!o<<1|!c],t):c},t.extent=function(n){var e,r,u,a,l;return arguments.length?(i=[[0,0],[0,0]],o&&(e=n[0],r=n[1],c&&(e=e[0],r=r[0]),i[0][0]=e,i[1][0]=r,o.invert&&(e=o(e),r=o(r)),e>r&&(l=e,e=r,r=l),f[0][0]=0|e,f[1][0]=0|r),c&&(u=n[0],a=n[1],o&&(u=u[1],a=a[1]),i[0][1]=u,i[1][1]=a,c.invert&&(u=c(u),a=c(a)),u>a&&(l=u,u=a,a=l),f[0][1]=0|u,f[1][1]=0|a),t):(n=i||f,o&&(e=n[0][0],r=n[1][0],i||(e=f[0][0],r=f[1][0],o.invert&&(e=o.invert(e),r=o.invert(r)),e>r&&(l=e,e=r,r=l))),c&&(u=n[0][1],a=n[1][1],i||(u=f[0][1],a=f[1][1],c.invert&&(u=c.invert(u),a=c.invert(a)),u>a&&(l=u,u=a,a=l))),o&&c?[[e,u],[r,a]]:o?[e,r]:c&&[u,a])},t.clear=function(){return i=null,f[0][0]=f[0][1]=f[1][0]=f[1][1]=0,t},t.empty=function(){return o&&f[0][0]===f[1][0]||c&&f[0][1]===f[1][1]},qi.rebind(t,a,"on")};var Ja={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ga=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]];qi.behavior={},qi.behavior.drag=function(){function t(){this.on("mousedown.drag",n).on("touchstart.drag",n)}function n(){function t(){var t=o.parentNode;return null!=f?qi.touches(t).filter(function(t){return t.identifier===f})[0]:qi.mouse(t)}function n(){if(!o.parentNode)return u();var n=t(),e=n[0]-s[0],r=n[1]-s[1];h|=e|r,s=n,j(),c({type:"drag",x:n[0]+a[0],y:n[1]+a[1],dx:e,dy:r})}function u(){c({type:"dragend"}),h&&(j(),qi.event.target===l&&g.on("click.drag",i,!0)),g.on(null!=f?"touchmove.drag-"+f:"mousemove.drag",null).on(null!=f?"touchend.drag-"+f:"mouseup.drag",null)}function i(){j(),g.on("click.drag",null)}var a,o=this,c=e.of(o,arguments),l=qi.event.target,f=qi.event.touches?qi.event.changedTouches[0].identifier:null,s=t(),h=0,g=qi.select(Li).on(null!=f?"touchmove.drag-"+f:"mousemove.drag",n).on(null!=f?"touchend.drag-"+f:"mouseup.drag",u,!0);r?(a=r.apply(o,arguments),a=[a.x-s[0],a.y-s[1]]):a=[0,0],null==f&&j(),c({type:"dragstart"})}var e=R(t,"drag","dragstart","dragend"),r=null;return t.origin=function(n){return arguments.length?(r=n,t):r},qi.rebind(t,e,"on")},qi.behavior.zoom=function(){function t(){this.on("mousedown.zoom",o).on("mousemove.zoom",l).on(Qa+".zoom",c).on("dblclick.zoom",f).on("touchstart.zoom",s).on("touchmove.zoom",h).on("touchend.zoom",s)}function n(t){return[(t[0]-b[0])/x,(t[1]-b[1])/x]}function e(t){return[t[0]*x+b[0],t[1]*x+b[1]]}function r(t){x=Math.max(_[0],Math.min(_[1],t))}function u(t,n){n=e(n),b[0]+=t[0]-n[0],b[1]+=t[1]-n[1]}function i(){m&&m.domain(d.range().map(function(t){return(t-b[0])/x}).map(d.invert)),y&&y.domain(v.range().map(function(t){return(t-b[1])/x}).map(v.invert))}function a(t){i(),qi.event.preventDefault(),t({type:"zoom",scale:x,translate:b})}function o(){function t(){l=1,u(qi.mouse(i),s),a(o)}function e(){l&&j(),f.on("mousemove.zoom",null).on("mouseup.zoom",null),l&&qi.event.target===c&&f.on("click.zoom",r,!0)}function r(){j(),f.on("click.zoom",null)}var i=this,o=w.of(i,arguments),c=qi.event.target,l=0,f=qi.select(Li).on("mousemove.zoom",t).on("mouseup.zoom",e),s=n(qi.mouse(i));Li.focus(),j()}function c(){g||(g=n(qi.mouse(this))),r(Math.pow(2,.002*Ka())*x),u(qi.mouse(this),g),a(w.of(this,arguments))}function l(){g=null}function f(){var t=qi.mouse(this),e=n(t),i=Math.log(x)/Math.LN2;r(Math.pow(2,qi.event.shiftKey?Math.ceil(i)-1:Math.floor(i)+1)),u(t,e),a(w.of(this,arguments))}function s(){var t=qi.touches(this),e=Date.now();if(p=x,g={},t.forEach(function(t){g[t.identifier]=n(t)}),j(),1===t.length){if(500>e-M){var i=t[0],o=n(t[0]);r(2*x),u(i,o),a(w.of(this,arguments))}M=e}}function h(){var t=qi.touches(this),n=t[0],e=g[n.identifier];if(i=t[1]){var i,o=g[i.identifier];n=[(n[0]+i[0])/2,(n[1]+i[1])/2],e=[(e[0]+o[0])/2,(e[1]+o[1])/2],r(qi.event.scale*p)}u(n,e),M=null,a(w.of(this,arguments))}var g,p,d,m,v,y,M,b=[0,0],x=1,_=Wa,w=R(t,"zoom");return t.translate=function(n){return arguments.length?(b=n.map(Number),i(),t):b},t.scale=function(n){return arguments.length?(x=+n,i(),t):x},t.scaleExtent=function(n){return arguments.length?(_=null==n?Wa:n.map(Number),t):_},t.x=function(n){return arguments.length?(m=n,d=n.copy(),b=[0,0],x=1,t):m},t.y=function(n){return arguments.length?(y=n,v=n.copy(),b=[0,0],x=1,t):y},qi.rebind(t,w,"on")};var Ka,Wa=[0,1/0],Qa="onwheel"in document?(Ka=function(){return-qi.event.deltaY*(qi.event.deltaMode?120:1)},"wheel"):"onmousewheel"in document?(Ka=function(){return qi.event.wheelDelta},"mousewheel"):(Ka=function(){return-qi.event.detail},"MozMousePixelScroll");qi.layout={},qi.layout.bundle=function(){return function(t){for(var n=[],e=-1,r=t.length;r>++e;)n.push(Ve(t[e]));return n}},qi.layout.chord=function(){function t(){var t,l,s,h,g,p={},d=[],m=qi.range(i),v=[];for(e=[],r=[],t=0,h=-1;i>++h;){for(l=0,g=-1;i>++g;)l+=u[h][g];d.push(l),v.push(qi.range(i)),t+=l}for(a&&m.sort(function(t,n){return a(d[t],d[n])}),o&&v.forEach(function(t,n){t.sort(function(t,e){return o(u[n][t],u[n][e])})}),t=(2*Ni-f*i)/t,l=0,h=-1;i>++h;){for(s=l,g=-1;i>++g;){var y=m[h],M=v[y][g],b=u[y][M],x=l,_=l+=b*t;p[y+"-"+M]={index:y,subindex:M,startAngle:x,endAngle:_,value:b}}r[y]={index:y,startAngle:s,endAngle:l,value:(l-s)/t},l+=f}for(h=-1;i>++h;)for(g=h-1;i>++g;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value(u-e)*o){var c=n.charge*o*o;return t.px-=i*c,t.py-=a*c,!0}if(n.point&&isFinite(o)){var c=n.pointCharge*o*o;t.px-=i*c,t.py-=a*c}}return!n.charge}}function n(t){t.px=qi.event.x,t.py=qi.event.y,c.resume()}var e,r,u,i,o,c={},l=qi.dispatch("start","tick","end"),f=[1,1],s=.9,h=to,g=no,p=-30,d=.1,m=.8,v=[],y=[];return c.tick=function(){if(.005>(r*=.99))return l.end({type:"end",alpha:r=0}),!0;var n,e,a,c,h,g,m,M,b,x=v.length,_=y.length;for(e=0;_>e;++e)a=y[e],c=a.source,h=a.target,M=h.x-c.x,b=h.y-c.y,(g=M*M+b*b)&&(g=r*i[e]*((g=Math.sqrt(g))-u[e])/g,M*=g,b*=g,h.x-=M*(m=c.weight/(h.weight+c.weight)),h.y-=b*m,c.x+=M*(m=1-m),c.y+=b*m);if((m=r*d)&&(M=f[0]/2,b=f[1]/2,e=-1,m))for(;x>++e;)a=v[e],a.x+=(M-a.x)*m,a.y+=(b-a.y)*m;if(p)for(Ke(n=qi.geom.quadtree(v),r,o),e=-1;x>++e;)(a=v[e]).fixed||n.visit(t(a));for(e=-1;x>++e;)a=v[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);l.tick({type:"tick",alpha:r})},c.nodes=function(t){return arguments.length?(v=t,c):v},c.links=function(t){return arguments.length?(y=t,c):y},c.size=function(t){return arguments.length?(f=t,c):f},c.linkDistance=function(t){return arguments.length?(h="function"==typeof t?t:+t,c):h},c.distance=c.linkDistance,c.linkStrength=function(t){return arguments.length?(g="function"==typeof t?t:+t,c):g},c.friction=function(t){return arguments.length?(s=+t,c):s},c.charge=function(t){return arguments.length?(p="function"==typeof t?t:+t,c):p},c.gravity=function(t){return arguments.length?(d=+t,c):d},c.theta=function(t){return arguments.length?(m=+t,c):m},c.alpha=function(t){return arguments.length?(t=+t,r?r=t>0?t:0:t>0&&(l.start({type:"start",alpha:r=t}),qi.timer(c.tick)),c):r},c.start=function(){function t(t,r){for(var u,i=n(e),a=-1,o=i.length;o>++a;)if(!isNaN(u=i[a][t]))return u; -return Math.random()*r}function n(){if(!a){for(a=[],r=0;s>r;++r)a[r]=[];for(r=0;d>r;++r){var t=y[r];a[t.source.index].push(t.target),a[t.target.index].push(t.source)}}return a[e]}var e,r,a,l,s=v.length,d=y.length,m=f[0],M=f[1];for(e=0;s>e;++e)(l=v[e]).index=e,l.weight=0;for(e=0;d>e;++e)l=y[e],"number"==typeof l.source&&(l.source=v[l.source]),"number"==typeof l.target&&(l.target=v[l.target]),++l.source.weight,++l.target.weight;for(e=0;s>e;++e)l=v[e],isNaN(l.x)&&(l.x=t("x",m)),isNaN(l.y)&&(l.y=t("y",M)),isNaN(l.px)&&(l.px=l.x),isNaN(l.py)&&(l.py=l.y);if(u=[],"function"==typeof h)for(e=0;d>e;++e)u[e]=+h.call(this,y[e],e);else for(e=0;d>e;++e)u[e]=h;if(i=[],"function"==typeof g)for(e=0;d>e;++e)i[e]=+g.call(this,y[e],e);else for(e=0;d>e;++e)i[e]=g;if(o=[],"function"==typeof p)for(e=0;s>e;++e)o[e]=+p.call(this,v[e],e);else for(e=0;s>e;++e)o[e]=p;return c.resume()},c.resume=function(){return c.alpha(.1)},c.stop=function(){return c.alpha(0)},c.drag=function(){return e||(e=qi.behavior.drag().origin(a).on("dragstart.force",Be).on("drag.force",n).on("dragend.force",$e)),arguments.length?(this.on("mouseover.force",Je).on("mouseout.force",Ge).call(e),void 0):e},qi.rebind(c,l,"on")};var to=20,no=1;qi.layout.partition=function(){function t(n,e,r,u){var i=n.children;if(n.x=e,n.y=n.depth*u,n.dx=r,n.dy=u,i&&(a=i.length)){var a,o,c,l=-1;for(r=n.value?r/n.value:0;a>++l;)t(o=i[l],e,c=o.value*r,u),e+=c}}function n(t){var e=t.children,r=0;if(e&&(u=e.length))for(var u,i=-1;u>++i;)r=Math.max(r,n(e[i]));return 1+r}function e(e,i){var a=r.call(this,e,i);return t(a[0],0,u[0],u[1]/n(a[0])),a}var r=qi.layout.hierarchy(),u=[1,1];return e.size=function(t){return arguments.length?(u=t,e):u},lr(e,r)},qi.layout.pie=function(){function t(i){var a=i.map(function(e,r){return+n.call(t,e,r)}),o=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-r)/qi.sum(a),l=qi.range(i.length);null!=e&&l.sort(e===eo?function(t,n){return a[n]-a[t]}:function(t,n){return e(i[t],i[n])});var f=[];return l.forEach(function(t){var n;f[t]={data:i[t],value:n=a[t],startAngle:o,endAngle:o+=n*c}}),f}var n=Number,e=eo,r=0,u=2*Ni;return t.value=function(e){return arguments.length?(n=e,t):n},t.sort=function(n){return arguments.length?(e=n,t):e},t.startAngle=function(n){return arguments.length?(r=n,t):r},t.endAngle=function(n){return arguments.length?(u=n,t):u},t};var eo={};qi.layout.stack=function(){function t(a,c){var l=a.map(function(e,r){return n.call(t,e,r)}),f=l.map(function(n){return n.map(function(n,e){return[i.call(t,n,e),o.call(t,n,e)]})}),s=e.call(t,f,c);l=qi.permute(l,s),f=qi.permute(f,s);var h,g,p,d=r.call(t,f,c),m=l.length,v=l[0].length;for(g=0;v>g;++g)for(u.call(t,l[0][g],p=d[g],f[0][g][1]),h=1;m>h;++h)u.call(t,l[h][g],p+=f[h-1][g][1],f[h][g][1]);return a}var n=a,e=nr,r=er,u=tr,i=We,o=Qe;return t.values=function(e){return arguments.length?(n=e,t):n},t.order=function(n){return arguments.length?(e="function"==typeof n?n:ro.get(n)||nr,t):e},t.offset=function(n){return arguments.length?(r="function"==typeof n?n:uo.get(n)||er,t):r},t.x=function(n){return arguments.length?(i=n,t):i},t.y=function(n){return arguments.length?(o=n,t):o},t.out=function(n){return arguments.length?(u=n,t):u},t};var ro=qi.map({"inside-out":function(t){var n,e,r=t.length,u=t.map(rr),i=t.map(ur),a=qi.range(r).sort(function(t,n){return u[t]-u[n]}),o=0,c=0,l=[],f=[];for(n=0;r>n;++n)e=a[n],c>o?(o+=i[e],l.push(e)):(c+=i[e],f.push(e));return f.reverse().concat(l)},reverse:function(t){return qi.range(t.length).reverse()},"default":nr}),uo=qi.map({silhouette:function(t){var n,e,r,u=t.length,i=t[0].length,a=[],o=0,c=[];for(e=0;i>e;++e){for(n=0,r=0;u>n;n++)r+=t[n][e][1];r>o&&(o=r),a.push(r)}for(e=0;i>e;++e)c[e]=(o-a[e])/2;return c},wiggle:function(t){var n,e,r,u,i,a,o,c,l,f=t.length,s=t[0],h=s.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(n=0,u=0;f>n;++n)u+=t[n][e][1];for(n=0,i=0,o=s[e][0]-s[e-1][0];f>n;++n){for(r=0,a=(t[n][e][1]-t[n][e-1][1])/(2*o);n>r;++r)a+=(t[r][e][1]-t[r][e-1][1])/o;i+=a*t[n][e][1]}g[e]=c-=u?i/u*o:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(t){var n,e,r,u=t.length,i=t[0].length,a=1/u,o=[];for(e=0;i>e;++e){for(n=0,r=0;u>n;n++)r+=t[n][e][1];if(r)for(n=0;u>n;n++)t[n][e][1]/=r;else for(n=0;u>n;n++)t[n][e][1]=a}for(e=0;i>e;++e)o[e]=0;return o},zero:er});qi.layout.histogram=function(){function t(t,i){for(var a,o,c=[],l=t.map(e,this),f=r.call(this,l,i),s=u.call(this,f,l,i),i=-1,h=l.length,g=s.length-1,p=n?1:1/h;g>++i;)a=c[i]=[],a.dx=s[i+1]-(a.x=s[i]),a.y=0;if(g>0)for(i=-1;h>++i;)o=l[i],o>=f[0]&&f[1]>=o&&(a=c[qi.bisect(s,o,1,g)-1],a.y+=p,a.push(t[i]));return c}var n=!0,e=Number,r=cr,u=ar;return t.value=function(n){return arguments.length?(e=n,t):e},t.range=function(n){return arguments.length?(r=c(n),t):r},t.bins=function(n){return arguments.length?(u="number"==typeof n?function(t){return or(t,n)}:c(n),t):u},t.frequency=function(e){return arguments.length?(n=!!e,t):n},t},qi.layout.hierarchy=function(){function t(n,a,o){var c=u.call(e,n,a);if(n.depth=a,o.push(n),c&&(l=c.length)){for(var l,f,s=-1,h=n.children=[],g=0,p=a+1;l>++s;)f=t(c[s],p,o),f.parent=n,h.push(f),g+=f.value;r&&h.sort(r),i&&(n.value=g)}else i&&(n.value=+i.call(e,n,a)||0);return n}function n(t,r){var u=t.children,a=0;if(u&&(o=u.length))for(var o,c=-1,l=r+1;o>++c;)a+=n(u[c],l);else i&&(a=+i.call(e,t,r)||0);return i&&(t.value=a),a}function e(n){var e=[];return t(n,0,e),e}var r=hr,u=fr,i=sr;return e.sort=function(t){return arguments.length?(r=t,e):r},e.children=function(t){return arguments.length?(u=t,e):u},e.value=function(t){return arguments.length?(i=t,e):i},e.revalue=function(t){return n(t,0),t},e},qi.layout.pack=function(){function t(t,u){var i=n.call(this,t,u),a=i[0];a.x=0,a.y=0,Lr(a,function(t){t.r=Math.sqrt(t.value)}),Lr(a,yr);var o=r[0],c=r[1],l=Math.max(2*a.r/o,2*a.r/c);if(e>0){var f=e*l/2;Lr(a,function(t){t.r+=f}),Lr(a,yr),Lr(a,function(t){t.r-=f}),l=Math.max(2*a.r/o,2*a.r/c)}return xr(a,o/2,c/2,1/l),i}var n=qi.layout.hierarchy().sort(pr),e=0,r=[1,1];return t.size=function(n){return arguments.length?(r=n,t):r},t.padding=function(n){return arguments.length?(e=+n,t):e},lr(t,n)},qi.layout.cluster=function(){function t(t,u){var i,a=n.call(this,t,u),o=a[0],c=0;Lr(o,function(t){var n=t.children;n&&n.length?(t.x=Sr(n),t.y=wr(n)):(t.x=i?c+=e(t,i):0,t.y=0,i=t)});var l=kr(o),f=Er(o),s=l.x-e(l,f)/2,h=f.x+e(f,l)/2;return Lr(o,function(t){t.x=(t.x-s)/(h-s)*r[0],t.y=(1-(o.y?t.y/o.y:1))*r[1]}),a}var n=qi.layout.hierarchy().sort(null).value(null),e=Ar,r=[1,1];return t.separation=function(n){return arguments.length?(e=n,t):e},t.size=function(n){return arguments.length?(r=n,t):r},lr(t,n)},qi.layout.tree=function(){function t(t,u){function i(t,n){var r=t.children,u=t._tree;if(r&&(a=r.length)){for(var a,c,l,f=r[0],s=f,h=-1;a>++h;)l=r[h],i(l,c),s=o(l,c,s),c=l;Fr(t);var g=.5*(f._tree.prelim+l._tree.prelim);n?(u.prelim=n._tree.prelim+e(t,n),u.mod=u.prelim-g):u.prelim=g}else n&&(u.prelim=n._tree.prelim+e(t,n))}function a(t,n){t.x=t._tree.prelim+n;var e=t.children;if(e&&(r=e.length)){var r,u=-1;for(n+=t._tree.mod;r>++u;)a(e[u],n)}}function o(t,n,r){if(n){for(var u,i=t,a=t,o=n,c=t.parent.children[0],l=i._tree.mod,f=a._tree.mod,s=o._tree.mod,h=c._tree.mod;o=Tr(o),i=Nr(i),o&&i;)c=Nr(c),a=Tr(a),a._tree.ancestor=t,u=o._tree.prelim+s-i._tree.prelim-l+e(o,i),u>0&&(Hr(jr(o,t,r),t,u),l+=u,f+=u),s+=o._tree.mod,l+=i._tree.mod,h+=c._tree.mod,f+=a._tree.mod;o&&!Tr(a)&&(a._tree.thread=o,a._tree.mod+=s-f),i&&!Nr(c)&&(c._tree.thread=i,c._tree.mod+=l-h,r=t)}return r}var c=n.call(this,t,u),l=c[0];Lr(l,function(t,n){t._tree={ancestor:t,prelim:0,mod:0,change:0,shift:0,number:n?n._tree.number+1:0}}),i(l),a(l,-l._tree.prelim);var f=qr(l,zr),s=qr(l,Cr),h=qr(l,Dr),g=f.x-e(f,s)/2,p=s.x+e(s,f)/2,d=h.depth||1;return Lr(l,function(t){t.x=(t.x-g)/(p-g)*r[0],t.y=t.depth/d*r[1],delete t._tree}),c}var n=qi.layout.hierarchy().sort(null).value(null),e=Ar,r=[1,1];return t.separation=function(n){return arguments.length?(e=n,t):e},t.size=function(n){return arguments.length?(r=n,t):r},lr(t,n)},qi.layout.treemap=function(){function t(t,n){for(var e,r,u=-1,i=t.length;i>++u;)r=(e=t[u]).value*(0>n?0:n),e.area=isNaN(r)||0>=r?0:r}function n(e){var i=e.children;if(i&&i.length){var a,o,c,l=s(e),f=[],h=i.slice(),p=1/0,d="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(t(h,l.dx*l.dy/e.value),f.area=0;(c=h.length)>0;)f.push(a=h[c-1]),f.area+=a.area,"squarify"!==g||p>=(o=r(f,d))?(h.pop(),p=o):(f.area-=f.pop().area,u(f,d,l,!1),d=Math.min(l.dx,l.dy),f.length=f.area=0,p=1/0);f.length&&(u(f,d,l,!0),f.length=f.area=0),i.forEach(n)}}function e(n){var r=n.children;if(r&&r.length){var i,a=s(n),o=r.slice(),c=[];for(t(o,a.dx*a.dy/n.value),c.area=0;i=o.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?a.dx:a.dy,a,!o.length),c.length=c.area=0);r.forEach(e)}}function r(t,n){for(var e,r=t.area,u=0,i=1/0,a=-1,o=t.length;o>++a;)(e=t[a].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,n*=n,r?Math.max(n*u*p/r,r/(n*i*p)):1/0}function u(t,n,e,r){var u,i=-1,a=t.length,o=e.x,l=e.y,f=n?c(t.area/n):0;if(n==e.dx){for((r||f>e.dy)&&(f=e.dy);a>++i;)u=t[i],u.x=o,u.y=l,u.dy=f,o+=u.dx=Math.min(e.x+e.dx-o,f?c(u.area/f):0);u.z=!0,u.dx+=e.x+e.dx-o,e.y+=f,e.dy-=f}else{for((r||f>e.dx)&&(f=e.dx);a>++i;)u=t[i],u.x=o,u.y=l,u.dx=f,l+=u.dy=Math.min(e.y+e.dy-l,f?c(u.area/f):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=f,e.dx-=f}}function i(r){var u=a||o(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],a&&o.revalue(i),t([i],i.dx*i.dy/i.value),(a?e:n)(i),h&&(a=u),u}var a,o=qi.layout.hierarchy(),c=Math.round,l=[1,1],f=null,s=Pr,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(t){return arguments.length?(l=t,i):l},i.padding=function(t){function n(n){var e=t.call(i,n,n.depth);return null==e?Pr(n):Rr(n,"number"==typeof e?[e,e,e,e]:e)}function e(n){return Rr(n,t)}if(!arguments.length)return f;var r;return s=null==(f=t)?Pr:"function"==(r=typeof t)?n:"number"===r?(t=[t,t,t,t],e):e,i},i.round=function(t){return arguments.length?(c=t?Math.round:Number,i):c!=Number},i.sticky=function(t){return arguments.length?(h=t,a=null,i):h},i.ratio=function(t){return arguments.length?(p=t,i):p},i.mode=function(t){return arguments.length?(g=t+"",i):g},lr(i,o)},qi.csv=Or(",","text/csv"),qi.tsv=Or(" ","text/tab-separated-values"),qi.geo={},qi.geo.stream=function(t,n){io.hasOwnProperty(t.type)?io[t.type](t,n):Yr(t,n)};var io={Feature:function(t,n){Yr(t.geometry,n)},FeatureCollection:function(t,n){for(var e=t.features,r=-1,u=e.length;u>++r;)Yr(e[r].geometry,n)}},ao={Sphere:function(t,n){n.sphere()},Point:function(t,n){var e=t.coordinates;n.point(e[0],e[1])},MultiPoint:function(t,n){for(var e,r=t.coordinates,u=-1,i=r.length;i>++u;)e=r[u],n.point(e[0],e[1])},LineString:function(t,n){Ur(t.coordinates,n,0)},MultiLineString:function(t,n){for(var e=t.coordinates,r=-1,u=e.length;u>++r;)Ur(e[r],n,0)},Polygon:function(t,n){Ir(t.coordinates,n)},MultiPolygon:function(t,n){for(var e=t.coordinates,r=-1,u=e.length;u>++r;)Ir(e[r],n)},GeometryCollection:function(t,n){for(var e=t.geometries,r=-1,u=e.length;u>++r;)Yr(e[r],n)}};qi.geo.albersUsa=function(){function t(t){return n(t)(t)}function n(t){var n=t[0],a=t[1];return a>50?r:-140>n?u:21>a?i:e}var e=qi.geo.albers(),r=qi.geo.albers().rotate([160,0]).center([0,60]).parallels([55,65]),u=qi.geo.albers().rotate([160,0]).center([0,20]).parallels([8,18]),i=qi.geo.albers().rotate([60,0]).center([0,10]).parallels([8,18]);return t.scale=function(n){return arguments.length?(e.scale(n),r.scale(.6*n),u.scale(n),i.scale(1.5*n),t.translate(e.translate())):e.scale()},t.translate=function(n){if(!arguments.length)return e.translate();var a=e.scale(),o=n[0],c=n[1];return e.translate(n),r.translate([o-.4*a,c+.17*a]),u.translate([o-.19*a,c+.2*a]),i.translate([o+.58*a,c+.43*a]),t},t.scale(e.scale())},(qi.geo.albers=function(){var t=29.5*Ci,n=45.5*Ci,e=Fu(Qr),r=e(t,n);return r.parallels=function(r){return arguments.length?e(t=r[0]*Ci,n=r[1]*Ci):[t*zi,n*zi]},r.rotate([98,0]).center([0,38]).scale(1e3)}).raw=Qr;var oo=Yu(function(t){return Math.sqrt(2/(1+t))},function(t){return 2*Math.asin(t/2)});(qi.geo.azimuthalEqualArea=function(){return Lu(oo)}).raw=oo;var co=Yu(function(t){var n=Math.acos(t);return n&&n/Math.sin(n)},a);(qi.geo.azimuthalEquidistant=function(){return Lu(co)}).raw=co,qi.geo.bounds=tu(a),qi.geo.centroid=function(t){lo=fo=so=ho=go=0,qi.geo.stream(t,po);var n;return fo&&Math.abs(n=Math.sqrt(so*so+ho*ho+go*go))>Ti?[Math.atan2(ho,so)*zi,Math.asin(Math.max(-1,Math.min(1,go/n)))*zi]:void 0};var lo,fo,so,ho,go,po={sphere:function(){2>lo&&(lo=2,fo=so=ho=go=0)},point:nu,lineStart:ru,lineEnd:uu,polygonStart:function(){2>lo&&(lo=2,fo=so=ho=go=0),po.lineStart=eu},polygonEnd:function(){po.lineStart=ru}};qi.geo.circle=function(){function t(){var t="function"==typeof r?r.apply(this,arguments):r,n=ju(-t[0]*Ci,-t[1]*Ci,0).invert,u=[];return e(null,null,1,{point:function(t,e){u.push(t=n(t,e)),t[0]*=zi,t[1]*=zi}}),{type:"Polygon",coordinates:[u]}}var n,e,r=[0,0],u=6;return t.origin=function(n){return arguments.length?(r=n,t):r},t.angle=function(r){return arguments.length?(e=iu((n=+r)*Ci,u*Ci),t):n},t.precision=function(r){return arguments.length?(e=iu(n*Ci,(u=+r)*Ci),t):u},t.angle(90)};var mo=ou(o,pu,mu);(qi.geo.equirectangular=function(){return Lu(Mu).scale(250/Ni)}).raw=Mu.invert=Mu;var vo=Yu(function(t){return 1/t},Math.atan);(qi.geo.gnomonic=function(){return Lu(vo)}).raw=vo,qi.geo.graticule=function(){function t(){return{type:"MultiLineString",coordinates:n()}}function n(){return qi.range(Math.ceil(r/c)*c,e,c).map(a).concat(qi.range(Math.ceil(i/l)*l,u,l).map(o))}var e,r,u,i,a,o,c=22.5,l=c,f=2.5;return t.lines=function(){return n().map(function(t){return{type:"LineString",coordinates:t}})},t.outline=function(){return{type:"Polygon",coordinates:[a(r).concat(o(u).slice(1),a(e).reverse().slice(1),o(i).reverse().slice(1))]}},t.extent=function(n){return arguments.length?(r=+n[0][0],e=+n[1][0],i=+n[0][1],u=+n[1][1],r>e&&(n=r,r=e,e=n),i>u&&(n=i,i=u,u=n),t.precision(f)):[[r,i],[e,u]]},t.step=function(n){return arguments.length?(c=+n[0],l=+n[1],t):[c,l]},t.precision=function(n){return arguments.length?(f=+n,a=bu(i,u,f),o=xu(r,e,f),t):f},t.extent([[-180+Ti,-90+Ti],[180-Ti,90-Ti]])},qi.geo.interpolate=function(t,n){return _u(t[0]*Ci,t[1]*Ci,n[0]*Ci,n[1]*Ci)},qi.geo.greatArc=function(){function e(){for(var t=r||a.apply(this,arguments),n=u||o.apply(this,arguments),e=i||qi.geo.interpolate(t,n),l=0,f=c/e.distance,s=[t];1>(l+=f);)s.push(e(l));return s.push(n),{type:"LineString",coordinates:s}}var r,u,i,a=n,o=t,c=6*Ci;return e.distance=function(){return(i||qi.geo.interpolate(r||a.apply(this,arguments),u||o.apply(this,arguments))).distance},e.source=function(t){return arguments.length?(a=t,r="function"==typeof t?null:t,i=r&&u?qi.geo.interpolate(r,u):null,e):a},e.target=function(t){return arguments.length?(o=t,u="function"==typeof t?null:t,i=r&&u?qi.geo.interpolate(r,u):null,e):o},e.precision=function(t){return arguments.length?(c=t*Ci,e):c/Ci},e},wu.invert=function(t,n){return[2*Ni*t,2*Math.atan(Math.exp(2*Ni*n))-Ni/2]},(qi.geo.mercator=function(){return Lu(wu).scale(500)}).raw=wu;var yo=Yu(function(){return 1},Math.asin);(qi.geo.orthographic=function(){return Lu(yo)}).raw=yo,qi.geo.path=function(){function t(t){return t&&qi.geo.stream(t,r(u.pointRadius("function"==typeof i?+i.apply(this,arguments):i))),u.result()}var n,e,r,u,i=4.5;return t.area=function(t){return Mo=0,qi.geo.stream(t,r(xo)),Mo},t.centroid=function(t){return lo=so=ho=go=0,qi.geo.stream(t,r(_o)),go?[so/go,ho/go]:void 0},t.bounds=function(t){return tu(r)(t)},t.projection=function(e){return arguments.length?(r=(n=e)?e.stream||ku(e):a,t):n},t.context=function(n){return arguments.length?(u=null==(e=n)?new Eu:new Au(n),t):e},t.pointRadius=function(n){return arguments.length?(i="function"==typeof n?n:+n,t):i},t.projection(qi.geo.albersUsa()).context(null)};var Mo,bo,xo={point:Pn,lineStart:Pn,lineEnd:Pn,polygonStart:function(){bo=0,xo.lineStart=Nu},polygonEnd:function(){xo.lineStart=xo.lineEnd=xo.point=Pn,Mo+=Math.abs(bo/2)}},_o={point:Tu,lineStart:qu,lineEnd:Cu,polygonStart:function(){_o.lineStart=zu},polygonEnd:function(){_o.point=Tu,_o.lineStart=qu,_o.lineEnd=Cu}};qi.geo.area=function(t){return wo=0,qi.geo.stream(t,Eo),wo};var wo,So,ko,Eo={sphere:function(){wo+=4*Ni},point:Pn,lineStart:Pn,lineEnd:Pn,polygonStart:function(){So=1,ko=0,Eo.lineStart=Du},polygonEnd:function(){var t=2*Math.atan2(ko,So);wo+=0>t?4*Ni+t:t,Eo.lineStart=Eo.lineEnd=Eo.point=Pn}};qi.geo.projection=Lu,qi.geo.projectionMutator=Fu;var Ao=Yu(function(t){return 1/(1+t)},function(t){return 2*Math.atan(t)});(qi.geo.stereographic=function(){return Lu(Ao)}).raw=Ao,qi.geom={},qi.geom.hull=function(t){if(3>t.length)return[];var n,e,r,u,i,a,o,c,l,f,s=t.length,h=s-1,g=[],p=[],d=0;for(n=1;s>n;++n)t[n][1]n;++n)n!==d&&(u=t[n][1]-t[d][1],r=t[n][0]-t[d][0],g.push({angle:Math.atan2(u,r),index:n}));for(g.sort(function(t,n){return t.angle-n.angle}),l=g[0].angle,c=g[0].index,o=0,n=1;h>n;++n)e=g[n].index,l==g[n].angle?(r=t[c][0]-t[d][0],u=t[c][1]-t[d][1],i=t[e][0]-t[d][0],a=t[e][1]-t[d][1],r*r+u*u>=i*i+a*a?g[n].index=-1:(g[o].index=-1,l=g[n].angle,o=n,c=e)):(l=g[n].angle,o=n,c=e);for(p.push(d),n=0,e=0;2>n;++e)-1!==g[e].index&&(p.push(g[e].index),n++);for(f=p.length;h>e;++e)if(-1!==g[e].index){for(;!Uu(p[f-2],p[f-1],g[e].index,t);)--f;p[f++]=g[e].index}var m=[];for(n=0;f>n;++n)m.push(t[p[n]]);return m},qi.geom.polygon=function(t){return t.area=function(){for(var n=0,e=t.length,r=t[e-1][1]*t[0][0]-t[e-1][0]*t[0][1];e>++n;)r+=t[n-1][1]*t[n][0]-t[n-1][0]*t[n][1];return.5*r},t.centroid=function(n){var e,r,u=-1,i=t.length,a=0,o=0,c=t[i-1];for(arguments.length||(n=-1/(6*t.area()));i>++u;)e=c,c=t[u],r=e[0]*c[1]-c[0]*e[1],a+=(e[0]+c[0])*r,o+=(e[1]+c[1])*r;return[a*n,o*n]},t.clip=function(n){for(var e,r,u,i,a,o,c=-1,l=t.length,f=t[l-1];l>++c;){for(e=n.slice(),n.length=0,i=t[c],a=e[(u=e.length)-1],r=-1;u>++r;)o=e[r],Iu(o,f,i)?(Iu(a,f,i)||n.push(Vu(a,o,f,i)),n.push(o)):Iu(a,f,i)&&n.push(Vu(a,o,f,i)),a=o;f=i}return n},t},qi.geom.voronoi=function(t){var n=t.map(function(){return[]}),e=1e6;return Xu(t,function(t){var r,u,i,a,o,c;1===t.a&&t.b>=0?(r=t.ep.r,u=t.ep.l):(r=t.ep.l,u=t.ep.r),1===t.a?(o=r?r.y:-e,i=t.c-t.b*o,c=u?u.y:e,a=t.c-t.b*c):(i=r?r.x:-e,o=t.c-t.a*i,a=u?u.x:e,c=t.c-t.a*a);var l=[i,o],f=[a,c];n[t.region.l.index].push(l,f),n[t.region.r.index].push(l,f)}),n=n.map(function(n,e){var r=t[e][0],u=t[e][1],i=n.map(function(t){return Math.atan2(t[0]-r,t[1]-u)}),a=qi.range(n.length).sort(function(t,n){return i[t]-i[n]});return a.filter(function(t,n){return!n||i[t]-i[a[n-1]]>Ti}).map(function(t){return n[t]})}),n.forEach(function(n,r){var u=n.length;if(!u)return n.push([-e,-e],[-e,e],[e,e],[e,-e]);if(!(u>2)){var i=t[r],a=n[0],o=n[1],c=i[0],l=i[1],f=a[0],s=a[1],h=o[0],g=o[1],p=Math.abs(h-f),d=g-s;if(Ti>Math.abs(d)){var m=s>l?-e:e;n.push([-e,m],[e,m])}else if(Ti>p){var v=f>c?-e:e;n.push([v,-e],[v,e])}else{var m=(f-c)*(g-s)>(h-f)*(s-l)?e:-e,y=Math.abs(d)-p;Ti>Math.abs(y)?n.push([0>d?m:-m,m]):(y>0&&(m*=-1),n.push([-e,m],[e,m]))}}}),n};var No={l:"r",r:"l"};qi.geom.delaunay=function(t){var n=t.map(function(){return[]}),e=[];return Xu(t,function(e){n[e.region.l.index].push(t[e.region.r.index])}),n.forEach(function(n,r){var u=t[r],i=u[0],a=u[1];n.forEach(function(t){t.angle=Math.atan2(t[0]-i,t[1]-a)}),n.sort(function(t,n){return t.angle-n.angle});for(var o=0,c=n.length-1;c>o;o++)e.push([u,n[o],n[o+1]])}),e},qi.geom.quadtree=function(t,n,e,r,u){function i(t,n,e,r,u,i){if(!isNaN(n.x)&&!isNaN(n.y))if(t.leaf){var o=t.point;o?.01>Math.abs(o.x-n.x)+Math.abs(o.y-n.y)?a(t,n,e,r,u,i):(t.point=null,a(t,o,e,r,u,i),a(t,n,e,r,u,i)):t.point=n}else a(t,n,e,r,u,i)}function a(t,n,e,r,u,a){var o=.5*(e+u),c=.5*(r+a),l=n.x>=o,f=n.y>=c,s=(f<<1)+l;t.leaf=!1,t=t.nodes[s]||(t.nodes[s]=Zu()),l?e=o:u=o,f?r=c:a=c,i(t,n,e,r,u,a)}var o,c=-1,l=t.length;if(5>arguments.length)if(3===arguments.length)u=e,r=n,e=n=0;else for(n=e=1/0,r=u=-1/0;l>++c;)o=t[c],n>o.x&&(n=o.x),e>o.y&&(e=o.y),o.x>r&&(r=o.x),o.y>u&&(u=o.y);var f=r-n,s=u-e;f>s?u=e+f:r=n+s;var h=Zu();return h.add=function(t){i(h,t,n,e,r,u)},h.visit=function(t){Bu(t,h,n,e,r,u)},t.forEach(h.add),h},qi.time={};var To=Date,qo=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];$u.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){Co.setUTCDate.apply(this._,arguments)},setDay:function(){Co.setUTCDay.apply(this._,arguments)},setFullYear:function(){Co.setUTCFullYear.apply(this._,arguments)},setHours:function(){Co.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){Co.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){Co.setUTCMinutes.apply(this._,arguments)},setMonth:function(){Co.setUTCMonth.apply(this._,arguments)},setSeconds:function(){Co.setUTCSeconds.apply(this._,arguments)},setTime:function(){Co.setTime.apply(this._,arguments)}};var Co=Date.prototype,zo="%a %b %e %X %Y",Do="%m/%d/%Y",Lo="%H:%M:%S",Fo=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Ho=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],jo=["January","February","March","April","May","June","July","August","September","October","November","December"],Po=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];qi.time.format=function(t){function n(n){for(var r,u,i,a=[],o=-1,c=0;e>++o;)37===t.charCodeAt(o)&&(a.push(t.substring(c,o)),null!=(u=Xo[r=t.charAt(++o)])&&(r=t.charAt(++o)),(i=Zo[r])&&(r=i(n,null==u?"e"===r?" ":"0":u)),a.push(r),c=o+1);return a.push(t.substring(c,o)),a.join("")}var e=t.length;return n.parse=function(n){var e={y:1900,m:0,d:1,H:0,M:0,S:0,L:0},r=Ju(e,t,n,0);if(r!=n.length)return null;"p"in e&&(e.H=e.H%12+12*e.p);var u=new To;return u.setFullYear(e.y,e.m,e.d),u.setHours(e.H,e.M,e.S,e.L),u},n.toString=function(){return t},n};var Ro=Gu(Fo),Oo=Gu(Ho),Yo=Gu(jo),Uo=Ku(jo),Io=Gu(Po),Vo=Ku(Po),Xo={"-":"",_:" ",0:"0"},Zo={a:function(t){return Ho[t.getDay()]},A:function(t){return Fo[t.getDay()]},b:function(t){return Po[t.getMonth()]},B:function(t){return jo[t.getMonth()]},c:qi.time.format(zo),d:function(t,n){return Wu(t.getDate(),n,2)},e:function(t,n){return Wu(t.getDate(),n,2)},H:function(t,n){return Wu(t.getHours(),n,2)},I:function(t,n){return Wu(t.getHours()%12||12,n,2)},j:function(t,n){return Wu(1+qi.time.dayOfYear(t),n,3)},L:function(t,n){return Wu(t.getMilliseconds(),n,3)},m:function(t,n){return Wu(t.getMonth()+1,n,2)},M:function(t,n){return Wu(t.getMinutes(),n,2)},p:function(t){return t.getHours()>=12?"PM":"AM"},S:function(t,n){return Wu(t.getSeconds(),n,2)},U:function(t,n){return Wu(qi.time.sundayOfYear(t),n,2)},w:function(t){return t.getDay()},W:function(t,n){return Wu(qi.time.mondayOfYear(t),n,2)},x:qi.time.format(Do),X:qi.time.format(Lo),y:function(t,n){return Wu(t.getFullYear()%100,n,2)},Y:function(t,n){return Wu(t.getFullYear()%1e4,n,4)},Z:mi,"%":function(){return"%"}},Bo={a:Qu,A:ti,b:ni,B:ei,c:ri,d:fi,e:fi,H:si,I:si,L:pi,m:li,M:hi,p:di,S:gi,x:ui,X:ii,y:oi,Y:ai},$o=/^\s*\d+/,Jo=qi.map({am:0,pm:1});qi.time.format.utc=function(t){function n(t){try{To=$u;var n=new To;return n._=t,e(n)}finally{To=Date}}var e=qi.time.format(t);return n.parse=function(t){try{To=$u;var n=e.parse(t);return n&&n._}finally{To=Date}},n.toString=e.toString,n};var Go=qi.time.format.utc("%Y-%m-%dT%H:%M:%S.%LZ");qi.time.format.iso=Date.prototype.toISOString?vi:Go,vi.parse=function(t){var n=new Date(t);return isNaN(n)?null:n},vi.toString=Go.toString,qi.time.second=yi(function(t){return new To(1e3*Math.floor(t/1e3))},function(t,n){t.setTime(t.getTime()+1e3*Math.floor(n))},function(t){return t.getSeconds()}),qi.time.seconds=qi.time.second.range,qi.time.seconds.utc=qi.time.second.utc.range,qi.time.minute=yi(function(t){return new To(6e4*Math.floor(t/6e4))},function(t,n){t.setTime(t.getTime()+6e4*Math.floor(n))},function(t){return t.getMinutes()}),qi.time.minutes=qi.time.minute.range,qi.time.minutes.utc=qi.time.minute.utc.range,qi.time.hour=yi(function(t){var n=t.getTimezoneOffset()/60;return new To(36e5*(Math.floor(t/36e5-n)+n))},function(t,n){t.setTime(t.getTime()+36e5*Math.floor(n))},function(t){return t.getHours()}),qi.time.hours=qi.time.hour.range,qi.time.hours.utc=qi.time.hour.utc.range,qi.time.day=yi(function(t){var n=new To(1970,0);return n.setFullYear(t.getFullYear(),t.getMonth(),t.getDate()),n},function(t,n){t.setDate(t.getDate()+n)},function(t){return t.getDate()-1}),qi.time.days=qi.time.day.range,qi.time.days.utc=qi.time.day.utc.range,qi.time.dayOfYear=function(t){var n=qi.time.year(t);return Math.floor((t-n-6e4*(t.getTimezoneOffset()-n.getTimezoneOffset()))/864e5)},qo.forEach(function(t,n){t=t.toLowerCase(),n=7-n;var e=qi.time[t]=yi(function(t){return(t=qi.time.day(t)).setDate(t.getDate()-(t.getDay()+n)%7),t},function(t,n){t.setDate(t.getDate()+7*Math.floor(n))},function(t){var e=qi.time.year(t).getDay();return Math.floor((qi.time.dayOfYear(t)+(e+n)%7)/7)-(e!==n)});qi.time[t+"s"]=e.range,qi.time[t+"s"].utc=e.utc.range,qi.time[t+"OfYear"]=function(t){var e=qi.time.year(t).getDay();return Math.floor((qi.time.dayOfYear(t)+(e+n)%7)/7)}}),qi.time.week=qi.time.sunday,qi.time.weeks=qi.time.sunday.range,qi.time.weeks.utc=qi.time.sunday.utc.range,qi.time.weekOfYear=qi.time.sundayOfYear,qi.time.month=yi(function(t){return t=qi.time.day(t),t.setDate(1),t},function(t,n){t.setMonth(t.getMonth()+n)},function(t){return t.getMonth()}),qi.time.months=qi.time.month.range,qi.time.months.utc=qi.time.month.utc.range,qi.time.year=yi(function(t){return t=qi.time.day(t),t.setMonth(0,1),t},function(t,n){t.setFullYear(t.getFullYear()+n)},function(t){return t.getFullYear()}),qi.time.years=qi.time.year.range,qi.time.years.utc=qi.time.year.utc.range;var Ko=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Wo=[[qi.time.second,1],[qi.time.second,5],[qi.time.second,15],[qi.time.second,30],[qi.time.minute,1],[qi.time.minute,5],[qi.time.minute,15],[qi.time.minute,30],[qi.time.hour,1],[qi.time.hour,3],[qi.time.hour,6],[qi.time.hour,12],[qi.time.day,1],[qi.time.day,2],[qi.time.week,1],[qi.time.month,1],[qi.time.month,3],[qi.time.year,1]],Qo=[[qi.time.format("%Y"),o],[qi.time.format("%B"),function(t){return t.getMonth()}],[qi.time.format("%b %d"),function(t){return 1!=t.getDate()}],[qi.time.format("%a %d"),function(t){return t.getDay()&&1!=t.getDate()}],[qi.time.format("%I %p"),function(t){return t.getHours()}],[qi.time.format("%I:%M"),function(t){return t.getMinutes()}],[qi.time.format(":%S"),function(t){return t.getSeconds()}],[qi.time.format(".%L"),function(t){return t.getMilliseconds()}]],tc=qi.scale.linear(),nc=wi(Qo);Wo.year=function(t,n){return tc.domain(t.map(ki)).ticks(n).map(Si)},qi.time.scale=function(){return bi(qi.scale.linear(),Wo,nc)};var ec=Wo.map(function(t){return[t[0].utc,t[1]]}),rc=[[qi.time.format.utc("%Y"),o],[qi.time.format.utc("%B"),function(t){return t.getUTCMonth()}],[qi.time.format.utc("%b %d"),function(t){return 1!=t.getUTCDate()}],[qi.time.format.utc("%a %d"),function(t){return t.getUTCDay()&&1!=t.getUTCDate()}],[qi.time.format.utc("%I %p"),function(t){return t.getUTCHours()}],[qi.time.format.utc("%I:%M"),function(t){return t.getUTCMinutes()}],[qi.time.format.utc(":%S"),function(t){return t.getUTCSeconds()}],[qi.time.format.utc(".%L"),function(t){return t.getUTCMilliseconds()}]],uc=wi(rc);return ec.year=function(t,n){return tc.domain(t.map(Ai)).ticks(n).map(Ei)},qi.time.scale.utc=function(){return bi(qi.scale.linear(),ec,uc)},qi}(); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/canvg.js b/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/canvg.js deleted file mode 100755 index a49f0cb930..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/canvg.js +++ /dev/null @@ -1,2610 +0,0 @@ -/* - * canvg.js - Javascript SVG parser and renderer on Canvas - * MIT Licensed - * Gabe Lerner (gabelerner@gmail.com) - * http://code.google.com/p/canvg/ - * - * Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/ - */ -if(!window.console) { - window.console = {}; - window.console.log = function(str) {}; - window.console.dir = function(str) {}; -} - -if(!Array.indexOf){ - Array.prototype.indexOf = function(obj){ - for(var i=0; i ignore mouse events - // ignoreAnimation: true => ignore animations - // ignoreDimensions: true => does not try to resize canvas - // ignoreClear: true => does not clear canvas - // offsetX: int => draws at a x offset - // offsetY: int => draws at a y offset - // scaleWidth: int => scales horizontally to width - // scaleHeight: int => scales vertically to height - // renderCallback: function => will call the function after the first render is completed - // forceRedraw: function => will call the function on every frame, if it returns true, will redraw - this.canvg = function (target, s, opts) { - // no parameters - if (target == null && s == null && opts == null) { - var svgTags = document.getElementsByTagName('svg'); - for (var i=0; i]*>/, ''); - var xmlDoc = new ActiveXObject('Microsoft.XMLDOM'); - xmlDoc.async = 'false'; - xmlDoc.loadXML(xml); - return xmlDoc; - } - } - - svg.Property = function(name, value) { - this.name = name; - this.value = value; - - this.hasValue = function() { - return (this.value != null && this.value !== ''); - } - - // return the numerical value of the property - this.numValue = function() { - if (!this.hasValue()) return 0; - - var n = parseFloat(this.value); - if ((this.value + '').match(/%$/)) { - n = n / 100.0; - } - return n; - } - - this.valueOrDefault = function(def) { - if (this.hasValue()) return this.value; - return def; - } - - this.numValueOrDefault = function(def) { - if (this.hasValue()) return this.numValue(); - return def; - } - - /* EXTENSIONS */ - var that = this; - - // color extensions - this.Color = { - // augment the current color value with the opacity - addOpacity: function(opacity) { - var newValue = that.value; - if (opacity != null && opacity != '') { - var color = new RGBColor(that.value); - if (color.ok) { - newValue = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + opacity + ')'; - } - } - return new svg.Property(that.name, newValue); - } - } - - // definition extensions - this.Definition = { - // get the definition from the definitions table - getDefinition: function() { - var name = that.value.replace(/^(url\()?#([^\)]+)\)?$/, '$2'); - return svg.Definitions[name]; - }, - - isUrl: function() { - return that.value.indexOf('url(') == 0 - }, - - getFillStyle: function(e) { - var def = this.getDefinition(); - - // gradient - if (def != null && def.createGradient) { - return def.createGradient(svg.ctx, e); - } - - // pattern - if (def != null && def.createPattern) { - return def.createPattern(svg.ctx, e); - } - - return null; - } - } - - // length extensions - this.Length = { - DPI: function(viewPort) { - return 96.0; // TODO: compute? - }, - - EM: function(viewPort) { - var em = 12; - - var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize); - if (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort); - - return em; - }, - - // get the length as pixels - toPixels: function(viewPort) { - if (!that.hasValue()) return 0; - var s = that.value+''; - if (s.match(/em$/)) return that.numValue() * this.EM(viewPort); - if (s.match(/ex$/)) return that.numValue() * this.EM(viewPort) / 2.0; - if (s.match(/px$/)) return that.numValue(); - if (s.match(/pt$/)) return that.numValue() * 1.25; - if (s.match(/pc$/)) return that.numValue() * 15; - if (s.match(/cm$/)) return that.numValue() * this.DPI(viewPort) / 2.54; - if (s.match(/mm$/)) return that.numValue() * this.DPI(viewPort) / 25.4; - if (s.match(/in$/)) return that.numValue() * this.DPI(viewPort); - if (s.match(/%$/)) return that.numValue() * svg.ViewPort.ComputeSize(viewPort); - return that.numValue(); - } - } - - // time extensions - this.Time = { - // get the time as milliseconds - toMilliseconds: function() { - if (!that.hasValue()) return 0; - var s = that.value+''; - if (s.match(/s$/)) return that.numValue() * 1000; - if (s.match(/ms$/)) return that.numValue(); - return that.numValue(); - } - } - - // angle extensions - this.Angle = { - // get the angle as radians - toRadians: function() { - if (!that.hasValue()) return 0; - var s = that.value+''; - if (s.match(/deg$/)) return that.numValue() * (Math.PI / 180.0); - if (s.match(/grad$/)) return that.numValue() * (Math.PI / 200.0); - if (s.match(/rad$/)) return that.numValue(); - return that.numValue() * (Math.PI / 180.0); - } - } - } - - // fonts - svg.Font = new (function() { - this.Styles = ['normal','italic','oblique','inherit']; - this.Variants = ['normal','small-caps','inherit']; - this.Weights = ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900','inherit']; - - this.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { - var f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font); - return { - fontFamily: fontFamily || f.fontFamily, - fontSize: fontSize || f.fontSize, - fontStyle: fontStyle || f.fontStyle, - fontWeight: fontWeight || f.fontWeight, - fontVariant: fontVariant || f.fontVariant, - toString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } - } - } - - var that = this; - this.Parse = function(s) { - var f = {}; - var d = svg.trim(svg.compressSpaces(s || '')).split(' '); - var set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false } - var ff = ''; - for (var i=0; i this.x2) this.x2 = x; - } - - if (y != null) { - if (isNaN(this.y1) || isNaN(this.y2)) { - this.y1 = y; - this.y2 = y; - } - if (y < this.y1) this.y1 = y; - if (y > this.y2) this.y2 = y; - } - } - this.addX = function(x) { this.addPoint(x, null); } - this.addY = function(y) { this.addPoint(null, y); } - - this.addBoundingBox = function(bb) { - this.addPoint(bb.x1, bb.y1); - this.addPoint(bb.x2, bb.y2); - } - - this.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) { - var cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0) - var cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0) - var cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0) - var cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0) - this.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y, cp2y, p2x, p2y); - } - - this.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) { - // from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html - var p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y]; - this.addPoint(p0[0], p0[1]); - this.addPoint(p3[0], p3[1]); - - for (i=0; i<=1; i++) { - var f = function(t) { - return Math.pow(1-t, 3) * p0[i] - + 3 * Math.pow(1-t, 2) * t * p1[i] - + 3 * (1-t) * Math.pow(t, 2) * p2[i] - + Math.pow(t, 3) * p3[i]; - } - - var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i]; - var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i]; - var c = 3 * p1[i] - 3 * p0[i]; - - if (a == 0) { - if (b == 0) continue; - var t = -c / b; - if (0 < t && t < 1) { - if (i == 0) this.addX(f(t)); - if (i == 1) this.addY(f(t)); - } - continue; - } - - var b2ac = Math.pow(b, 2) - 4 * c * a; - if (b2ac < 0) continue; - var t1 = (-b + Math.sqrt(b2ac)) / (2 * a); - if (0 < t1 && t1 < 1) { - if (i == 0) this.addX(f(t1)); - if (i == 1) this.addY(f(t1)); - } - var t2 = (-b - Math.sqrt(b2ac)) / (2 * a); - if (0 < t2 && t2 < 1) { - if (i == 0) this.addX(f(t2)); - if (i == 1) this.addY(f(t2)); - } - } - } - - this.isPointInBox = function(x, y) { - return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2); - } - - this.addPoint(x1, y1); - this.addPoint(x2, y2); - } - - // transforms - svg.Transform = function(v) { - var that = this; - this.Type = {} - - // translate - this.Type.translate = function(s) { - this.p = svg.CreatePoint(s); - this.apply = function(ctx) { - ctx.translate(this.p.x || 0.0, this.p.y || 0.0); - } - this.applyToPoint = function(p) { - p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); - } - } - - // rotate - this.Type.rotate = function(s) { - var a = svg.ToNumberArray(s); - this.angle = new svg.Property('angle', a[0]); - this.cx = a[1] || 0; - this.cy = a[2] || 0; - this.apply = function(ctx) { - ctx.translate(this.cx, this.cy); - ctx.rotate(this.angle.Angle.toRadians()); - ctx.translate(-this.cx, -this.cy); - } - this.applyToPoint = function(p) { - var a = this.angle.Angle.toRadians(); - p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]); - p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]); - p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]); - } - } - - this.Type.scale = function(s) { - this.p = svg.CreatePoint(s); - this.apply = function(ctx) { - ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0); - } - this.applyToPoint = function(p) { - p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]); - } - } - - this.Type.matrix = function(s) { - this.m = svg.ToNumberArray(s); - this.apply = function(ctx) { - ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]); - } - this.applyToPoint = function(p) { - p.applyTransform(this.m); - } - } - - this.Type.SkewBase = function(s) { - this.base = that.Type.matrix; - this.base(s); - this.angle = new svg.Property('angle', s); - } - this.Type.SkewBase.prototype = new this.Type.matrix; - - this.Type.skewX = function(s) { - this.base = that.Type.SkewBase; - this.base(s); - this.m = [1, 0, Math.tan(this.angle.Angle.toRadians()), 1, 0, 0]; - } - this.Type.skewX.prototype = new this.Type.SkewBase; - - this.Type.skewY = function(s) { - this.base = that.Type.SkewBase; - this.base(s); - this.m = [1, Math.tan(this.angle.Angle.toRadians()), 0, 1, 0, 0]; - } - this.Type.skewY.prototype = new this.Type.SkewBase; - - this.transforms = []; - - this.apply = function(ctx) { - for (var i=0; i= this.tokens.length - 1; - } - - this.isCommandOrEnd = function() { - if (this.isEnd()) return true; - return this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null; - } - - this.isRelativeCommand = function() { - return this.command == this.command.toLowerCase(); - } - - this.getToken = function() { - this.i = this.i + 1; - return this.tokens[this.i]; - } - - this.getScalar = function() { - return parseFloat(this.getToken()); - } - - this.nextCommand = function() { - this.previousCommand = this.command; - this.command = this.getToken(); - } - - this.getPoint = function() { - var p = new svg.Point(this.getScalar(), this.getScalar()); - return this.makeAbsolute(p); - } - - this.getAsControlPoint = function() { - var p = this.getPoint(); - this.control = p; - return p; - } - - this.getAsCurrentPoint = function() { - var p = this.getPoint(); - this.current = p; - return p; - } - - this.getReflectedControlPoint = function() { - if (this.previousCommand.toLowerCase() != 'c' && this.previousCommand.toLowerCase() != 's') { - return this.current; - } - - // reflect point - var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y); - return p; - } - - this.makeAbsolute = function(p) { - if (this.isRelativeCommand()) { - p.x = this.current.x + p.x; - p.y = this.current.y + p.y; - } - return p; - } - - this.addMarker = function(p, from) { - this.addMarkerAngle(p, from == null ? null : from.angleTo(p)); - } - - this.addMarkerAngle = function(p, a) { - this.points.push(p); - this.angles.push(a); - } - - this.getMarkerPoints = function() { return this.points; } - this.getMarkerAngles = function() { - for (var i=0; i 1) { - rx *= Math.sqrt(l); - ry *= Math.sqrt(l); - } - // cx', cy' - var s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt( - ((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) / - (Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2)) - ); - if (isNaN(s)) s = 0; - var cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx); - // cx, cy - var centp = new svg.Point( - (curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y, - (curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y - ); - // vector magnitude - var m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); } - // ratio between two vectors - var r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) } - // angle between two vectors - var a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); } - // initial angle - var a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]); - // angle delta - var u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]; - var v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry]; - var ad = a(u, v); - if (r(u,v) <= -1) ad = Math.PI; - if (r(u,v) >= 1) ad = 0; - - if (sweepFlag == 0 && ad > 0) ad = ad - 2 * Math.PI; - if (sweepFlag == 1 && ad < 0) ad = ad + 2 * Math.PI; - - // for markers - var halfWay = new svg.Point( - centp.x - rx * Math.cos((a1 + ad) / 2), - centp.y - ry * Math.sin((a1 + ad) / 2) - ); - pp.addMarkerAngle(halfWay, (a1 + ad) / 2 + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2); - pp.addMarkerAngle(cp, ad + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2); - - bb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better - if (ctx != null) { - var r = rx > ry ? rx : ry; - var sx = rx > ry ? 1 : rx / ry; - var sy = rx > ry ? ry / rx : 1; - - ctx.translate(centp.x, centp.y); - ctx.rotate(xAxisRotation); - ctx.scale(sx, sy); - ctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag); - ctx.scale(1/sx, 1/sy); - ctx.rotate(-xAxisRotation); - ctx.translate(-centp.x, -centp.y); - } - } - break; - case 'Z': - if (ctx != null) ctx.closePath(); - pp.current = pp.start; - } - } - - return bb; - } - - this.getMarkers = function() { - var points = this.PathParser.getMarkerPoints(); - var angles = this.PathParser.getMarkerAngles(); - - var markers = []; - for (var i=0; i this.maxDuration) { - // loop for indefinitely repeating animations - if (this.attribute('repeatCount').value == 'indefinite') { - this.duration = 0.0 - } - else if (this.attribute('fill').valueOrDefault('remove') == 'remove' && !this.removed) { - this.removed = true; - this.getProperty().value = this.initialValue; - return true; - } - else { - return false; // no updates made - } - } - this.duration = this.duration + delta; - - // if we're past the begin time - var updated = false; - if (this.begin < this.duration) { - var newValue = this.calcValue(); // tween - - if (this.attribute('type').hasValue()) { - // for transform, etc. - var type = this.attribute('type').value; - newValue = type + '(' + newValue + ')'; - } - - this.getProperty().value = newValue; - updated = true; - } - - return updated; - } - - // fraction of duration we've covered - this.progress = function() { - return ((this.duration - this.begin) / (this.maxDuration - this.begin)); - } - } - svg.Element.AnimateBase.prototype = new svg.Element.ElementBase; - - // animate element - svg.Element.animate = function(node) { - this.base = svg.Element.AnimateBase; - this.base(node); - - this.calcValue = function() { - var from = this.attribute('from').numValue(); - var to = this.attribute('to').numValue(); - - // tween value linearly - return from + (to - from) * this.progress(); - }; - } - svg.Element.animate.prototype = new svg.Element.AnimateBase; - - // animate color element - svg.Element.animateColor = function(node) { - this.base = svg.Element.AnimateBase; - this.base(node); - - this.calcValue = function() { - var from = new RGBColor(this.attribute('from').value); - var to = new RGBColor(this.attribute('to').value); - - if (from.ok && to.ok) { - // tween color linearly - var r = from.r + (to.r - from.r) * this.progress(); - var g = from.g + (to.g - from.g) * this.progress(); - var b = from.b + (to.b - from.b) * this.progress(); - return 'rgb('+parseInt(r,10)+','+parseInt(g,10)+','+parseInt(b,10)+')'; - } - return this.attribute('from').value; - }; - } - svg.Element.animateColor.prototype = new svg.Element.AnimateBase; - - // animate transform element - svg.Element.animateTransform = function(node) { - this.base = svg.Element.animate; - this.base(node); - } - svg.Element.animateTransform.prototype = new svg.Element.animate; - - // font element - svg.Element.font = function(node) { - this.base = svg.Element.ElementBase; - this.base(node); - - this.horizAdvX = this.attribute('horiz-adv-x').numValue(); - - this.isRTL = false; - this.isArabic = false; - this.fontFace = null; - this.missingGlyph = null; - this.glyphs = []; - for (var i=0; i0 && text[i-1]!=' ' && i0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial'; - if (typeof(font.glyphs[c]) != 'undefined') { - glyph = font.glyphs[c][arabicForm]; - if (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c]; - } - } - else { - glyph = font.glyphs[c]; - } - if (glyph == null) glyph = font.missingGlyph; - return glyph; - } - - this.renderChildren = function(ctx) { - var customFont = this.parent.style('font-family').Definition.getDefinition(); - if (customFont != null) { - var fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize); - var fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle); - var text = this.getText(); - if (customFont.isRTL) text = text.split("").reverse().join(""); - - if (this.parent.style('text-anchor').value == 'middle') { - this.x = this.x - this.measureText(ctx) / 2.0; - } - - var dx = svg.ToNumberArray(this.parent.attribute('dx').value); - for (var i=0; i 0 ? node.childNodes[0].nodeValue : // element - node.text; - this.getText = function() { - return this.text; - } - } - svg.Element.tspan.prototype = new svg.Element.TextElementBase; - - // tref - svg.Element.tref = function(node) { - this.base = svg.Element.TextElementBase; - this.base(node); - - this.getText = function() { - var element = this.attribute('xlink:href').Definition.getDefinition(); - if (element != null) return element.children[0].getText(); - } - } - svg.Element.tref.prototype = new svg.Element.TextElementBase; - - // a element - svg.Element.a = function(node) { - this.base = svg.Element.TextElementBase; - this.base(node); - - this.hasText = true; - for (var i=0; i 1 ? node.childNodes[1].nodeValue : ''); - css = css.replace(/(\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/)|(^[\s]*\/\/.*)/gm, ''); // remove comments - css = svg.compressSpaces(css); // replace whitespace - var cssDefs = css.split('}'); - for (var i=0; i 0) { - var urlStart = srcs[s].indexOf('url'); - var urlEnd = srcs[s].indexOf(')', urlStart); - var url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6); - var doc = svg.parseXml(svg.ajax(url)); - var fonts = doc.getElementsByTagName('font'); - for (var f=0; f values - tolerance) { - return value - rem + values; - } - } - return value; - }; - - - var createUUID = R.createUUID = (function (uuidRegEx, uuidReplacer) { - return function () { - return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(uuidRegEx, uuidReplacer).toUpperCase(); - }; - })(/[xy]/g, function (c) { - var r = math.random() * 16 | 0, - v = c == "x" ? r : (r & 3 | 8); - return v.toString(16); - }); - - - R.setWindow = function (newwin) { - eve("raphael.setWindow", R, g.win, newwin); - g.win = newwin; - g.doc = g.win.document; - if (R._engine.initWin) { - R._engine.initWin(g.win); - } - }; - var toHex = function (color) { - if (R.vml) { - // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/ - var trim = /^\s+|\s+$/g; - var bod; - try { - var docum = new ActiveXObject("htmlfile"); - docum.write(""); - docum.close(); - bod = docum.body; - } catch(e) { - bod = createPopup().document.body; - } - var range = bod.createTextRange(); - toHex = cacher(function (color) { - try { - bod.style.color = Str(color).replace(trim, E); - var value = range.queryCommandValue("ForeColor"); - value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16); - return "#" + ("000000" + value.toString(16)).slice(-6); - } catch(e) { - return "none"; - } - }); - } else { - var i = g.doc.createElement("i"); - i.title = "Rapha\xebl Colour Picker"; - i.style.display = "none"; - g.doc.body.appendChild(i); - toHex = cacher(function (color) { - i.style.color = color; - return g.doc.defaultView.getComputedStyle(i, E).getPropertyValue("color"); - }); - } - return toHex(color); - }, - hsbtoString = function () { - return "hsb(" + [this.h, this.s, this.b] + ")"; - }, - hsltoString = function () { - return "hsl(" + [this.h, this.s, this.l] + ")"; - }, - rgbtoString = function () { - return this.hex; - }, - prepareRGB = function (r, g, b) { - if (g == null && R.is(r, "object") && "r" in r && "g" in r && "b" in r) { - b = r.b; - g = r.g; - r = r.r; - } - if (g == null && R.is(r, string)) { - var clr = R.getRGB(r); - r = clr.r; - g = clr.g; - b = clr.b; - } - if (r > 1 || g > 1 || b > 1) { - r /= 255; - g /= 255; - b /= 255; - } - - return [r, g, b]; - }, - packageRGB = function (r, g, b, o) { - r *= 255; - g *= 255; - b *= 255; - var rgb = { - r: r, - g: g, - b: b, - hex: R.rgb(r, g, b), - toString: rgbtoString - }; - R.is(o, "finite") && (rgb.opacity = o); - return rgb; - }; - - - R.color = function (clr) { - var rgb; - if (R.is(clr, "object") && "h" in clr && "s" in clr && "b" in clr) { - rgb = R.hsb2rgb(clr); - clr.r = rgb.r; - clr.g = rgb.g; - clr.b = rgb.b; - clr.hex = rgb.hex; - } else if (R.is(clr, "object") && "h" in clr && "s" in clr && "l" in clr) { - rgb = R.hsl2rgb(clr); - clr.r = rgb.r; - clr.g = rgb.g; - clr.b = rgb.b; - clr.hex = rgb.hex; - } else { - if (R.is(clr, "string")) { - clr = R.getRGB(clr); - } - if (R.is(clr, "object") && "r" in clr && "g" in clr && "b" in clr) { - rgb = R.rgb2hsl(clr); - clr.h = rgb.h; - clr.s = rgb.s; - clr.l = rgb.l; - rgb = R.rgb2hsb(clr); - clr.v = rgb.b; - } else { - clr = {hex: "none"}; - clr.r = clr.g = clr.b = clr.h = clr.s = clr.v = clr.l = -1; - } - } - clr.toString = rgbtoString; - return clr; - }; - - R.hsb2rgb = function (h, s, v, o) { - if (this.is(h, "object") && "h" in h && "s" in h && "b" in h) { - v = h.b; - s = h.s; - h = h.h; - o = h.o; - } - h *= 360; - var R, G, B, X, C; - h = (h % 360) / 60; - C = v * s; - X = C * (1 - abs(h % 2 - 1)); - R = G = B = v - C; - - h = ~~h; - R += [C, X, 0, 0, X, C][h]; - G += [X, C, C, X, 0, 0][h]; - B += [0, 0, X, C, C, X][h]; - return packageRGB(R, G, B, o); - }; - - R.hsl2rgb = function (h, s, l, o) { - if (this.is(h, "object") && "h" in h && "s" in h && "l" in h) { - l = h.l; - s = h.s; - h = h.h; - } - if (h > 1 || s > 1 || l > 1) { - h /= 360; - s /= 100; - l /= 100; - } - h *= 360; - var R, G, B, X, C; - h = (h % 360) / 60; - C = 2 * s * (l < .5 ? l : 1 - l); - X = C * (1 - abs(h % 2 - 1)); - R = G = B = l - C / 2; - - h = ~~h; - R += [C, X, 0, 0, X, C][h]; - G += [X, C, C, X, 0, 0][h]; - B += [0, 0, X, C, C, X][h]; - return packageRGB(R, G, B, o); - }; - - R.rgb2hsb = function (r, g, b) { - b = prepareRGB(r, g, b); - r = b[0]; - g = b[1]; - b = b[2]; - - var H, S, V, C; - V = mmax(r, g, b); - C = V - mmin(r, g, b); - H = (C == 0 ? null : - V == r ? (g - b) / C : - V == g ? (b - r) / C + 2 : - (r - g) / C + 4 - ); - H = ((H + 360) % 6) * 60 / 360; - S = C == 0 ? 0 : C / V; - return {h: H, s: S, b: V, toString: hsbtoString}; - }; - - R.rgb2hsl = function (r, g, b) { - b = prepareRGB(r, g, b); - r = b[0]; - g = b[1]; - b = b[2]; - - var H, S, L, M, m, C; - M = mmax(r, g, b); - m = mmin(r, g, b); - C = M - m; - H = (C == 0 ? null : - M == r ? (g - b) / C : - M == g ? (b - r) / C + 2 : - (r - g) / C + 4); - H = ((H + 360) % 6) * 60 / 360; - L = (M + m) / 2; - S = (C == 0 ? 0 : - L < .5 ? C / (2 * L) : - C / (2 - 2 * L)); - return {h: H, s: S, l: L, toString: hsltoString}; - }; - R._path2string = function () { - return this.join(",").replace(p2s, "$1"); - }; - function repush(array, item) { - for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) { - return array.push(array.splice(i, 1)[0]); - } - } - function cacher(f, scope, postprocessor) { - function newf() { - var arg = Array.prototype.slice.call(arguments, 0), - args = arg.join("\u2400"), - cache = newf.cache = newf.cache || {}, - count = newf.count = newf.count || []; - if (cache[has](args)) { - repush(count, args); - return postprocessor ? postprocessor(cache[args]) : cache[args]; - } - count.length >= 1e3 && delete cache[count.shift()]; - count.push(args); - cache[args] = f[apply](scope, arg); - return postprocessor ? postprocessor(cache[args]) : cache[args]; - } - return newf; - } - - var preload = R._preload = function (src, f) { - var img = g.doc.createElement("img"); - img.style.cssText = "position:absolute;left:-9999em;top:-9999em"; - img.onload = function () { - f.call(this); - this.onload = null; - g.doc.body.removeChild(this); - }; - img.onerror = function () { - g.doc.body.removeChild(this); - }; - g.doc.body.appendChild(img); - img.src = src; - }; - - function clrToString() { - return this.hex; - } - - - R.getRGB = cacher(function (colour) { - if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) { - return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString}; - } - if (colour == "none") { - return {r: -1, g: -1, b: -1, hex: "none", toString: clrToString}; - } - !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour)); - var res, - red, - green, - blue, - opacity, - t, - values, - rgb = colour.match(colourRegExp); - if (rgb) { - if (rgb[2]) { - blue = toInt(rgb[2].substring(5), 16); - green = toInt(rgb[2].substring(3, 5), 16); - red = toInt(rgb[2].substring(1, 3), 16); - } - if (rgb[3]) { - blue = toInt((t = rgb[3].charAt(3)) + t, 16); - green = toInt((t = rgb[3].charAt(2)) + t, 16); - red = toInt((t = rgb[3].charAt(1)) + t, 16); - } - if (rgb[4]) { - values = rgb[4][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - } - if (rgb[5]) { - values = rgb[5][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); - rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - return R.hsb2rgb(red, green, blue, opacity); - } - if (rgb[6]) { - values = rgb[6][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); - rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - return R.hsl2rgb(red, green, blue, opacity); - } - rgb = {r: red, g: green, b: blue, toString: clrToString}; - rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); - R.is(opacity, "finite") && (rgb.opacity = opacity); - return rgb; - } - return {r: -1, g: -1, b: -1, hex: "none", error: 1, toString: clrToString}; - }, R); - - R.hsb = cacher(function (h, s, b) { - return R.hsb2rgb(h, s, b).hex; - }); - - R.hsl = cacher(function (h, s, l) { - return R.hsl2rgb(h, s, l).hex; - }); - - R.rgb = cacher(function (r, g, b) { - return "#" + (16777216 | b | (g << 8) | (r << 16)).toString(16).slice(1); - }); - - R.getColor = function (value) { - var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75}, - rgb = this.hsb2rgb(start.h, start.s, start.b); - start.h += .075; - if (start.h > 1) { - start.h = 0; - start.s -= .2; - start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b}); - } - return rgb.hex; - }; - - R.getColor.reset = function () { - delete this.start; - }; - - // http://schepers.cc/getting-to-the-point - function catmullRom2bezier(crp, z) { - var d = []; - for (var i = 0, iLen = crp.length; iLen - 2 * !z > i; i += 2) { - var p = [ - {x: +crp[i - 2], y: +crp[i - 1]}, - {x: +crp[i], y: +crp[i + 1]}, - {x: +crp[i + 2], y: +crp[i + 3]}, - {x: +crp[i + 4], y: +crp[i + 5]} - ]; - if (z) { - if (!i) { - p[0] = {x: +crp[iLen - 2], y: +crp[iLen - 1]}; - } else if (iLen - 4 == i) { - p[3] = {x: +crp[0], y: +crp[1]}; - } else if (iLen - 2 == i) { - p[2] = {x: +crp[0], y: +crp[1]}; - p[3] = {x: +crp[2], y: +crp[3]}; - } - } else { - if (iLen - 4 == i) { - p[3] = p[2]; - } else if (!i) { - p[0] = {x: +crp[i], y: +crp[i + 1]}; - } - } - d.push(["C", - (-p[0].x + 6 * p[1].x + p[2].x) / 6, - (-p[0].y + 6 * p[1].y + p[2].y) / 6, - (p[1].x + 6 * p[2].x - p[3].x) / 6, - (p[1].y + 6*p[2].y - p[3].y) / 6, - p[2].x, - p[2].y - ]); - } - - return d; - } - - R.parsePathString = function (pathString) { - if (!pathString) { - return null; - } - var pth = paths(pathString); - if (pth.arr) { - return pathClone(pth.arr); - } - - var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, r: 4, q: 4, s: 4, t: 2, v: 1, z: 0}, - data = []; - if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption - data = pathClone(pathString); - } - if (!data.length) { - Str(pathString).replace(pathCommand, function (a, b, c) { - var params = [], - name = b.toLowerCase(); - c.replace(pathValues, function (a, b) { - b && params.push(+b); - }); - if (name == "m" && params.length > 2) { - data.push([b][concat](params.splice(0, 2))); - name = "l"; - b = b == "m" ? "l" : "L"; - } - if (name == "r") { - data.push([b][concat](params)); - } else while (params.length >= paramCounts[name]) { - data.push([b][concat](params.splice(0, paramCounts[name]))); - if (!paramCounts[name]) { - break; - } - } - }); - } - data.toString = R._path2string; - pth.arr = pathClone(data); - return data; - }; - - R.parseTransformString = cacher(function (TString) { - if (!TString) { - return null; - } - var paramCounts = {r: 3, s: 4, t: 2, m: 6}, - data = []; - if (R.is(TString, array) && R.is(TString[0], array)) { // rough assumption - data = pathClone(TString); - } - if (!data.length) { - Str(TString).replace(tCommand, function (a, b, c) { - var params = [], - name = lowerCase.call(b); - c.replace(pathValues, function (a, b) { - b && params.push(+b); - }); - data.push([b][concat](params)); - }); - } - data.toString = R._path2string; - return data; - }); - // PATHS - var paths = function (ps) { - var p = paths.ps = paths.ps || {}; - if (p[ps]) { - p[ps].sleep = 100; - } else { - p[ps] = { - sleep: 100 - }; - } - setTimeout(function () { - for (var key in p) if (p[has](key) && key != ps) { - p[key].sleep--; - !p[key].sleep && delete p[key]; - } - }); - return p[ps]; - }; - - R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { - var t1 = 1 - t, - t13 = pow(t1, 3), - t12 = pow(t1, 2), - t2 = t * t, - t3 = t2 * t, - x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x, - y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y, - mx = p1x + 2 * t * (c1x - p1x) + t2 * (c2x - 2 * c1x + p1x), - my = p1y + 2 * t * (c1y - p1y) + t2 * (c2y - 2 * c1y + p1y), - nx = c1x + 2 * t * (c2x - c1x) + t2 * (p2x - 2 * c2x + c1x), - ny = c1y + 2 * t * (c2y - c1y) + t2 * (p2y - 2 * c2y + c1y), - ax = t1 * p1x + t * c1x, - ay = t1 * p1y + t * c1y, - cx = t1 * c2x + t * p2x, - cy = t1 * c2y + t * p2y, - alpha = (90 - math.atan2(mx - nx, my - ny) * 180 / PI); - (mx > nx || my < ny) && (alpha += 180); - return { - x: x, - y: y, - m: {x: mx, y: my}, - n: {x: nx, y: ny}, - start: {x: ax, y: ay}, - end: {x: cx, y: cy}, - alpha: alpha - }; - }; - - R.bezierBBox = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { - if (!R.is(p1x, "array")) { - p1x = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y]; - } - var bbox = curveDim.apply(null, p1x); - return { - x: bbox.min.x, - y: bbox.min.y, - x2: bbox.max.x, - y2: bbox.max.y, - width: bbox.max.x - bbox.min.x, - height: bbox.max.y - bbox.min.y - }; - }; - - R.isPointInsideBBox = function (bbox, x, y) { - return x >= bbox.x && x <= bbox.x2 && y >= bbox.y && y <= bbox.y2; - }; - - R.isBBoxIntersect = function (bbox1, bbox2) { - var i = R.isPointInsideBBox; - return i(bbox2, bbox1.x, bbox1.y) - || i(bbox2, bbox1.x2, bbox1.y) - || i(bbox2, bbox1.x, bbox1.y2) - || i(bbox2, bbox1.x2, bbox1.y2) - || i(bbox1, bbox2.x, bbox2.y) - || i(bbox1, bbox2.x2, bbox2.y) - || i(bbox1, bbox2.x, bbox2.y2) - || i(bbox1, bbox2.x2, bbox2.y2) - || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) - && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); - }; - function base3(t, p1, p2, p3, p4) { - var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, - t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; - return t * t2 - 3 * p1 + 3 * p2; - } - function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) { - if (z == null) { - z = 1; - } - z = z > 1 ? 1 : z < 0 ? 0 : z; - var z2 = z / 2, - n = 12, - Tvalues = [-0.1252,0.1252,-0.3678,0.3678,-0.5873,0.5873,-0.7699,0.7699,-0.9041,0.9041,-0.9816,0.9816], - Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472], - sum = 0; - for (var i = 0; i < n; i++) { - var ct = z2 * Tvalues[i] + z2, - xbase = base3(ct, x1, x2, x3, x4), - ybase = base3(ct, y1, y2, y3, y4), - comb = xbase * xbase + ybase * ybase; - sum += Cvalues[i] * math.sqrt(comb); - } - return z2 * sum; - } - function getTatLen(x1, y1, x2, y2, x3, y3, x4, y4, ll) { - if (ll < 0 || bezlen(x1, y1, x2, y2, x3, y3, x4, y4) < ll) { - return; - } - var t = 1, - step = t / 2, - t2 = t - step, - l, - e = .01; - l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); - while (abs(l - ll) > e) { - step /= 2; - t2 += (l < ll ? 1 : -1) * step; - l = bezlen(x1, y1, x2, y2, x3, y3, x4, y4, t2); - } - return t2; - } - function intersect(x1, y1, x2, y2, x3, y3, x4, y4) { - if ( - mmax(x1, x2) < mmin(x3, x4) || - mmin(x1, x2) > mmax(x3, x4) || - mmax(y1, y2) < mmin(y3, y4) || - mmin(y1, y2) > mmax(y3, y4) - ) { - return; - } - var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), - ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), - denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); - - if (!denominator) { - return; - } - var px = nx / denominator, - py = ny / denominator, - px2 = +px.toFixed(2), - py2 = +py.toFixed(2); - if ( - px2 < +mmin(x1, x2).toFixed(2) || - px2 > +mmax(x1, x2).toFixed(2) || - px2 < +mmin(x3, x4).toFixed(2) || - px2 > +mmax(x3, x4).toFixed(2) || - py2 < +mmin(y1, y2).toFixed(2) || - py2 > +mmax(y1, y2).toFixed(2) || - py2 < +mmin(y3, y4).toFixed(2) || - py2 > +mmax(y3, y4).toFixed(2) - ) { - return; - } - return {x: px, y: py}; - } - function inter(bez1, bez2) { - return interHelper(bez1, bez2); - } - function interCount(bez1, bez2) { - return interHelper(bez1, bez2, 1); - } - function interHelper(bez1, bez2, justCount) { - var bbox1 = R.bezierBBox(bez1), - bbox2 = R.bezierBBox(bez2); - if (!R.isBBoxIntersect(bbox1, bbox2)) { - return justCount ? 0 : []; - } - var l1 = bezlen.apply(0, bez1), - l2 = bezlen.apply(0, bez2), - n1 = ~~(l1 / 5), - n2 = ~~(l2 / 5), - dots1 = [], - dots2 = [], - xy = {}, - res = justCount ? 0 : []; - for (var i = 0; i < n1 + 1; i++) { - var p = R.findDotsAtSegment.apply(R, bez1.concat(i / n1)); - dots1.push({x: p.x, y: p.y, t: i / n1}); - } - for (i = 0; i < n2 + 1; i++) { - p = R.findDotsAtSegment.apply(R, bez2.concat(i / n2)); - dots2.push({x: p.x, y: p.y, t: i / n2}); - } - for (i = 0; i < n1; i++) { - for (var j = 0; j < n2; j++) { - var di = dots1[i], - di1 = dots1[i + 1], - dj = dots2[j], - dj1 = dots2[j + 1], - ci = abs(di1.x - di.x) < .001 ? "y" : "x", - cj = abs(dj1.x - dj.x) < .001 ? "y" : "x", - is = intersect(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y); - if (is) { - if (xy[is.x.toFixed(4)] == is.y.toFixed(4)) { - continue; - } - xy[is.x.toFixed(4)] = is.y.toFixed(4); - var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), - t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); - if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { - if (justCount) { - res++; - } else { - res.push({ - x: is.x, - y: is.y, - t1: t1, - t2: t2 - }); - } - } - } - } - } - return res; - } - - R.pathIntersection = function (path1, path2) { - return interPathHelper(path1, path2); - }; - R.pathIntersectionNumber = function (path1, path2) { - return interPathHelper(path1, path2, 1); - }; - function interPathHelper(path1, path2, justCount) { - path1 = R._path2curve(path1); - path2 = R._path2curve(path2); - var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2, - res = justCount ? 0 : []; - for (var i = 0, ii = path1.length; i < ii; i++) { - var pi = path1[i]; - if (pi[0] == "M") { - x1 = x1m = pi[1]; - y1 = y1m = pi[2]; - } else { - if (pi[0] == "C") { - bez1 = [x1, y1].concat(pi.slice(1)); - x1 = bez1[6]; - y1 = bez1[7]; - } else { - bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; - x1 = x1m; - y1 = y1m; - } - for (var j = 0, jj = path2.length; j < jj; j++) { - var pj = path2[j]; - if (pj[0] == "M") { - x2 = x2m = pj[1]; - y2 = y2m = pj[2]; - } else { - if (pj[0] == "C") { - bez2 = [x2, y2].concat(pj.slice(1)); - x2 = bez2[6]; - y2 = bez2[7]; - } else { - bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; - x2 = x2m; - y2 = y2m; - } - var intr = interHelper(bez1, bez2, justCount); - if (justCount) { - res += intr; - } else { - for (var k = 0, kk = intr.length; k < kk; k++) { - intr[k].segment1 = i; - intr[k].segment2 = j; - intr[k].bez1 = bez1; - intr[k].bez2 = bez2; - } - res = res.concat(intr); - } - } - } - } - } - return res; - } - - R.isPointInsidePath = function (path, x, y) { - var bbox = R.pathBBox(path); - return R.isPointInsideBBox(bbox, x, y) && - interPathHelper(path, [["M", x, y], ["H", bbox.x2 + 10]], 1) % 2 == 1; - }; - R._removedFactory = function (methodname) { - return function () { - eve("raphael.log", null, "Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object", methodname); - }; - }; - - var pathDimensions = R.pathBBox = function (path) { - var pth = paths(path); - if (pth.bbox) { - return pth.bbox; - } - if (!path) { - return {x: 0, y: 0, width: 0, height: 0, x2: 0, y2: 0}; - } - path = path2curve(path); - var x = 0, - y = 0, - X = [], - Y = [], - p; - for (var i = 0, ii = path.length; i < ii; i++) { - p = path[i]; - if (p[0] == "M") { - x = p[1]; - y = p[2]; - X.push(x); - Y.push(y); - } else { - var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); - X = X[concat](dim.min.x, dim.max.x); - Y = Y[concat](dim.min.y, dim.max.y); - x = p[5]; - y = p[6]; - } - } - var xmin = mmin[apply](0, X), - ymin = mmin[apply](0, Y), - xmax = mmax[apply](0, X), - ymax = mmax[apply](0, Y), - bb = { - x: xmin, - y: ymin, - x2: xmax, - y2: ymax, - width: xmax - xmin, - height: ymax - ymin - }; - pth.bbox = clone(bb); - return bb; - }, - pathClone = function (pathArray) { - var res = clone(pathArray); - res.toString = R._path2string; - return res; - }, - pathToRelative = R._pathToRelative = function (pathArray) { - var pth = paths(pathArray); - if (pth.rel) { - return pathClone(pth.rel); - } - if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption - pathArray = R.parsePathString(pathArray); - } - var res = [], - x = 0, - y = 0, - mx = 0, - my = 0, - start = 0; - if (pathArray[0][0] == "M") { - x = pathArray[0][1]; - y = pathArray[0][2]; - mx = x; - my = y; - start++; - res.push(["M", x, y]); - } - for (var i = start, ii = pathArray.length; i < ii; i++) { - var r = res[i] = [], - pa = pathArray[i]; - if (pa[0] != lowerCase.call(pa[0])) { - r[0] = lowerCase.call(pa[0]); - switch (r[0]) { - case "a": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] - x).toFixed(3); - r[7] = +(pa[7] - y).toFixed(3); - break; - case "v": - r[1] = +(pa[1] - y).toFixed(3); - break; - case "m": - mx = pa[1]; - my = pa[2]; - default: - for (var j = 1, jj = pa.length; j < jj; j++) { - r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); - } - } - } else { - r = res[i] = []; - if (pa[0] == "m") { - mx = pa[1] + x; - my = pa[2] + y; - } - for (var k = 0, kk = pa.length; k < kk; k++) { - res[i][k] = pa[k]; - } - } - var len = res[i].length; - switch (res[i][0]) { - case "z": - x = mx; - y = my; - break; - case "h": - x += +res[i][len - 1]; - break; - case "v": - y += +res[i][len - 1]; - break; - default: - x += +res[i][len - 2]; - y += +res[i][len - 1]; - } - } - res.toString = R._path2string; - pth.rel = pathClone(res); - return res; - }, - pathToAbsolute = R._pathToAbsolute = function (pathArray) { - var pth = paths(pathArray); - if (pth.abs) { - return pathClone(pth.abs); - } - if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption - pathArray = R.parsePathString(pathArray); - } - if (!pathArray || !pathArray.length) { - return [["M", 0, 0]]; - } - var res = [], - x = 0, - y = 0, - mx = 0, - my = 0, - start = 0; - if (pathArray[0][0] == "M") { - x = +pathArray[0][1]; - y = +pathArray[0][2]; - mx = x; - my = y; - start++; - res[0] = ["M", x, y]; - } - var crz = pathArray.length == 3 && pathArray[0][0] == "M" && pathArray[1][0].toUpperCase() == "R" && pathArray[2][0].toUpperCase() == "Z"; - for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { - res.push(r = []); - pa = pathArray[i]; - if (pa[0] != upperCase.call(pa[0])) { - r[0] = upperCase.call(pa[0]); - switch (r[0]) { - case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] + x); - r[7] = +(pa[7] + y); - break; - case "V": - r[1] = +pa[1] + y; - break; - case "H": - r[1] = +pa[1] + x; - break; - case "R": - var dots = [x, y][concat](pa.slice(1)); - for (var j = 2, jj = dots.length; j < jj; j++) { - dots[j] = +dots[j] + x; - dots[++j] = +dots[j] + y; - } - res.pop(); - res = res[concat](catmullRom2bezier(dots, crz)); - break; - case "M": - mx = +pa[1] + x; - my = +pa[2] + y; - default: - for (j = 1, jj = pa.length; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); - } - } - } else if (pa[0] == "R") { - dots = [x, y][concat](pa.slice(1)); - res.pop(); - res = res[concat](catmullRom2bezier(dots, crz)); - r = ["R"][concat](pa.slice(-2)); - } else { - for (var k = 0, kk = pa.length; k < kk; k++) { - r[k] = pa[k]; - } - } - switch (r[0]) { - case "Z": - x = mx; - y = my; - break; - case "H": - x = r[1]; - break; - case "V": - y = r[1]; - break; - case "M": - mx = r[r.length - 2]; - my = r[r.length - 1]; - default: - x = r[r.length - 2]; - y = r[r.length - 1]; - } - } - res.toString = R._path2string; - pth.abs = pathClone(res); - return res; - }, - l2c = function (x1, y1, x2, y2) { - return [x1, y1, x2, y2, x2, y2]; - }, - q2c = function (x1, y1, ax, ay, x2, y2) { - var _13 = 1 / 3, - _23 = 2 / 3; - return [ - _13 * x1 + _23 * ax, - _13 * y1 + _23 * ay, - _13 * x2 + _23 * ax, - _13 * y2 + _23 * ay, - x2, - y2 - ]; - }, - a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { - // for more information of where this math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - var _120 = PI * 120 / 180, - rad = PI / 180 * (+angle || 0), - res = [], - xy, - rotate = cacher(function (x, y, rad) { - var X = x * math.cos(rad) - y * math.sin(rad), - Y = x * math.sin(rad) + y * math.cos(rad); - return {x: X, y: Y}; - }); - if (!recursive) { - xy = rotate(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotate(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - var cos = math.cos(PI / 180 * angle), - sin = math.sin(PI / 180 * angle), - x = (x1 - x2) / 2, - y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = math.sqrt(h); - rx = h * rx; - ry = h * ry; - } - var rx2 = rx * rx, - ry2 = ry * ry, - k = (large_arc_flag == sweep_flag ? -1 : 1) * - math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), - cx = k * rx * y / ry + (x1 + x2) / 2, - cy = k * -ry * x / rx + (y1 + y2) / 2, - f1 = math.asin(((y1 - cy) / ry).toFixed(9)), - f2 = math.asin(((y2 - cy) / ry).toFixed(9)); - - f1 = x1 < cx ? PI - f1 : f1; - f2 = x2 < cx ? PI - f2 : f2; - f1 < 0 && (f1 = PI * 2 + f1); - f2 < 0 && (f2 = PI * 2 + f2); - if (sweep_flag && f1 > f2) { - f1 = f1 - PI * 2; - } - if (!sweep_flag && f2 > f1) { - f2 = f2 - PI * 2; - } - } else { - f1 = recursive[0]; - f2 = recursive[1]; - cx = recursive[2]; - cy = recursive[3]; - } - var df = f2 - f1; - if (abs(df) > _120) { - var f2old = f2, - x2old = x2, - y2old = y2; - f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); - x2 = cx + rx * math.cos(f2); - y2 = cy + ry * math.sin(f2); - res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - var c1 = math.cos(f1), - s1 = math.sin(f1), - c2 = math.cos(f2), - s2 = math.sin(f2), - t = math.tan(df / 4), - hx = 4 / 3 * rx * t, - hy = 4 / 3 * ry * t, - m1 = [x1, y1], - m2 = [x1 + hx * s1, y1 - hy * c1], - m3 = [x2 + hx * s2, y2 - hy * c2], - m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return [m2, m3, m4][concat](res); - } else { - res = [m2, m3, m4][concat](res).join()[split](","); - var newres = []; - for (var i = 0, ii = res.length; i < ii; i++) { - newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; - } - return newres; - } - }, - findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { - var t1 = 1 - t; - return { - x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, - y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y - }; - }, - curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { - var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), - b = 2 * (c1x - p1x) - 2 * (c2x - c1x), - c = p1x - c1x, - t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a, - t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a, - y = [p1y, p2y], - x = [p1x, p2x], - dot; - abs(t1) > "1e12" && (t1 = .5); - abs(t2) > "1e12" && (t2 = .5); - if (t1 > 0 && t1 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); - x.push(dot.x); - y.push(dot.y); - } - if (t2 > 0 && t2 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); - x.push(dot.x); - y.push(dot.y); - } - a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); - b = 2 * (c1y - p1y) - 2 * (c2y - c1y); - c = p1y - c1y; - t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a; - t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a; - abs(t1) > "1e12" && (t1 = .5); - abs(t2) > "1e12" && (t2 = .5); - if (t1 > 0 && t1 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); - x.push(dot.x); - y.push(dot.y); - } - if (t2 > 0 && t2 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); - x.push(dot.x); - y.push(dot.y); - } - return { - min: {x: mmin[apply](0, x), y: mmin[apply](0, y)}, - max: {x: mmax[apply](0, x), y: mmax[apply](0, y)} - }; - }), - path2curve = R._path2curve = cacher(function (path, path2) { - var pth = !path2 && paths(path); - if (!path2 && pth.curve) { - return pathClone(pth.curve); - } - var p = pathToAbsolute(path), - p2 = path2 && pathToAbsolute(path2), - attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, - attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, - processPath = function (path, d) { - var nx, ny; - if (!path) { - return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; - } - !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null); - switch (path[0]) { - case "M": - d.X = path[1]; - d.Y = path[2]; - break; - case "A": - path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1)))); - break; - case "S": - nx = d.x + (d.x - (d.bx || d.x)); - ny = d.y + (d.y - (d.by || d.y)); - path = ["C", nx, ny][concat](path.slice(1)); - break; - case "T": - d.qx = d.x + (d.x - (d.qx || d.x)); - d.qy = d.y + (d.y - (d.qy || d.y)); - path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); - break; - case "Q": - d.qx = path[1]; - d.qy = path[2]; - path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4])); - break; - case "L": - path = ["C"][concat](l2c(d.x, d.y, path[1], path[2])); - break; - case "H": - path = ["C"][concat](l2c(d.x, d.y, path[1], d.y)); - break; - case "V": - path = ["C"][concat](l2c(d.x, d.y, d.x, path[1])); - break; - case "Z": - path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y)); - break; - } - return path; - }, - fixArc = function (pp, i) { - if (pp[i].length > 7) { - pp[i].shift(); - var pi = pp[i]; - while (pi.length) { - pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6))); - } - pp.splice(i, 1); - ii = mmax(p.length, p2 && p2.length || 0); - } - }, - fixM = function (path1, path2, a1, a2, i) { - if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { - path2.splice(i, 0, ["M", a2.x, a2.y]); - a1.bx = 0; - a1.by = 0; - a1.x = path1[i][1]; - a1.y = path1[i][2]; - ii = mmax(p.length, p2 && p2.length || 0); - } - }; - for (var i = 0, ii = mmax(p.length, p2 && p2.length || 0); i < ii; i++) { - p[i] = processPath(p[i], attrs); - fixArc(p, i); - p2 && (p2[i] = processPath(p2[i], attrs2)); - p2 && fixArc(p2, i); - fixM(p, p2, attrs, attrs2, i); - fixM(p2, p, attrs2, attrs, i); - var seg = p[i], - seg2 = p2 && p2[i], - seglen = seg.length, - seg2len = p2 && seg2.length; - attrs.x = seg[seglen - 2]; - attrs.y = seg[seglen - 1]; - attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; - attrs.by = toFloat(seg[seglen - 3]) || attrs.y; - attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x); - attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y); - attrs2.x = p2 && seg2[seg2len - 2]; - attrs2.y = p2 && seg2[seg2len - 1]; - } - if (!p2) { - pth.curve = pathClone(p); - } - return p2 ? [p, p2] : p; - }, null, pathClone), - parseDots = R._parseDots = cacher(function (gradient) { - var dots = []; - for (var i = 0, ii = gradient.length; i < ii; i++) { - var dot = {}, - par = gradient[i].match(/^([^:]*):?([\d\.]*)/); - dot.color = R.getRGB(par[1]); - if (dot.color.error) { - return null; - } - dot.color = dot.color.hex; - par[2] && (dot.offset = par[2] + "%"); - dots.push(dot); - } - for (i = 1, ii = dots.length - 1; i < ii; i++) { - if (!dots[i].offset) { - var start = toFloat(dots[i - 1].offset || 0), - end = 0; - for (var j = i + 1; j < ii; j++) { - if (dots[j].offset) { - end = dots[j].offset; - break; - } - } - if (!end) { - end = 100; - j = ii; - } - end = toFloat(end); - var d = (end - start) / (j - i + 1); - for (; i < j; i++) { - start += d; - dots[i].offset = start + "%"; - } - } - } - return dots; - }), - tear = R._tear = function (el, paper) { - el == paper.top && (paper.top = el.prev); - el == paper.bottom && (paper.bottom = el.next); - el.next && (el.next.prev = el.prev); - el.prev && (el.prev.next = el.next); - }, - tofront = R._tofront = function (el, paper) { - if (paper.top === el) { - return; - } - tear(el, paper); - el.next = null; - el.prev = paper.top; - paper.top.next = el; - paper.top = el; - }, - toback = R._toback = function (el, paper) { - if (paper.bottom === el) { - return; - } - tear(el, paper); - el.next = paper.bottom; - el.prev = null; - paper.bottom.prev = el; - paper.bottom = el; - }, - insertafter = R._insertafter = function (el, el2, paper) { - tear(el, paper); - el2 == paper.top && (paper.top = el); - el2.next && (el2.next.prev = el); - el.next = el2.next; - el.prev = el2; - el2.next = el; - }, - insertbefore = R._insertbefore = function (el, el2, paper) { - tear(el, paper); - el2 == paper.bottom && (paper.bottom = el); - el2.prev && (el2.prev.next = el); - el.prev = el2.prev; - el2.prev = el; - el.next = el2; - }, - - toMatrix = R.toMatrix = function (path, transform) { - var bb = pathDimensions(path), - el = { - _: { - transform: E - }, - getBBox: function () { - return bb; - } - }; - extractTransform(el, transform); - return el.matrix; - }, - - transformPath = R.transformPath = function (path, transform) { - return mapPath(path, toMatrix(path, transform)); - }, - extractTransform = R._extractTransform = function (el, tstr) { - if (tstr == null) { - return el._.transform; - } - tstr = Str(tstr).replace(/\.{3}|\u2026/g, el._.transform || E); - var tdata = R.parseTransformString(tstr), - deg = 0, - dx = 0, - dy = 0, - sx = 1, - sy = 1, - _ = el._, - m = new Matrix; - _.transform = tdata || []; - if (tdata) { - for (var i = 0, ii = tdata.length; i < ii; i++) { - var t = tdata[i], - tlen = t.length, - command = Str(t[0]).toLowerCase(), - absolute = t[0] != command, - inver = absolute ? m.invert() : 0, - x1, - y1, - x2, - y2, - bb; - if (command == "t" && tlen == 3) { - if (absolute) { - x1 = inver.x(0, 0); - y1 = inver.y(0, 0); - x2 = inver.x(t[1], t[2]); - y2 = inver.y(t[1], t[2]); - m.translate(x2 - x1, y2 - y1); - } else { - m.translate(t[1], t[2]); - } - } else if (command == "r") { - if (tlen == 2) { - bb = bb || el.getBBox(1); - m.rotate(t[1], bb.x + bb.width / 2, bb.y + bb.height / 2); - deg += t[1]; - } else if (tlen == 4) { - if (absolute) { - x2 = inver.x(t[2], t[3]); - y2 = inver.y(t[2], t[3]); - m.rotate(t[1], x2, y2); - } else { - m.rotate(t[1], t[2], t[3]); - } - deg += t[1]; - } - } else if (command == "s") { - if (tlen == 2 || tlen == 3) { - bb = bb || el.getBBox(1); - m.scale(t[1], t[tlen - 1], bb.x + bb.width / 2, bb.y + bb.height / 2); - sx *= t[1]; - sy *= t[tlen - 1]; - } else if (tlen == 5) { - if (absolute) { - x2 = inver.x(t[3], t[4]); - y2 = inver.y(t[3], t[4]); - m.scale(t[1], t[2], x2, y2); - } else { - m.scale(t[1], t[2], t[3], t[4]); - } - sx *= t[1]; - sy *= t[2]; - } - } else if (command == "m" && tlen == 7) { - m.add(t[1], t[2], t[3], t[4], t[5], t[6]); - } - _.dirtyT = 1; - el.matrix = m; - } - } - - - el.matrix = m; - - _.sx = sx; - _.sy = sy; - _.deg = deg; - _.dx = dx = m.e; - _.dy = dy = m.f; - - if (sx == 1 && sy == 1 && !deg && _.bbox) { - _.bbox.x += +dx; - _.bbox.y += +dy; - } else { - _.dirtyT = 1; - } - }, - getEmpty = function (item) { - var l = item[0]; - switch (l.toLowerCase()) { - case "t": return [l, 0, 0]; - case "m": return [l, 1, 0, 0, 1, 0, 0]; - case "r": if (item.length == 4) { - return [l, 0, item[2], item[3]]; - } else { - return [l, 0]; - } - case "s": if (item.length == 5) { - return [l, 1, 1, item[3], item[4]]; - } else if (item.length == 3) { - return [l, 1, 1]; - } else { - return [l, 1]; - } - } - }, - equaliseTransform = R._equaliseTransform = function (t1, t2) { - t2 = Str(t2).replace(/\.{3}|\u2026/g, t1); - t1 = R.parseTransformString(t1) || []; - t2 = R.parseTransformString(t2) || []; - var maxlength = mmax(t1.length, t2.length), - from = [], - to = [], - i = 0, j, jj, - tt1, tt2; - for (; i < maxlength; i++) { - tt1 = t1[i] || getEmpty(t2[i]); - tt2 = t2[i] || getEmpty(tt1); - if ((tt1[0] != tt2[0]) || - (tt1[0].toLowerCase() == "r" && (tt1[2] != tt2[2] || tt1[3] != tt2[3])) || - (tt1[0].toLowerCase() == "s" && (tt1[3] != tt2[3] || tt1[4] != tt2[4])) - ) { - return; - } - from[i] = []; - to[i] = []; - for (j = 0, jj = mmax(tt1.length, tt2.length); j < jj; j++) { - j in tt1 && (from[i][j] = tt1[j]); - j in tt2 && (to[i][j] = tt2[j]); - } - } - return { - from: from, - to: to - }; - }; - R._getContainer = function (x, y, w, h) { - var container; - container = h == null && !R.is(x, "object") ? g.doc.getElementById(x) : x; - if (container == null) { - return; - } - if (container.tagName) { - if (y == null) { - return { - container: container, - width: container.style.pixelWidth || container.offsetWidth, - height: container.style.pixelHeight || container.offsetHeight - }; - } else { - return { - container: container, - width: y, - height: w - }; - } - } - return { - container: 1, - x: x, - y: y, - width: w, - height: h - }; - }; - - R.pathToRelative = pathToRelative; - R._engine = {}; - - R.path2curve = path2curve; - - R.matrix = function (a, b, c, d, e, f) { - return new Matrix(a, b, c, d, e, f); - }; - function Matrix(a, b, c, d, e, f) { - if (a != null) { - this.a = +a; - this.b = +b; - this.c = +c; - this.d = +d; - this.e = +e; - this.f = +f; - } else { - this.a = 1; - this.b = 0; - this.c = 0; - this.d = 1; - this.e = 0; - this.f = 0; - } - } - (function (matrixproto) { - - matrixproto.add = function (a, b, c, d, e, f) { - var out = [[], [], []], - m = [[this.a, this.c, this.e], [this.b, this.d, this.f], [0, 0, 1]], - matrix = [[a, c, e], [b, d, f], [0, 0, 1]], - x, y, z, res; - - if (a && a instanceof Matrix) { - matrix = [[a.a, a.c, a.e], [a.b, a.d, a.f], [0, 0, 1]]; - } - - for (x = 0; x < 3; x++) { - for (y = 0; y < 3; y++) { - res = 0; - for (z = 0; z < 3; z++) { - res += m[x][z] * matrix[z][y]; - } - out[x][y] = res; - } - } - this.a = out[0][0]; - this.b = out[1][0]; - this.c = out[0][1]; - this.d = out[1][1]; - this.e = out[0][2]; - this.f = out[1][2]; - }; - - matrixproto.invert = function () { - var me = this, - x = me.a * me.d - me.b * me.c; - return new Matrix(me.d / x, -me.b / x, -me.c / x, me.a / x, (me.c * me.f - me.d * me.e) / x, (me.b * me.e - me.a * me.f) / x); - }; - - matrixproto.clone = function () { - return new Matrix(this.a, this.b, this.c, this.d, this.e, this.f); - }; - - matrixproto.translate = function (x, y) { - this.add(1, 0, 0, 1, x, y); - }; - - matrixproto.scale = function (x, y, cx, cy) { - y == null && (y = x); - (cx || cy) && this.add(1, 0, 0, 1, cx, cy); - this.add(x, 0, 0, y, 0, 0); - (cx || cy) && this.add(1, 0, 0, 1, -cx, -cy); - }; - - matrixproto.rotate = function (a, x, y) { - a = R.rad(a); - x = x || 0; - y = y || 0; - var cos = +math.cos(a).toFixed(9), - sin = +math.sin(a).toFixed(9); - this.add(cos, sin, -sin, cos, x, y); - this.add(1, 0, 0, 1, -x, -y); - }; - - matrixproto.x = function (x, y) { - return x * this.a + y * this.c + this.e; - }; - - matrixproto.y = function (x, y) { - return x * this.b + y * this.d + this.f; - }; - matrixproto.get = function (i) { - return +this[Str.fromCharCode(97 + i)].toFixed(4); - }; - matrixproto.toString = function () { - return R.svg ? - "matrix(" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)].join() + ")" : - [this.get(0), this.get(2), this.get(1), this.get(3), 0, 0].join(); - }; - matrixproto.toFilter = function () { - return "progid:DXImageTransform.Microsoft.Matrix(M11=" + this.get(0) + - ", M12=" + this.get(2) + ", M21=" + this.get(1) + ", M22=" + this.get(3) + - ", Dx=" + this.get(4) + ", Dy=" + this.get(5) + ", sizingmethod='auto expand')"; - }; - matrixproto.offset = function () { - return [this.e.toFixed(4), this.f.toFixed(4)]; - }; - function norm(a) { - return a[0] * a[0] + a[1] * a[1]; - } - function normalize(a) { - var mag = math.sqrt(norm(a)); - a[0] && (a[0] /= mag); - a[1] && (a[1] /= mag); - } - - matrixproto.split = function () { - var out = {}; - // translation - out.dx = this.e; - out.dy = this.f; - - // scale and shear - var row = [[this.a, this.c], [this.b, this.d]]; - out.scalex = math.sqrt(norm(row[0])); - normalize(row[0]); - - out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1]; - row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear]; - - out.scaley = math.sqrt(norm(row[1])); - normalize(row[1]); - out.shear /= out.scaley; - - // rotation - var sin = -row[0][1], - cos = row[1][1]; - if (cos < 0) { - out.rotate = R.deg(math.acos(cos)); - if (sin < 0) { - out.rotate = 360 - out.rotate; - } - } else { - out.rotate = R.deg(math.asin(sin)); - } - - out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate); - out.isSuperSimple = !+out.shear.toFixed(9) && out.scalex.toFixed(9) == out.scaley.toFixed(9) && !out.rotate; - out.noRotation = !+out.shear.toFixed(9) && !out.rotate; - return out; - }; - - matrixproto.toTransformString = function (shorter) { - var s = shorter || this[split](); - if (s.isSimple) { - s.scalex = +s.scalex.toFixed(4); - s.scaley = +s.scaley.toFixed(4); - s.rotate = +s.rotate.toFixed(4); - return (s.dx || s.dy ? "t" + [s.dx, s.dy] : E) + - (s.scalex != 1 || s.scaley != 1 ? "s" + [s.scalex, s.scaley, 0, 0] : E) + - (s.rotate ? "r" + [s.rotate, 0, 0] : E); - } else { - return "m" + [this.get(0), this.get(1), this.get(2), this.get(3), this.get(4), this.get(5)]; - } - }; - })(Matrix.prototype); - - // WebKit rendering bug workaround method - var version = navigator.userAgent.match(/Version\/(.*?)\s/) || navigator.userAgent.match(/Chrome\/(\d+)/); - if ((navigator.vendor == "Apple Computer, Inc.") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == "iP") || - (navigator.vendor == "Google Inc." && version && version[1] < 8)) { - - paperproto.safari = function () { - var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: "none"}); - setTimeout(function () {rect.remove();}); - }; - } else { - paperproto.safari = fun; - } - - var preventDefault = function () { - this.returnValue = false; - }, - preventTouch = function () { - return this.originalEvent.preventDefault(); - }, - stopPropagation = function () { - this.cancelBubble = true; - }, - stopTouch = function () { - return this.originalEvent.stopPropagation(); - }, - addEvent = (function () { - if (g.doc.addEventListener) { - return function (obj, type, fn, element) { - var realName = supportsTouch && touchMap[type] ? touchMap[type] : type, - f = function (e) { - var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, - scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft, - x = e.clientX + scrollX, - y = e.clientY + scrollY; - if (supportsTouch && touchMap[has](type)) { - for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) { - if (e.targetTouches[i].target == obj) { - var olde = e; - e = e.targetTouches[i]; - e.originalEvent = olde; - e.preventDefault = preventTouch; - e.stopPropagation = stopTouch; - break; - } - } - } - return fn.call(element, e, x, y); - }; - obj.addEventListener(realName, f, false); - return function () { - obj.removeEventListener(realName, f, false); - return true; - }; - }; - } else if (g.doc.attachEvent) { - return function (obj, type, fn, element) { - var f = function (e) { - e = e || g.win.event; - var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, - scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft, - x = e.clientX + scrollX, - y = e.clientY + scrollY; - e.preventDefault = e.preventDefault || preventDefault; - e.stopPropagation = e.stopPropagation || stopPropagation; - return fn.call(element, e, x, y); - }; - obj.attachEvent("on" + type, f); - var detacher = function () { - obj.detachEvent("on" + type, f); - return true; - }; - return detacher; - }; - } - })(), - drag = [], - dragMove = function (e) { - var x = e.clientX, - y = e.clientY, - scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, - scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft, - dragi, - j = drag.length; - while (j--) { - dragi = drag[j]; - if (supportsTouch) { - var i = e.touches.length, - touch; - while (i--) { - touch = e.touches[i]; - if (touch.identifier == dragi.el._drag.id) { - x = touch.clientX; - y = touch.clientY; - (e.originalEvent ? e.originalEvent : e).preventDefault(); - break; - } - } - } else { - e.preventDefault(); - } - var node = dragi.el.node, - o, - next = node.nextSibling, - parent = node.parentNode, - display = node.style.display; - g.win.opera && parent.removeChild(node); - node.style.display = "none"; - o = dragi.el.paper.getElementByPoint(x, y); - node.style.display = display; - g.win.opera && (next ? parent.insertBefore(node, next) : parent.appendChild(node)); - o && eve("raphael.drag.over." + dragi.el.id, dragi.el, o); - x += scrollX; - y += scrollY; - eve("raphael.drag.move." + dragi.el.id, dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e); - } - }, - dragUp = function (e) { - R.unmousemove(dragMove).unmouseup(dragUp); - var i = drag.length, - dragi; - while (i--) { - dragi = drag[i]; - dragi.el._drag = {}; - eve("raphael.drag.end." + dragi.el.id, dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e); - } - drag = []; - }, - - elproto = R.el = {}; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - for (var i = events.length; i--;) { - (function (eventName) { - R[eventName] = elproto[eventName] = function (fn, scope) { - if (R.is(fn, "function")) { - this.events = this.events || []; - this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || g.doc, eventName, fn, scope || this)}); - } - return this; - }; - R["un" + eventName] = elproto["un" + eventName] = function (fn) { - var events = this.events || [], - l = events.length; - while (l--) if (events[l].name == eventName && events[l].f == fn) { - events[l].unbind(); - events.splice(l, 1); - !events.length && delete this.events; - return this; - } - return this; - }; - })(events[i]); - } - - - elproto.data = function (key, value) { - var data = eldata[this.id] = eldata[this.id] || {}; - if (arguments.length == 1) { - if (R.is(key, "object")) { - for (var i in key) if (key[has](i)) { - this.data(i, key[i]); - } - return this; - } - eve("raphael.data.get." + this.id, this, data[key], key); - return data[key]; - } - data[key] = value; - eve("raphael.data.set." + this.id, this, value, key); - return this; - }; - - elproto.removeData = function (key) { - if (key == null) { - eldata[this.id] = {}; - } else { - eldata[this.id] && delete eldata[this.id][key]; - } - return this; - }; - - elproto.hover = function (f_in, f_out, scope_in, scope_out) { - return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in); - }; - - elproto.unhover = function (f_in, f_out) { - return this.unmouseover(f_in).unmouseout(f_out); - }; - var draggable = []; - - elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) { - function start(e) { - (e.originalEvent || e).preventDefault(); - var scrollY = g.doc.documentElement.scrollTop || g.doc.body.scrollTop, - scrollX = g.doc.documentElement.scrollLeft || g.doc.body.scrollLeft; - this._drag.x = e.clientX + scrollX; - this._drag.y = e.clientY + scrollY; - this._drag.id = e.identifier; - !drag.length && R.mousemove(dragMove).mouseup(dragUp); - drag.push({el: this, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope}); - onstart && eve.on("raphael.drag.start." + this.id, onstart); - onmove && eve.on("raphael.drag.move." + this.id, onmove); - onend && eve.on("raphael.drag.end." + this.id, onend); - eve("raphael.drag.start." + this.id, start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e); - } - this._drag = {}; - draggable.push({el: this, start: start}); - this.mousedown(start); - return this; - }; - - elproto.onDragOver = function (f) { - f ? eve.on("raphael.drag.over." + this.id, f) : eve.unbind("raphael.drag.over." + this.id); - }; - - elproto.undrag = function () { - var i = draggable.length; - while (i--) if (draggable[i].el == this) { - this.unmousedown(draggable[i].start); - draggable.splice(i, 1); - eve.unbind("raphael.drag.*." + this.id); - } - !draggable.length && R.unmousemove(dragMove).unmouseup(dragUp); - }; - - paperproto.circle = function (x, y, r) { - var out = R._engine.circle(this, x || 0, y || 0, r || 0); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.rect = function (x, y, w, h, r) { - var out = R._engine.rect(this, x || 0, y || 0, w || 0, h || 0, r || 0); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.ellipse = function (x, y, rx, ry) { - var out = R._engine.ellipse(this, x || 0, y || 0, rx || 0, ry || 0); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.path = function (pathString) { - pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E); - var out = R._engine.path(R.format[apply](R, arguments), this); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.image = function (src, x, y, w, h) { - var out = R._engine.image(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.text = function (x, y, text) { - var out = R._engine.text(this, x || 0, y || 0, Str(text)); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.set = function (itemsArray) { - !R.is(itemsArray, "array") && (itemsArray = Array.prototype.splice.call(arguments, 0, arguments.length)); - var out = new Set(itemsArray); - this.__set__ && this.__set__.push(out); - return out; - }; - - paperproto.setStart = function (set) { - this.__set__ = set || this.set(); - }; - - paperproto.setFinish = function (set) { - var out = this.__set__; - delete this.__set__; - return out; - }; - - paperproto.setSize = function (width, height) { - return R._engine.setSize.call(this, width, height); - }; - - paperproto.setViewBox = function (x, y, w, h, fit) { - return R._engine.setViewBox.call(this, x, y, w, h, fit); - }; - - - paperproto.top = paperproto.bottom = null; - - paperproto.raphael = R; - var getOffset = function (elem) { - var box = elem.getBoundingClientRect(), - doc = elem.ownerDocument, - body = doc.body, - docElem = doc.documentElement, - clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, - top = box.top + (g.win.pageYOffset || docElem.scrollTop || body.scrollTop ) - clientTop, - left = box.left + (g.win.pageXOffset || docElem.scrollLeft || body.scrollLeft) - clientLeft; - return { - y: top, - x: left - }; - }; - - paperproto.getElementByPoint = function (x, y) { - var paper = this, - svg = paper.canvas, - target = g.doc.elementFromPoint(x, y); - if (g.win.opera && target.tagName == "svg") { - var so = getOffset(svg), - sr = svg.createSVGRect(); - sr.x = x - so.x; - sr.y = y - so.y; - sr.width = sr.height = 1; - var hits = svg.getIntersectionList(sr, null); - if (hits.length) { - target = hits[hits.length - 1]; - } - } - if (!target) { - return null; - } - while (target.parentNode && target != svg.parentNode && !target.raphael) { - target = target.parentNode; - } - target == paper.canvas.parentNode && (target = svg); - target = target && target.raphael ? paper.getById(target.raphaelid) : null; - return target; - }; - - paperproto.getById = function (id) { - var bot = this.bottom; - while (bot) { - if (bot.id == id) { - return bot; - } - bot = bot.next; - } - return null; - }; - - paperproto.forEach = function (callback, thisArg) { - var bot = this.bottom; - while (bot) { - if (callback.call(thisArg, bot) === false) { - return this; - } - bot = bot.next; - } - return this; - }; - - paperproto.getElementsByPoint = function (x, y) { - var set = this.set(); - this.forEach(function (el) { - if (el.isPointInside(x, y)) { - set.push(el); - } - }); - return set; - }; - function x_y() { - return this.x + S + this.y; - } - function x_y_w_h() { - return this.x + S + this.y + S + this.width + " \xd7 " + this.height; - } - - elproto.isPointInside = function (x, y) { - var rp = this.realPath = this.realPath || getPath[this.type](this); - return R.isPointInsidePath(rp, x, y); - }; - - elproto.getBBox = function (isWithoutTransform) { - if (this.removed) { - return {}; - } - var _ = this._; - if (isWithoutTransform) { - if (_.dirty || !_.bboxwt) { - this.realPath = getPath[this.type](this); - _.bboxwt = pathDimensions(this.realPath); - _.bboxwt.toString = x_y_w_h; - _.dirty = 0; - } - return _.bboxwt; - } - if (_.dirty || _.dirtyT || !_.bbox) { - if (_.dirty || !this.realPath) { - _.bboxwt = 0; - this.realPath = getPath[this.type](this); - } - _.bbox = pathDimensions(mapPath(this.realPath, this.matrix)); - _.bbox.toString = x_y_w_h; - _.dirty = _.dirtyT = 0; - } - return _.bbox; - }; - - elproto.clone = function () { - if (this.removed) { - return null; - } - var out = this.paper[this.type]().attr(this.attr()); - this.__set__ && this.__set__.push(out); - return out; - }; - - elproto.glow = function (glow) { - if (this.type == "text") { - return null; - } - glow = glow || {}; - var s = { - width: (glow.width || 10) + (+this.attr("stroke-width") || 1), - fill: glow.fill || false, - opacity: glow.opacity || .5, - offsetx: glow.offsetx || 0, - offsety: glow.offsety || 0, - color: glow.color || "#000" - }, - c = s.width / 2, - r = this.paper, - out = r.set(), - path = this.realPath || getPath[this.type](this); - path = this.matrix ? mapPath(path, this.matrix) : path; - for (var i = 1; i < c + 1; i++) { - out.push(r.path(path).attr({ - stroke: s.color, - fill: s.fill ? s.color : "none", - "stroke-linejoin": "round", - "stroke-linecap": "round", - "stroke-width": +(s.width / c * i).toFixed(3), - opacity: +(s.opacity / c).toFixed(3) - })); - } - return out.insertBefore(this).translate(s.offsetx, s.offsety); - }; - var curveslengths = {}, - getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) { - if (length == null) { - return bezlen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y); - } else { - return R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, getTatLen(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length)); - } - }, - getLengthFactory = function (istotal, subpath) { - return function (path, length, onlystart) { - path = path2curve(path); - var x, y, p, l, sp = "", subpaths = {}, point, - len = 0; - for (var i = 0, ii = path.length; i < ii; i++) { - p = path[i]; - if (p[0] == "M") { - x = +p[1]; - y = +p[2]; - } else { - l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); - if (len + l > length) { - if (subpath && !subpaths.start) { - point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); - sp += ["C" + point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y]; - if (onlystart) {return sp;} - subpaths.start = sp; - sp = ["M" + point.x, point.y + "C" + point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]].join(); - len += l; - x = +p[5]; - y = +p[6]; - continue; - } - if (!istotal && !subpath) { - point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); - return {x: point.x, y: point.y, alpha: point.alpha}; - } - } - len += l; - x = +p[5]; - y = +p[6]; - } - sp += p.shift() + p; - } - subpaths.end = sp; - point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[0], p[1], p[2], p[3], p[4], p[5], 1); - point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha}); - return point; - }; - }; - var getTotalLength = getLengthFactory(1), - getPointAtLength = getLengthFactory(), - getSubpathsAtLength = getLengthFactory(0, 1); - - R.getTotalLength = getTotalLength; - - R.getPointAtLength = getPointAtLength; - - R.getSubpath = function (path, from, to) { - if (this.getTotalLength(path) - to < 1e-6) { - return getSubpathsAtLength(path, from).end; - } - var a = getSubpathsAtLength(path, to, 1); - return from ? getSubpathsAtLength(a, from).end : a; - }; - - elproto.getTotalLength = function () { - if (this.type != "path") {return;} - if (this.node.getTotalLength) { - return this.node.getTotalLength(); - } - return getTotalLength(this.attrs.path); - }; - - elproto.getPointAtLength = function (length) { - if (this.type != "path") {return;} - return getPointAtLength(this.attrs.path, length); - }; - - elproto.getSubpath = function (from, to) { - if (this.type != "path") {return;} - return R.getSubpath(this.attrs.path, from, to); - }; - - var ef = R.easing_formulas = { - linear: function (n) { - return n; - }, - "<": function (n) { - return pow(n, 1.7); - }, - ">": function (n) { - return pow(n, .48); - }, - "<>": function (n) { - var q = .48 - n / 1.04, - Q = math.sqrt(.1734 + q * q), - x = Q - q, - X = pow(abs(x), 1 / 3) * (x < 0 ? -1 : 1), - y = -Q - q, - Y = pow(abs(y), 1 / 3) * (y < 0 ? -1 : 1), - t = X + Y + .5; - return (1 - t) * 3 * t * t + t * t * t; - }, - backIn: function (n) { - var s = 1.70158; - return n * n * ((s + 1) * n - s); - }, - backOut: function (n) { - n = n - 1; - var s = 1.70158; - return n * n * ((s + 1) * n + s) + 1; - }, - elastic: function (n) { - if (n == !!n) { - return n; - } - return pow(2, -10 * n) * math.sin((n - .075) * (2 * PI) / .3) + 1; - }, - bounce: function (n) { - var s = 7.5625, - p = 2.75, - l; - if (n < (1 / p)) { - l = s * n * n; - } else { - if (n < (2 / p)) { - n -= (1.5 / p); - l = s * n * n + .75; - } else { - if (n < (2.5 / p)) { - n -= (2.25 / p); - l = s * n * n + .9375; - } else { - n -= (2.625 / p); - l = s * n * n + .984375; - } - } - } - return l; - } - }; - ef.easeIn = ef["ease-in"] = ef["<"]; - ef.easeOut = ef["ease-out"] = ef[">"]; - ef.easeInOut = ef["ease-in-out"] = ef["<>"]; - ef["back-in"] = ef.backIn; - ef["back-out"] = ef.backOut; - - var animationElements = [], - requestAnimFrame = window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.oRequestAnimationFrame || - window.msRequestAnimationFrame || - function (callback) { - setTimeout(callback, 16); - }, - animation = function () { - var Now = +new Date, - l = 0; - for (; l < animationElements.length; l++) { - var e = animationElements[l]; - if (e.el.removed || e.paused) { - continue; - } - var time = Now - e.start, - ms = e.ms, - easing = e.easing, - from = e.from, - diff = e.diff, - to = e.to, - t = e.t, - that = e.el, - set = {}, - now, - init = {}, - key; - if (e.initstatus) { - time = (e.initstatus * e.anim.top - e.prev) / (e.percent - e.prev) * ms; - e.status = e.initstatus; - delete e.initstatus; - e.stop && animationElements.splice(l--, 1); - } else { - e.status = (e.prev + (e.percent - e.prev) * (time / ms)) / e.anim.top; - } - if (time < 0) { - continue; - } - if (time < ms) { - var pos = easing(time / ms); - for (var attr in from) if (from[has](attr)) { - switch (availableAnimAttrs[attr]) { - case nu: - now = +from[attr] + pos * ms * diff[attr]; - break; - case "colour": - now = "rgb(" + [ - upto255(round(from[attr].r + pos * ms * diff[attr].r)), - upto255(round(from[attr].g + pos * ms * diff[attr].g)), - upto255(round(from[attr].b + pos * ms * diff[attr].b)) - ].join(",") + ")"; - break; - case "path": - now = []; - for (var i = 0, ii = from[attr].length; i < ii; i++) { - now[i] = [from[attr][i][0]]; - for (var j = 1, jj = from[attr][i].length; j < jj; j++) { - now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j]; - } - now[i] = now[i].join(S); - } - now = now.join(S); - break; - case "transform": - if (diff[attr].real) { - now = []; - for (i = 0, ii = from[attr].length; i < ii; i++) { - now[i] = [from[attr][i][0]]; - for (j = 1, jj = from[attr][i].length; j < jj; j++) { - now[i][j] = from[attr][i][j] + pos * ms * diff[attr][i][j]; - } - } - } else { - var get = function (i) { - return +from[attr][i] + pos * ms * diff[attr][i]; - }; - // now = [["r", get(2), 0, 0], ["t", get(3), get(4)], ["s", get(0), get(1), 0, 0]]; - now = [["m", get(0), get(1), get(2), get(3), get(4), get(5)]]; - } - break; - case "csv": - if (attr == "clip-rect") { - now = []; - i = 4; - while (i--) { - now[i] = +from[attr][i] + pos * ms * diff[attr][i]; - } - } - break; - default: - var from2 = [][concat](from[attr]); - now = []; - i = that.paper.customAttributes[attr].length; - while (i--) { - now[i] = +from2[i] + pos * ms * diff[attr][i]; - } - break; - } - set[attr] = now; - } - that.attr(set); - (function (id, that, anim) { - setTimeout(function () { - eve("raphael.anim.frame." + id, that, anim); - }); - })(that.id, that, e.anim); - } else { - (function(f, el, a) { - setTimeout(function() { - eve("raphael.anim.frame." + el.id, el, a); - eve("raphael.anim.finish." + el.id, el, a); - R.is(f, "function") && f.call(el); - }); - })(e.callback, that, e.anim); - that.attr(to); - animationElements.splice(l--, 1); - if (e.repeat > 1 && !e.next) { - for (key in to) if (to[has](key)) { - init[key] = e.totalOrigin[key]; - } - e.el.attr(init); - runAnimation(e.anim, e.el, e.anim.percents[0], null, e.totalOrigin, e.repeat - 1); - } - if (e.next && !e.stop) { - runAnimation(e.anim, e.el, e.next, null, e.totalOrigin, e.repeat); - } - } - } - R.svg && that && that.paper && that.paper.safari(); - animationElements.length && requestAnimFrame(animation); - }, - upto255 = function (color) { - return color > 255 ? 255 : color < 0 ? 0 : color; - }; - - elproto.animateWith = function (el, anim, params, ms, easing, callback) { - var element = this; - if (element.removed) { - callback && callback.call(element); - return element; - } - var a = params instanceof Animation ? params : R.animation(params, ms, easing, callback), - x, y; - runAnimation(a, element, a.percents[0], null, element.attr()); - for (var i = 0, ii = animationElements.length; i < ii; i++) { - if (animationElements[i].anim == anim && animationElements[i].el == el) { - animationElements[ii - 1].start = animationElements[i].start; - break; - } - } - return element; - // - // - // var a = params ? R.animation(params, ms, easing, callback) : anim, - // status = element.status(anim); - // return this.animate(a).status(a, status * anim.ms / a.ms); - }; - function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) { - var cx = 3 * p1x, - bx = 3 * (p2x - p1x) - cx, - ax = 1 - cx - bx, - cy = 3 * p1y, - by = 3 * (p2y - p1y) - cy, - ay = 1 - cy - by; - function sampleCurveX(t) { - return ((ax * t + bx) * t + cx) * t; - } - function solve(x, epsilon) { - var t = solveCurveX(x, epsilon); - return ((ay * t + by) * t + cy) * t; - } - function solveCurveX(x, epsilon) { - var t0, t1, t2, x2, d2, i; - for(t2 = x, i = 0; i < 8; i++) { - x2 = sampleCurveX(t2) - x; - if (abs(x2) < epsilon) { - return t2; - } - d2 = (3 * ax * t2 + 2 * bx) * t2 + cx; - if (abs(d2) < 1e-6) { - break; - } - t2 = t2 - x2 / d2; - } - t0 = 0; - t1 = 1; - t2 = x; - if (t2 < t0) { - return t0; - } - if (t2 > t1) { - return t1; - } - while (t0 < t1) { - x2 = sampleCurveX(t2); - if (abs(x2 - x) < epsilon) { - return t2; - } - if (x > x2) { - t0 = t2; - } else { - t1 = t2; - } - t2 = (t1 - t0) / 2 + t0; - } - return t2; - } - return solve(t, 1 / (200 * duration)); - } - elproto.onAnimation = function (f) { - f ? eve.on("raphael.anim.frame." + this.id, f) : eve.unbind("raphael.anim.frame." + this.id); - return this; - }; - function Animation(anim, ms) { - var percents = [], - newAnim = {}; - this.ms = ms; - this.times = 1; - if (anim) { - for (var attr in anim) if (anim[has](attr)) { - newAnim[toFloat(attr)] = anim[attr]; - percents.push(toFloat(attr)); - } - percents.sort(sortByNumber); - } - this.anim = newAnim; - this.top = percents[percents.length - 1]; - this.percents = percents; - } - - Animation.prototype.delay = function (delay) { - var a = new Animation(this.anim, this.ms); - a.times = this.times; - a.del = +delay || 0; - return a; - }; - - Animation.prototype.repeat = function (times) { - var a = new Animation(this.anim, this.ms); - a.del = this.del; - a.times = math.floor(mmax(times, 0)) || 1; - return a; - }; - function runAnimation(anim, element, percent, status, totalOrigin, times) { - percent = toFloat(percent); - var params, - isInAnim, - isInAnimSet, - percents = [], - next, - prev, - timestamp, - ms = anim.ms, - from = {}, - to = {}, - diff = {}; - if (status) { - for (i = 0, ii = animationElements.length; i < ii; i++) { - var e = animationElements[i]; - if (e.el.id == element.id && e.anim == anim) { - if (e.percent != percent) { - animationElements.splice(i, 1); - isInAnimSet = 1; - } else { - isInAnim = e; - } - element.attr(e.totalOrigin); - break; - } - } - } else { - status = +to; // NaN - } - for (var i = 0, ii = anim.percents.length; i < ii; i++) { - if (anim.percents[i] == percent || anim.percents[i] > status * anim.top) { - percent = anim.percents[i]; - prev = anim.percents[i - 1] || 0; - ms = ms / anim.top * (percent - prev); - next = anim.percents[i + 1]; - params = anim.anim[percent]; - break; - } else if (status) { - element.attr(anim.anim[anim.percents[i]]); - } - } - if (!params) { - return; - } - if (!isInAnim) { - for (var attr in params) if (params[has](attr)) { - if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) { - from[attr] = element.attr(attr); - (from[attr] == null) && (from[attr] = availableAttrs[attr]); - to[attr] = params[attr]; - switch (availableAnimAttrs[attr]) { - case nu: - diff[attr] = (to[attr] - from[attr]) / ms; - break; - case "colour": - from[attr] = R.getRGB(from[attr]); - var toColour = R.getRGB(to[attr]); - diff[attr] = { - r: (toColour.r - from[attr].r) / ms, - g: (toColour.g - from[attr].g) / ms, - b: (toColour.b - from[attr].b) / ms - }; - break; - case "path": - var pathes = path2curve(from[attr], to[attr]), - toPath = pathes[1]; - from[attr] = pathes[0]; - diff[attr] = []; - for (i = 0, ii = from[attr].length; i < ii; i++) { - diff[attr][i] = [0]; - for (var j = 1, jj = from[attr][i].length; j < jj; j++) { - diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms; - } - } - break; - case "transform": - var _ = element._, - eq = equaliseTransform(_[attr], to[attr]); - if (eq) { - from[attr] = eq.from; - to[attr] = eq.to; - diff[attr] = []; - diff[attr].real = true; - for (i = 0, ii = from[attr].length; i < ii; i++) { - diff[attr][i] = [from[attr][i][0]]; - for (j = 1, jj = from[attr][i].length; j < jj; j++) { - diff[attr][i][j] = (to[attr][i][j] - from[attr][i][j]) / ms; - } - } - } else { - var m = (element.matrix || new Matrix), - to2 = { - _: {transform: _.transform}, - getBBox: function () { - return element.getBBox(1); - } - }; - from[attr] = [ - m.a, - m.b, - m.c, - m.d, - m.e, - m.f - ]; - extractTransform(to2, to[attr]); - to[attr] = to2._.transform; - diff[attr] = [ - (to2.matrix.a - m.a) / ms, - (to2.matrix.b - m.b) / ms, - (to2.matrix.c - m.c) / ms, - (to2.matrix.d - m.d) / ms, - (to2.matrix.e - m.e) / ms, - (to2.matrix.f - m.f) / ms - ]; - // from[attr] = [_.sx, _.sy, _.deg, _.dx, _.dy]; - // var to2 = {_:{}, getBBox: function () { return element.getBBox(); }}; - // extractTransform(to2, to[attr]); - // diff[attr] = [ - // (to2._.sx - _.sx) / ms, - // (to2._.sy - _.sy) / ms, - // (to2._.deg - _.deg) / ms, - // (to2._.dx - _.dx) / ms, - // (to2._.dy - _.dy) / ms - // ]; - } - break; - case "csv": - var values = Str(params[attr])[split](separator), - from2 = Str(from[attr])[split](separator); - if (attr == "clip-rect") { - from[attr] = from2; - diff[attr] = []; - i = from2.length; - while (i--) { - diff[attr][i] = (values[i] - from[attr][i]) / ms; - } - } - to[attr] = values; - break; - default: - values = [][concat](params[attr]); - from2 = [][concat](from[attr]); - diff[attr] = []; - i = element.paper.customAttributes[attr].length; - while (i--) { - diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms; - } - break; - } - } - } - var easing = params.easing, - easyeasy = R.easing_formulas[easing]; - if (!easyeasy) { - easyeasy = Str(easing).match(bezierrg); - if (easyeasy && easyeasy.length == 5) { - var curve = easyeasy; - easyeasy = function (t) { - return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms); - }; - } else { - easyeasy = pipe; - } - } - timestamp = params.start || anim.start || +new Date; - e = { - anim: anim, - percent: percent, - timestamp: timestamp, - start: timestamp + (anim.del || 0), - status: 0, - initstatus: status || 0, - stop: false, - ms: ms, - easing: easyeasy, - from: from, - diff: diff, - to: to, - el: element, - callback: params.callback, - prev: prev, - next: next, - repeat: times || anim.times, - origin: element.attr(), - totalOrigin: totalOrigin - }; - animationElements.push(e); - if (status && !isInAnim && !isInAnimSet) { - e.stop = true; - e.start = new Date - ms * status; - if (animationElements.length == 1) { - return animation(); - } - } - if (isInAnimSet) { - e.start = new Date - e.ms * status; - } - animationElements.length == 1 && requestAnimFrame(animation); - } else { - isInAnim.initstatus = status; - isInAnim.start = new Date - isInAnim.ms * status; - } - eve("raphael.anim.start." + element.id, element, anim); - } - - R.animation = function (params, ms, easing, callback) { - if (params instanceof Animation) { - return params; - } - if (R.is(easing, "function") || !easing) { - callback = callback || easing || null; - easing = null; - } - params = Object(params); - ms = +ms || 0; - var p = {}, - json, - attr; - for (attr in params) if (params[has](attr) && toFloat(attr) != attr && toFloat(attr) + "%" != attr) { - json = true; - p[attr] = params[attr]; - } - if (!json) { - return new Animation(params, ms); - } else { - easing && (p.easing = easing); - callback && (p.callback = callback); - return new Animation({100: p}, ms); - } - }; - - elproto.animate = function (params, ms, easing, callback) { - var element = this; - if (element.removed) { - callback && callback.call(element); - return element; - } - var anim = params instanceof Animation ? params : R.animation(params, ms, easing, callback); - runAnimation(anim, element, anim.percents[0], null, element.attr()); - return element; - }; - - elproto.setTime = function (anim, value) { - if (anim && value != null) { - this.status(anim, mmin(value, anim.ms) / anim.ms); - } - return this; - }; - - elproto.status = function (anim, value) { - var out = [], - i = 0, - len, - e; - if (value != null) { - runAnimation(anim, this, -1, mmin(value, 1)); - return this; - } else { - len = animationElements.length; - for (; i < len; i++) { - e = animationElements[i]; - if (e.el.id == this.id && (!anim || e.anim == anim)) { - if (anim) { - return e.status; - } - out.push({ - anim: e.anim, - status: e.status - }); - } - } - if (anim) { - return 0; - } - return out; - } - }; - - elproto.pause = function (anim) { - for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { - if (eve("raphael.anim.pause." + this.id, this, animationElements[i].anim) !== false) { - animationElements[i].paused = true; - } - } - return this; - }; - - elproto.resume = function (anim) { - for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { - var e = animationElements[i]; - if (eve("raphael.anim.resume." + this.id, this, e.anim) !== false) { - delete e.paused; - this.status(e.anim, e.status); - } - } - return this; - }; - - elproto.stop = function (anim) { - for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.id == this.id && (!anim || animationElements[i].anim == anim)) { - if (eve("raphael.anim.stop." + this.id, this, animationElements[i].anim) !== false) { - animationElements.splice(i--, 1); - } - } - return this; - }; - function stopAnimation(paper) { - for (var i = 0; i < animationElements.length; i++) if (animationElements[i].el.paper == paper) { - animationElements.splice(i--, 1); - } - } - eve.on("raphael.remove", stopAnimation); - eve.on("raphael.clear", stopAnimation); - elproto.toString = function () { - return "Rapha\xebl\u2019s object"; - }; - - // Set - var Set = function (items) { - this.items = []; - this.length = 0; - this.type = "set"; - if (items) { - for (var i = 0, ii = items.length; i < ii; i++) { - if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) { - this[this.items.length] = this.items[this.items.length] = items[i]; - this.length++; - } - } - } - }, - setproto = Set.prototype; - - setproto.push = function () { - var item, - len; - for (var i = 0, ii = arguments.length; i < ii; i++) { - item = arguments[i]; - if (item && (item.constructor == elproto.constructor || item.constructor == Set)) { - len = this.items.length; - this[len] = this.items[len] = item; - this.length++; - } - } - return this; - }; - - setproto.pop = function () { - this.length && delete this[this.length--]; - return this.items.pop(); - }; - - setproto.forEach = function (callback, thisArg) { - for (var i = 0, ii = this.items.length; i < ii; i++) { - if (callback.call(thisArg, this.items[i], i) === false) { - return this; - } - } - return this; - }; - for (var method in elproto) if (elproto[has](method)) { - setproto[method] = (function (methodname) { - return function () { - var arg = arguments; - return this.forEach(function (el) { - el[methodname][apply](el, arg); - }); - }; - })(method); - } - setproto.attr = function (name, value) { - if (name && R.is(name, array) && R.is(name[0], "object")) { - for (var j = 0, jj = name.length; j < jj; j++) { - this.items[j].attr(name[j]); - } - } else { - for (var i = 0, ii = this.items.length; i < ii; i++) { - this.items[i].attr(name, value); - } - } - return this; - }; - - setproto.clear = function () { - while (this.length) { - this.pop(); - } - }; - - setproto.splice = function (index, count, insertion) { - index = index < 0 ? mmax(this.length + index, 0) : index; - count = mmax(0, mmin(this.length - index, count)); - var tail = [], - todel = [], - args = [], - i; - for (i = 2; i < arguments.length; i++) { - args.push(arguments[i]); - } - for (i = 0; i < count; i++) { - todel.push(this[index + i]); - } - for (; i < this.length - index; i++) { - tail.push(this[index + i]); - } - var arglen = args.length; - for (i = 0; i < arglen + tail.length; i++) { - this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen]; - } - i = this.items.length = this.length -= count - arglen; - while (this[i]) { - delete this[i++]; - } - return new Set(todel); - }; - - setproto.exclude = function (el) { - for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) { - this.splice(i, 1); - return true; - } - }; - setproto.animate = function (params, ms, easing, callback) { - (R.is(easing, "function") || !easing) && (callback = easing || null); - var len = this.items.length, - i = len, - item, - set = this, - collector; - if (!len) { - return this; - } - callback && (collector = function () { - !--len && callback.call(set); - }); - easing = R.is(easing, string) ? easing : collector; - var anim = R.animation(params, ms, easing, collector); - item = this.items[--i].animate(anim); - while (i--) { - this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim, anim); - } - return this; - }; - setproto.insertAfter = function (el) { - var i = this.items.length; - while (i--) { - this.items[i].insertAfter(el); - } - return this; - }; - setproto.getBBox = function () { - var x = [], - y = [], - x2 = [], - y2 = []; - for (var i = this.items.length; i--;) if (!this.items[i].removed) { - var box = this.items[i].getBBox(); - x.push(box.x); - y.push(box.y); - x2.push(box.x + box.width); - y2.push(box.y + box.height); - } - x = mmin[apply](0, x); - y = mmin[apply](0, y); - x2 = mmax[apply](0, x2); - y2 = mmax[apply](0, y2); - return { - x: x, - y: y, - x2: x2, - y2: y2, - width: x2 - x, - height: y2 - y - }; - }; - setproto.clone = function (s) { - s = new Set; - for (var i = 0, ii = this.items.length; i < ii; i++) { - s.push(this.items[i].clone()); - } - return s; - }; - setproto.toString = function () { - return "Rapha\xebl\u2018s set"; - }; - - - R.registerFont = function (font) { - if (!font.face) { - return font; - } - this.fonts = this.fonts || {}; - var fontcopy = { - w: font.w, - face: {}, - glyphs: {} - }, - family = font.face["font-family"]; - for (var prop in font.face) if (font.face[has](prop)) { - fontcopy.face[prop] = font.face[prop]; - } - if (this.fonts[family]) { - this.fonts[family].push(fontcopy); - } else { - this.fonts[family] = [fontcopy]; - } - if (!font.svg) { - fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10); - for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) { - var path = font.glyphs[glyph]; - fontcopy.glyphs[glyph] = { - w: path.w, - k: {}, - d: path.d && "M" + path.d.replace(/[mlcxtrv]/g, function (command) { - return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M"; - }) + "z" - }; - if (path.k) { - for (var k in path.k) if (path[has](k)) { - fontcopy.glyphs[glyph].k[k] = path.k[k]; - } - } - } - } - return font; - }; - - paperproto.getFont = function (family, weight, style, stretch) { - stretch = stretch || "normal"; - style = style || "normal"; - weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400; - if (!R.fonts) { - return; - } - var font = R.fonts[family]; - if (!font) { - var name = new RegExp("(^|\\s)" + family.replace(/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i"); - for (var fontName in R.fonts) if (R.fonts[has](fontName)) { - if (name.test(fontName)) { - font = R.fonts[fontName]; - break; - } - } - } - var thefont; - if (font) { - for (var i = 0, ii = font.length; i < ii; i++) { - thefont = font[i]; - if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) { - break; - } - } - } - return thefont; - }; - - paperproto.print = function (x, y, string, font, size, origin, letter_spacing) { - origin = origin || "middle"; // baseline|middle - letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1); - var letters = Str(string)[split](E), - shift = 0, - notfirst = 0, - path = E, - scale; - R.is(font, string) && (font = this.getFont(font)); - if (font) { - scale = (size || 16) / font.face["units-per-em"]; - var bb = font.face.bbox[split](separator), - top = +bb[0], - lineHeight = bb[3] - bb[1], - shifty = 0, - height = +bb[1] + (origin == "baseline" ? lineHeight + (+font.face.descent) : lineHeight / 2); - for (var i = 0, ii = letters.length; i < ii; i++) { - if (letters[i] == "\n") { - shift = 0; - curr = 0; - notfirst = 0; - shifty += lineHeight; - } else { - var prev = notfirst && font.glyphs[letters[i - 1]] || {}, - curr = font.glyphs[letters[i]]; - shift += notfirst ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0; - notfirst = 1; - } - if (curr && curr.d) { - path += R.transformPath(curr.d, ["t", shift * scale, shifty * scale, "s", scale, scale, top, height, "t", (x - top) / scale, (y - height) / scale]); - } - } - } - return this.path(path).attr({ - fill: "#000", - stroke: "none" - }); - }; - - - paperproto.add = function (json) { - if (R.is(json, "array")) { - var res = this.set(), - i = 0, - ii = json.length, - j; - for (; i < ii; i++) { - j = json[i] || {}; - elements[has](j.type) && res.push(this[j.type]().attr(j)); - } - } - return res; - }; - - - R.format = function (token, params) { - var args = R.is(params, array) ? [0][concat](params) : arguments; - token && R.is(token, string) && args.length - 1 && (token = token.replace(formatrg, function (str, i) { - return args[++i] == null ? E : args[i]; - })); - return token || E; - }; - - R.fullfill = (function () { - var tokenRegex = /\{([^\}]+)\}/g, - objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g, // matches .xxxxx or ["xxxxx"] to run over object properties - replacer = function (all, key, obj) { - var res = obj; - key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { - name = name || quotedName; - if (res) { - if (name in res) { - res = res[name]; - } - typeof res == "function" && isFunc && (res = res()); - } - }); - res = (res == null || res == obj ? all : res) + ""; - return res; - }; - return function (str, obj) { - return String(str).replace(tokenRegex, function (all, key) { - return replacer(all, key, obj); - }); - }; - })(); - - R.ninja = function () { - oldRaphael.was ? (g.win.Raphael = oldRaphael.is) : delete Raphael; - return R; - }; - - R.st = setproto; - // Firefox <3.6 fix: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html - (function (doc, loaded, f) { - if (doc.readyState == null && doc.addEventListener){ - doc.addEventListener(loaded, f = function () { - doc.removeEventListener(loaded, f, false); - doc.readyState = "complete"; - }, false); - doc.readyState = "loading"; - } - function isLoaded() { - (/in/).test(doc.readyState) ? setTimeout(isLoaded, 9) : R.eve("raphael.DOMload"); - } - isLoaded(); - })(document, "DOMContentLoaded"); - - oldRaphael.was ? (g.win.Raphael = R) : (Raphael = R); - - eve.on("raphael.DOMload", function () { - loaded = true; - }); -})(); - - -// ┌─────────────────────────────────────────────────────────────────────┠\\ -// │ RaphaĂ«l - JavaScript Vector Library │ \\ -// ├─────────────────────────────────────────────────────────────────────┤ \\ -// │ SVG Module │ \\ -// ├─────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\ -// └─────────────────────────────────────────────────────────────────────┠\\ -window.Raphael.svg && function (R) { - var has = "hasOwnProperty", - Str = String, - toFloat = parseFloat, - toInt = parseInt, - math = Math, - mmax = math.max, - abs = math.abs, - pow = math.pow, - separator = /[, ]+/, - eve = R.eve, - E = "", - S = " "; - var xlink = "http://www.w3.org/1999/xlink", - markers = { - block: "M5,0 0,2.5 5,5z", - classic: "M5,0 0,2.5 5,5 3.5,3 3.5,2z", - diamond: "M2.5,0 5,2.5 2.5,5 0,2.5z", - open: "M6,1 1,3.5 6,6", - oval: "M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z" - }, - markerCounter = {}; - R.toString = function () { - return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version; - }; - var $ = function (el, attr) { - if (attr) { - if (typeof el == "string") { - el = $(el); - } - for (var key in attr) if (attr[has](key)) { - if (key.substring(0, 6) == "xlink:") { - el.setAttributeNS(xlink, key.substring(6), Str(attr[key])); - } else { - el.setAttribute(key, Str(attr[key])); - } - } - } else { - el = R._g.doc.createElementNS("http://www.w3.org/2000/svg", el); - el.style && (el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"); - } - return el; - }, - addGradientFill = function (element, gradient) { - var type = "linear", - id = element.id + gradient, - fx = .5, fy = .5, - o = element.node, - SVG = element.paper, - s = o.style, - el = R._g.doc.getElementById(id); - if (!el) { - gradient = Str(gradient).replace(R._radial_gradient, function (all, _fx, _fy) { - type = "radial"; - if (_fx && _fy) { - fx = toFloat(_fx); - fy = toFloat(_fy); - var dir = ((fy > .5) * 2 - 1); - pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && - (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) && - fy != .5 && - (fy = fy.toFixed(5) - 1e-5 * dir); - } - return E; - }); - gradient = gradient.split(/\s*\-\s*/); - if (type == "linear") { - var angle = gradient.shift(); - angle = -toFloat(angle); - if (isNaN(angle)) { - return null; - } - var vector = [0, 0, math.cos(R.rad(angle)), math.sin(R.rad(angle))], - max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1); - vector[2] *= max; - vector[3] *= max; - if (vector[2] < 0) { - vector[0] = -vector[2]; - vector[2] = 0; - } - if (vector[3] < 0) { - vector[1] = -vector[3]; - vector[3] = 0; - } - } - var dots = R._parseDots(gradient); - if (!dots) { - return null; - } - id = id.replace(/[\(\)\s,\xb0#]/g, "_"); - - if (element.gradient && id != element.gradient.id) { - SVG.defs.removeChild(element.gradient); - delete element.gradient; - } - - if (!element.gradient) { - el = $(type + "Gradient", {id: id}); - element.gradient = el; - $(el, type == "radial" ? { - fx: fx, - fy: fy - } : { - x1: vector[0], - y1: vector[1], - x2: vector[2], - y2: vector[3], - gradientTransform: element.matrix.invert() - }); - SVG.defs.appendChild(el); - for (var i = 0, ii = dots.length; i < ii; i++) { - el.appendChild($("stop", { - offset: dots[i].offset ? dots[i].offset : i ? "100%" : "0%", - "stop-color": dots[i].color || "#fff" - })); - } - } - } - $(o, { - fill: "url(#" + id + ")", - opacity: 1, - "fill-opacity": 1 - }); - s.fill = E; - s.opacity = 1; - s.fillOpacity = 1; - return 1; - }, - updatePosition = function (o) { - var bbox = o.getBBox(1); - $(o.pattern, {patternTransform: o.matrix.invert() + " translate(" + bbox.x + "," + bbox.y + ")"}); - }, - addArrow = function (o, value, isEnd) { - if (o.type == "path") { - var values = Str(value).toLowerCase().split("-"), - p = o.paper, - se = isEnd ? "end" : "start", - node = o.node, - attrs = o.attrs, - stroke = attrs["stroke-width"], - i = values.length, - type = "classic", - from, - to, - dx, - refX, - attr, - w = 3, - h = 3, - t = 5; - while (i--) { - switch (values[i]) { - case "block": - case "classic": - case "oval": - case "diamond": - case "open": - case "none": - type = values[i]; - break; - case "wide": h = 5; break; - case "narrow": h = 2; break; - case "long": w = 5; break; - case "short": w = 2; break; - } - } - if (type == "open") { - w += 2; - h += 2; - t += 2; - dx = 1; - refX = isEnd ? 4 : 1; - attr = { - fill: "none", - stroke: attrs.stroke - }; - } else { - refX = dx = w / 2; - attr = { - fill: attrs.stroke, - stroke: "none" - }; - } - if (o._.arrows) { - if (isEnd) { - o._.arrows.endPath && markerCounter[o._.arrows.endPath]--; - o._.arrows.endMarker && markerCounter[o._.arrows.endMarker]--; - } else { - o._.arrows.startPath && markerCounter[o._.arrows.startPath]--; - o._.arrows.startMarker && markerCounter[o._.arrows.startMarker]--; - } - } else { - o._.arrows = {}; - } - if (type != "none") { - var pathId = "raphael-marker-" + type, - markerId = "raphael-marker-" + se + type + w + h; - if (!R._g.doc.getElementById(pathId)) { - p.defs.appendChild($($("path"), { - "stroke-linecap": "round", - d: markers[type], - id: pathId - })); - markerCounter[pathId] = 1; - } else { - markerCounter[pathId]++; - } - var marker = R._g.doc.getElementById(markerId), - use; - if (!marker) { - marker = $($("marker"), { - id: markerId, - markerHeight: h, - markerWidth: w, - orient: "auto", - refX: refX, - refY: h / 2 - }); - use = $($("use"), { - "xlink:href": "#" + pathId, - transform: (isEnd ? "rotate(180 " + w / 2 + " " + h / 2 + ") " : E) + "scale(" + w / t + "," + h / t + ")", - "stroke-width": (1 / ((w / t + h / t) / 2)).toFixed(4) - }); - marker.appendChild(use); - p.defs.appendChild(marker); - markerCounter[markerId] = 1; - } else { - markerCounter[markerId]++; - use = marker.getElementsByTagName("use")[0]; - } - $(use, attr); - var delta = dx * (type != "diamond" && type != "oval"); - if (isEnd) { - from = o._.arrows.startdx * stroke || 0; - to = R.getTotalLength(attrs.path) - delta * stroke; - } else { - from = delta * stroke; - to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0); - } - attr = {}; - attr["marker-" + se] = "url(#" + markerId + ")"; - if (to || from) { - attr.d = Raphael.getSubpath(attrs.path, from, to); - } - $(node, attr); - o._.arrows[se + "Path"] = pathId; - o._.arrows[se + "Marker"] = markerId; - o._.arrows[se + "dx"] = delta; - o._.arrows[se + "Type"] = type; - o._.arrows[se + "String"] = value; - } else { - if (isEnd) { - from = o._.arrows.startdx * stroke || 0; - to = R.getTotalLength(attrs.path) - from; - } else { - from = 0; - to = R.getTotalLength(attrs.path) - (o._.arrows.enddx * stroke || 0); - } - o._.arrows[se + "Path"] && $(node, {d: Raphael.getSubpath(attrs.path, from, to)}); - delete o._.arrows[se + "Path"]; - delete o._.arrows[se + "Marker"]; - delete o._.arrows[se + "dx"]; - delete o._.arrows[se + "Type"]; - delete o._.arrows[se + "String"]; - } - for (attr in markerCounter) if (markerCounter[has](attr) && !markerCounter[attr]) { - var item = R._g.doc.getElementById(attr); - item && item.parentNode.removeChild(item); - } - } - }, - dasharray = { - "": [0], - "none": [0], - "-": [3, 1], - ".": [1, 1], - "-.": [3, 1, 1, 1], - "-..": [3, 1, 1, 1, 1, 1], - ". ": [1, 3], - "- ": [4, 3], - "--": [8, 3], - "- .": [4, 3, 1, 3], - "--.": [8, 3, 1, 3], - "--..": [8, 3, 1, 3, 1, 3] - }, - addDashes = function (o, value, params) { - value = dasharray[Str(value).toLowerCase()]; - if (value) { - var width = o.attrs["stroke-width"] || "1", - butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0, - dashes = [], - i = value.length; - while (i--) { - dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt; - } - $(o.node, {"stroke-dasharray": dashes.join(",")}); - } - }, - setFillAndStroke = function (o, params) { - var node = o.node, - attrs = o.attrs, - vis = node.style.visibility; - node.style.visibility = "hidden"; - for (var att in params) { - if (params[has](att)) { - if (!R._availableAttrs[has](att)) { - continue; - } - var value = params[att]; - attrs[att] = value; - switch (att) { - case "blur": - o.blur(value); - break; - case "href": - case "title": - case "target": - var pn = node.parentNode; - if (pn.tagName.toLowerCase() != "a") { - var hl = $("a"); - pn.insertBefore(hl, node); - hl.appendChild(node); - pn = hl; - } - if (att == "target") { - pn.setAttributeNS(xlink, "show", value == "blank" ? "new" : value); - } else { - pn.setAttributeNS(xlink, att, value); - } - break; - case "cursor": - node.style.cursor = value; - break; - case "transform": - o.transform(value); - break; - case "arrow-start": - addArrow(o, value); - break; - case "arrow-end": - addArrow(o, value, 1); - break; - case "clip-rect": - var rect = Str(value).split(separator); - if (rect.length == 4) { - o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode); - var el = $("clipPath"), - rc = $("rect"); - el.id = R.createUUID(); - $(rc, { - x: rect[0], - y: rect[1], - width: rect[2], - height: rect[3] - }); - el.appendChild(rc); - o.paper.defs.appendChild(el); - $(node, {"clip-path": "url(#" + el.id + ")"}); - o.clip = rc; - } - if (!value) { - var path = node.getAttribute("clip-path"); - if (path) { - var clip = R._g.doc.getElementById(path.replace(/(^url\(#|\)$)/g, E)); - clip && clip.parentNode.removeChild(clip); - $(node, {"clip-path": E}); - delete o.clip; - } - } - break; - case "path": - if (o.type == "path") { - $(node, {d: value ? attrs.path = R._pathToAbsolute(value) : "M0,0"}); - o._.dirty = 1; - if (o._.arrows) { - "startString" in o._.arrows && addArrow(o, o._.arrows.startString); - "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); - } - } - break; - case "width": - node.setAttribute(att, value); - o._.dirty = 1; - if (attrs.fx) { - att = "x"; - value = attrs.x; - } else { - break; - } - case "x": - if (attrs.fx) { - value = -attrs.x - (attrs.width || 0); - } - case "rx": - if (att == "rx" && o.type == "rect") { - break; - } - case "cx": - node.setAttribute(att, value); - o.pattern && updatePosition(o); - o._.dirty = 1; - break; - case "height": - node.setAttribute(att, value); - o._.dirty = 1; - if (attrs.fy) { - att = "y"; - value = attrs.y; - } else { - break; - } - case "y": - if (attrs.fy) { - value = -attrs.y - (attrs.height || 0); - } - case "ry": - if (att == "ry" && o.type == "rect") { - break; - } - case "cy": - node.setAttribute(att, value); - o.pattern && updatePosition(o); - o._.dirty = 1; - break; - case "r": - if (o.type == "rect") { - $(node, {rx: value, ry: value}); - } else { - node.setAttribute(att, value); - } - o._.dirty = 1; - break; - case "src": - if (o.type == "image") { - node.setAttributeNS(xlink, "href", value); - } - break; - case "stroke-width": - if (o._.sx != 1 || o._.sy != 1) { - value /= mmax(abs(o._.sx), abs(o._.sy)) || 1; - } - if (o.paper._vbSize) { - value *= o.paper._vbSize; - } - node.setAttribute(att, value); - if (attrs["stroke-dasharray"]) { - addDashes(o, attrs["stroke-dasharray"], params); - } - if (o._.arrows) { - "startString" in o._.arrows && addArrow(o, o._.arrows.startString); - "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); - } - break; - case "stroke-dasharray": - addDashes(o, value, params); - break; - case "fill": - var isURL = Str(value).match(R._ISURL); - if (isURL) { - el = $("pattern"); - var ig = $("image"); - el.id = R.createUUID(); - $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1}); - $(ig, {x: 0, y: 0, "xlink:href": isURL[1]}); - el.appendChild(ig); - - (function (el) { - R._preload(isURL[1], function () { - var w = this.offsetWidth, - h = this.offsetHeight; - $(el, {width: w, height: h}); - $(ig, {width: w, height: h}); - o.paper.safari(); - }); - })(el); - o.paper.defs.appendChild(el); - $(node, {fill: "url(#" + el.id + ")"}); - o.pattern = el; - o.pattern && updatePosition(o); - break; - } - var clr = R.getRGB(value); - if (!clr.error) { - delete params.gradient; - delete attrs.gradient; - !R.is(attrs.opacity, "undefined") && - R.is(params.opacity, "undefined") && - $(node, {opacity: attrs.opacity}); - !R.is(attrs["fill-opacity"], "undefined") && - R.is(params["fill-opacity"], "undefined") && - $(node, {"fill-opacity": attrs["fill-opacity"]}); - } else if ((o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value)) { - if ("opacity" in attrs || "fill-opacity" in attrs) { - var gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E)); - if (gradient) { - var stops = gradient.getElementsByTagName("stop"); - $(stops[stops.length - 1], {"stop-opacity": ("opacity" in attrs ? attrs.opacity : 1) * ("fill-opacity" in attrs ? attrs["fill-opacity"] : 1)}); - } - } - attrs.gradient = value; - attrs.fill = "none"; - break; - } - clr[has]("opacity") && $(node, {"fill-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); - case "stroke": - clr = R.getRGB(value); - node.setAttribute(att, clr.hex); - att == "stroke" && clr[has]("opacity") && $(node, {"stroke-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); - if (att == "stroke" && o._.arrows) { - "startString" in o._.arrows && addArrow(o, o._.arrows.startString); - "endString" in o._.arrows && addArrow(o, o._.arrows.endString, 1); - } - break; - case "gradient": - (o.type == "circle" || o.type == "ellipse" || Str(value).charAt() != "r") && addGradientFill(o, value); - break; - case "opacity": - if (attrs.gradient && !attrs[has]("stroke-opacity")) { - $(node, {"stroke-opacity": value > 1 ? value / 100 : value}); - } - // fall - case "fill-opacity": - if (attrs.gradient) { - gradient = R._g.doc.getElementById(node.getAttribute("fill").replace(/^url\(#|\)$/g, E)); - if (gradient) { - stops = gradient.getElementsByTagName("stop"); - $(stops[stops.length - 1], {"stop-opacity": value}); - } - break; - } - default: - att == "font-size" && (value = toInt(value, 10) + "px"); - var cssrule = att.replace(/(\-.)/g, function (w) { - return w.substring(1).toUpperCase(); - }); - node.style[cssrule] = value; - o._.dirty = 1; - node.setAttribute(att, value); - break; - } - } - } - - tuneText(o, params); - node.style.visibility = vis; - }, - leading = 1.2, - tuneText = function (el, params) { - if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) { - return; - } - var a = el.attrs, - node = el.node, - fontSize = node.firstChild ? toInt(R._g.doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10; - - if (params[has]("text")) { - a.text = params.text; - while (node.firstChild) { - node.removeChild(node.firstChild); - } - var texts = Str(params.text).split("\n"), - tspans = [], - tspan; - for (var i = 0, ii = texts.length; i < ii; i++) { - tspan = $("tspan"); - i && $(tspan, {dy: fontSize * leading, x: a.x}); - tspan.appendChild(R._g.doc.createTextNode(texts[i])); - node.appendChild(tspan); - tspans[i] = tspan; - } - } else { - tspans = node.getElementsByTagName("tspan"); - for (i = 0, ii = tspans.length; i < ii; i++) if (i) { - $(tspans[i], {dy: fontSize * leading, x: a.x}); - } else { - $(tspans[0], {dy: 0}); - } - } - $(node, {x: a.x, y: a.y}); - el._.dirty = 1; - var bb = el._getBBox(), - dif = a.y - (bb.y + bb.height / 2); - dif && R.is(dif, "finite") && $(tspans[0], {dy: dif}); - }, - Element = function (node, svg) { - var X = 0, - Y = 0; - - this[0] = this.node = node; - - node.raphael = true; - - this.id = R._oid++; - node.raphaelid = this.id; - this.matrix = R.matrix(); - this.realPath = null; - - this.paper = svg; - this.attrs = this.attrs || {}; - this._ = { - transform: [], - sx: 1, - sy: 1, - deg: 0, - dx: 0, - dy: 0, - dirty: 1 - }; - !svg.bottom && (svg.bottom = this); - - this.prev = svg.top; - svg.top && (svg.top.next = this); - svg.top = this; - - this.next = null; - }, - elproto = R.el; - - Element.prototype = elproto; - elproto.constructor = Element; - - R._engine.path = function (pathString, SVG) { - var el = $("path"); - SVG.canvas && SVG.canvas.appendChild(el); - var p = new Element(el, SVG); - p.type = "path"; - setFillAndStroke(p, { - fill: "none", - stroke: "#000", - path: pathString - }); - return p; - }; - - elproto.rotate = function (deg, cx, cy) { - if (this.removed) { - return this; - } - deg = Str(deg).split(separator); - if (deg.length - 1) { - cx = toFloat(deg[1]); - cy = toFloat(deg[2]); - } - deg = toFloat(deg[0]); - (cy == null) && (cx = cy); - if (cx == null || cy == null) { - var bbox = this.getBBox(1); - cx = bbox.x + bbox.width / 2; - cy = bbox.y + bbox.height / 2; - } - this.transform(this._.transform.concat([["r", deg, cx, cy]])); - return this; - }; - - elproto.scale = function (sx, sy, cx, cy) { - if (this.removed) { - return this; - } - sx = Str(sx).split(separator); - if (sx.length - 1) { - sy = toFloat(sx[1]); - cx = toFloat(sx[2]); - cy = toFloat(sx[3]); - } - sx = toFloat(sx[0]); - (sy == null) && (sy = sx); - (cy == null) && (cx = cy); - if (cx == null || cy == null) { - var bbox = this.getBBox(1); - } - cx = cx == null ? bbox.x + bbox.width / 2 : cx; - cy = cy == null ? bbox.y + bbox.height / 2 : cy; - this.transform(this._.transform.concat([["s", sx, sy, cx, cy]])); - return this; - }; - - elproto.translate = function (dx, dy) { - if (this.removed) { - return this; - } - dx = Str(dx).split(separator); - if (dx.length - 1) { - dy = toFloat(dx[1]); - } - dx = toFloat(dx[0]) || 0; - dy = +dy || 0; - this.transform(this._.transform.concat([["t", dx, dy]])); - return this; - }; - - elproto.transform = function (tstr) { - var _ = this._; - if (tstr == null) { - return _.transform; - } - R._extractTransform(this, tstr); - - this.clip && $(this.clip, {transform: this.matrix.invert()}); - this.pattern && updatePosition(this); - this.node && $(this.node, {transform: this.matrix}); - - if (_.sx != 1 || _.sy != 1) { - var sw = this.attrs[has]("stroke-width") ? this.attrs["stroke-width"] : 1; - this.attr({"stroke-width": sw}); - } - - return this; - }; - - elproto.hide = function () { - !this.removed && this.paper.safari(this.node.style.display = "none"); - return this; - }; - - elproto.show = function () { - !this.removed && this.paper.safari(this.node.style.display = ""); - return this; - }; - - elproto.remove = function () { - if (this.removed || !this.node.parentNode) { - return; - } - var paper = this.paper; - paper.__set__ && paper.__set__.exclude(this); - eve.unbind("raphael.*.*." + this.id); - if (this.gradient) { - paper.defs.removeChild(this.gradient); - } - R._tear(this, paper); - if (this.node.parentNode.tagName.toLowerCase() == "a") { - this.node.parentNode.parentNode.removeChild(this.node.parentNode); - } else { - this.node.parentNode.removeChild(this.node); - } - for (var i in this) { - this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; - } - this.removed = true; - }; - elproto._getBBox = function () { - if (this.node.style.display == "none") { - this.show(); - var hide = true; - } - var bbox = {}; - try { - bbox = this.node.getBBox(); - } catch(e) { - // Firefox 3.0.x plays badly here - } finally { - bbox = bbox || {}; - } - hide && this.hide(); - return bbox; - }; - - elproto.attr = function (name, value) { - if (this.removed) { - return this; - } - if (name == null) { - var res = {}; - for (var a in this.attrs) if (this.attrs[has](a)) { - res[a] = this.attrs[a]; - } - res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; - res.transform = this._.transform; - return res; - } - if (value == null && R.is(name, "string")) { - if (name == "fill" && this.attrs.fill == "none" && this.attrs.gradient) { - return this.attrs.gradient; - } - if (name == "transform") { - return this._.transform; - } - var names = name.split(separator), - out = {}; - for (var i = 0, ii = names.length; i < ii; i++) { - name = names[i]; - if (name in this.attrs) { - out[name] = this.attrs[name]; - } else if (R.is(this.paper.customAttributes[name], "function")) { - out[name] = this.paper.customAttributes[name].def; - } else { - out[name] = R._availableAttrs[name]; - } - } - return ii - 1 ? out : out[names[0]]; - } - if (value == null && R.is(name, "array")) { - out = {}; - for (i = 0, ii = name.length; i < ii; i++) { - out[name[i]] = this.attr(name[i]); - } - return out; - } - if (value != null) { - var params = {}; - params[name] = value; - } else if (name != null && R.is(name, "object")) { - params = name; - } - for (var key in params) { - eve("raphael.attr." + key + "." + this.id, this, params[key]); - } - for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { - var par = this.paper.customAttributes[key].apply(this, [].concat(params[key])); - this.attrs[key] = params[key]; - for (var subkey in par) if (par[has](subkey)) { - params[subkey] = par[subkey]; - } - } - setFillAndStroke(this, params); - return this; - }; - - elproto.toFront = function () { - if (this.removed) { - return this; - } - if (this.node.parentNode.tagName.toLowerCase() == "a") { - this.node.parentNode.parentNode.appendChild(this.node.parentNode); - } else { - this.node.parentNode.appendChild(this.node); - } - var svg = this.paper; - svg.top != this && R._tofront(this, svg); - return this; - }; - - elproto.toBack = function () { - if (this.removed) { - return this; - } - var parent = this.node.parentNode; - if (parent.tagName.toLowerCase() == "a") { - parent.parentNode.insertBefore(this.node.parentNode, this.node.parentNode.parentNode.firstChild); - } else if (parent.firstChild != this.node) { - parent.insertBefore(this.node, this.node.parentNode.firstChild); - } - R._toback(this, this.paper); - var svg = this.paper; - return this; - }; - - elproto.insertAfter = function (element) { - if (this.removed) { - return this; - } - var node = element.node || element[element.length - 1].node; - if (node.nextSibling) { - node.parentNode.insertBefore(this.node, node.nextSibling); - } else { - node.parentNode.appendChild(this.node); - } - R._insertafter(this, element, this.paper); - return this; - }; - - elproto.insertBefore = function (element) { - if (this.removed) { - return this; - } - var node = element.node || element[0].node; - node.parentNode.insertBefore(this.node, node); - R._insertbefore(this, element, this.paper); - return this; - }; - elproto.blur = function (size) { - // Experimental. No Safari support. Use it on your own risk. - var t = this; - if (+size !== 0) { - var fltr = $("filter"), - blur = $("feGaussianBlur"); - t.attrs.blur = size; - fltr.id = R.createUUID(); - $(blur, {stdDeviation: +size || 1.5}); - fltr.appendChild(blur); - t.paper.defs.appendChild(fltr); - t._blur = fltr; - $(t.node, {filter: "url(#" + fltr.id + ")"}); - } else { - if (t._blur) { - t._blur.parentNode.removeChild(t._blur); - delete t._blur; - delete t.attrs.blur; - } - t.node.removeAttribute("filter"); - } - }; - R._engine.circle = function (svg, x, y, r) { - var el = $("circle"); - svg.canvas && svg.canvas.appendChild(el); - var res = new Element(el, svg); - res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"}; - res.type = "circle"; - $(el, res.attrs); - return res; - }; - R._engine.rect = function (svg, x, y, w, h, r) { - var el = $("rect"); - svg.canvas && svg.canvas.appendChild(el); - var res = new Element(el, svg); - res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"}; - res.type = "rect"; - $(el, res.attrs); - return res; - }; - R._engine.ellipse = function (svg, x, y, rx, ry) { - var el = $("ellipse"); - svg.canvas && svg.canvas.appendChild(el); - var res = new Element(el, svg); - res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"}; - res.type = "ellipse"; - $(el, res.attrs); - return res; - }; - R._engine.image = function (svg, src, x, y, w, h) { - var el = $("image"); - $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"}); - el.setAttributeNS(xlink, "href", src); - svg.canvas && svg.canvas.appendChild(el); - var res = new Element(el, svg); - res.attrs = {x: x, y: y, width: w, height: h, src: src}; - res.type = "image"; - return res; - }; - R._engine.text = function (svg, x, y, text) { - var el = $("text"); - svg.canvas && svg.canvas.appendChild(el); - var res = new Element(el, svg); - res.attrs = { - x: x, - y: y, - "text-anchor": "middle", - text: text, - font: R._availableAttrs.font, - stroke: "none", - fill: "#000" - }; - res.type = "text"; - setFillAndStroke(res, res.attrs); - return res; - }; - R._engine.setSize = function (width, height) { - this.width = width || this.width; - this.height = height || this.height; - this.canvas.setAttribute("width", this.width); - this.canvas.setAttribute("height", this.height); - if (this._viewBox) { - this.setViewBox.apply(this, this._viewBox); - } - return this; - }; - R._engine.create = function () { - var con = R._getContainer.apply(0, arguments), - container = con && con.container, - x = con.x, - y = con.y, - width = con.width, - height = con.height; - if (!container) { - throw new Error("SVG container not found."); - } - var cnvs = $("svg"), - css = "overflow:hidden;", - isFloating; - x = x || 0; - y = y || 0; - width = width || 512; - height = height || 342; - $(cnvs, { - height: height, - version: 1.1, - width: width, - xmlns: "http://www.w3.org/2000/svg" - }); - if (container == 1) { - cnvs.style.cssText = css + "position:absolute;left:" + x + "px;top:" + y + "px"; - R._g.doc.body.appendChild(cnvs); - isFloating = 1; - } else { - cnvs.style.cssText = css + "position:relative"; - if (container.firstChild) { - container.insertBefore(cnvs, container.firstChild); - } else { - container.appendChild(cnvs); - } - } - container = new R._Paper; - container.width = width; - container.height = height; - container.canvas = cnvs; - container.clear(); - container._left = container._top = 0; - isFloating && (container.renderfix = function () {}); - container.renderfix(); - return container; - }; - R._engine.setViewBox = function (x, y, w, h, fit) { - eve("raphael.setViewBox", this, this._viewBox, [x, y, w, h, fit]); - var size = mmax(w / this.width, h / this.height), - top = this.top, - aspectRatio = fit ? "meet" : "xMinYMin", - vb, - sw; - if (x == null) { - if (this._vbSize) { - size = 1; - } - delete this._vbSize; - vb = "0 0 " + this.width + S + this.height; - } else { - this._vbSize = size; - vb = x + S + y + S + w + S + h; - } - $(this.canvas, { - viewBox: vb, - preserveAspectRatio: aspectRatio - }); - while (size && top) { - sw = "stroke-width" in top.attrs ? top.attrs["stroke-width"] : 1; - top.attr({"stroke-width": sw}); - top._.dirty = 1; - top._.dirtyT = 1; - top = top.prev; - } - this._viewBox = [x, y, w, h, !!fit]; - return this; - }; - - R.prototype.renderfix = function () { - var cnvs = this.canvas, - s = cnvs.style, - pos; - try { - pos = cnvs.getScreenCTM() || cnvs.createSVGMatrix(); - } catch (e) { - pos = cnvs.createSVGMatrix(); - } - var left = -pos.e % 1, - top = -pos.f % 1; - if (left || top) { - if (left) { - this._left = (this._left + left) % 1; - s.left = this._left + "px"; - } - if (top) { - this._top = (this._top + top) % 1; - s.top = this._top + "px"; - } - } - }; - - R.prototype.clear = function () { - R.eve("raphael.clear", this); - var c = this.canvas; - while (c.firstChild) { - c.removeChild(c.firstChild); - } - this.bottom = this.top = null; - (this.desc = $("desc")).appendChild(R._g.doc.createTextNode("Created with Rapha\xebl " + R.version)); - c.appendChild(this.desc); - c.appendChild(this.defs = $("defs")); - }; - - R.prototype.remove = function () { - eve("raphael.remove", this); - this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); - for (var i in this) { - this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; - } - }; - var setproto = R.st; - for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) { - setproto[method] = (function (methodname) { - return function () { - var arg = arguments; - return this.forEach(function (el) { - el[methodname].apply(el, arg); - }); - }; - })(method); - } -}(window.Raphael); - -// ┌─────────────────────────────────────────────────────────────────────┠\\ -// │ RaphaĂ«l - JavaScript Vector Library │ \\ -// ├─────────────────────────────────────────────────────────────────────┤ \\ -// │ VML Module │ \\ -// ├─────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright (c) 2008-2011 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright (c) 2008-2011 Sencha Labs (http://sencha.com) │ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license. │ \\ -// └─────────────────────────────────────────────────────────────────────┠\\ -window.Raphael.vml && function (R) { - var has = "hasOwnProperty", - Str = String, - toFloat = parseFloat, - math = Math, - round = math.round, - mmax = math.max, - mmin = math.min, - abs = math.abs, - fillString = "fill", - separator = /[, ]+/, - eve = R.eve, - ms = " progid:DXImageTransform.Microsoft", - S = " ", - E = "", - map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"}, - bites = /([clmz]),?([^clmz]*)/gi, - blurregexp = / progid:\S+Blur\([^\)]+\)/g, - val = /-?[^,\s-]+/g, - cssDot = "position:absolute;left:0;top:0;width:1px;height:1px", - zoom = 21600, - pathTypes = {path: 1, rect: 1, image: 1}, - ovalTypes = {circle: 1, ellipse: 1}, - path2vml = function (path) { - var total = /[ahqstv]/ig, - command = R._pathToAbsolute; - Str(path).match(total) && (command = R._path2curve); - total = /[clmz]/g; - if (command == R._pathToAbsolute && !Str(path).match(total)) { - var res = Str(path).replace(bites, function (all, command, args) { - var vals = [], - isMove = command.toLowerCase() == "m", - res = map[command]; - args.replace(val, function (value) { - if (isMove && vals.length == 2) { - res += vals + map[command == "m" ? "l" : "L"]; - vals = []; - } - vals.push(round(value * zoom)); - }); - return res + vals; - }); - return res; - } - var pa = command(path), p, r; - res = []; - for (var i = 0, ii = pa.length; i < ii; i++) { - p = pa[i]; - r = pa[i][0].toLowerCase(); - r == "z" && (r = "x"); - for (var j = 1, jj = p.length; j < jj; j++) { - r += round(p[j] * zoom) + (j != jj - 1 ? "," : E); - } - res.push(r); - } - return res.join(S); - }, - compensation = function (deg, dx, dy) { - var m = R.matrix(); - m.rotate(-deg, .5, .5); - return { - dx: m.x(dx, dy), - dy: m.y(dx, dy) - }; - }, - setCoords = function (p, sx, sy, dx, dy, deg) { - var _ = p._, - m = p.matrix, - fillpos = _.fillpos, - o = p.node, - s = o.style, - y = 1, - flip = "", - dxdy, - kx = zoom / sx, - ky = zoom / sy; - s.visibility = "hidden"; - if (!sx || !sy) { - return; - } - o.coordsize = abs(kx) + S + abs(ky); - s.rotation = deg * (sx * sy < 0 ? -1 : 1); - if (deg) { - var c = compensation(deg, dx, dy); - dx = c.dx; - dy = c.dy; - } - sx < 0 && (flip += "x"); - sy < 0 && (flip += " y") && (y = -1); - s.flip = flip; - o.coordorigin = (dx * -kx) + S + (dy * -ky); - if (fillpos || _.fillsize) { - var fill = o.getElementsByTagName(fillString); - fill = fill && fill[0]; - o.removeChild(fill); - if (fillpos) { - c = compensation(deg, m.x(fillpos[0], fillpos[1]), m.y(fillpos[0], fillpos[1])); - fill.position = c.dx * y + S + c.dy * y; - } - if (_.fillsize) { - fill.size = _.fillsize[0] * abs(sx) + S + _.fillsize[1] * abs(sy); - } - o.appendChild(fill); - } - s.visibility = "visible"; - }; - R.toString = function () { - return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version; - }; - var addArrow = function (o, value, isEnd) { - var values = Str(value).toLowerCase().split("-"), - se = isEnd ? "end" : "start", - i = values.length, - type = "classic", - w = "medium", - h = "medium"; - while (i--) { - switch (values[i]) { - case "block": - case "classic": - case "oval": - case "diamond": - case "open": - case "none": - type = values[i]; - break; - case "wide": - case "narrow": h = values[i]; break; - case "long": - case "short": w = values[i]; break; - } - } - var stroke = o.node.getElementsByTagName("stroke")[0]; - stroke[se + "arrow"] = type; - stroke[se + "arrowlength"] = w; - stroke[se + "arrowwidth"] = h; - }, - setFillAndStroke = function (o, params) { - // o.paper.canvas.style.display = "none"; - o.attrs = o.attrs || {}; - var node = o.node, - a = o.attrs, - s = node.style, - xy, - newpath = pathTypes[o.type] && (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.cx != a.cx || params.cy != a.cy || params.rx != a.rx || params.ry != a.ry || params.r != a.r), - isOval = ovalTypes[o.type] && (a.cx != params.cx || a.cy != params.cy || a.r != params.r || a.rx != params.rx || a.ry != params.ry), - res = o; - - - for (var par in params) if (params[has](par)) { - a[par] = params[par]; - } - if (newpath) { - a.path = R._getPath[o.type](o); - o._.dirty = 1; - } - params.href && (node.href = params.href); - params.title && (node.title = params.title); - params.target && (node.target = params.target); - params.cursor && (s.cursor = params.cursor); - "blur" in params && o.blur(params.blur); - if (params.path && o.type == "path" || newpath) { - node.path = path2vml(~Str(a.path).toLowerCase().indexOf("r") ? R._pathToAbsolute(a.path) : a.path); - if (o.type == "image") { - o._.fillpos = [a.x, a.y]; - o._.fillsize = [a.width, a.height]; - setCoords(o, 1, 1, 0, 0, 0); - } - } - "transform" in params && o.transform(params.transform); - if (isOval) { - var cx = +a.cx, - cy = +a.cy, - rx = +a.rx || +a.r || 0, - ry = +a.ry || +a.r || 0; - node.path = R.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x", round((cx - rx) * zoom), round((cy - ry) * zoom), round((cx + rx) * zoom), round((cy + ry) * zoom), round(cx * zoom)); - } - if ("clip-rect" in params) { - var rect = Str(params["clip-rect"]).split(separator); - if (rect.length == 4) { - rect[2] = +rect[2] + (+rect[0]); - rect[3] = +rect[3] + (+rect[1]); - var div = node.clipRect || R._g.doc.createElement("div"), - dstyle = div.style; - dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect); - if (!node.clipRect) { - dstyle.position = "absolute"; - dstyle.top = 0; - dstyle.left = 0; - dstyle.width = o.paper.width + "px"; - dstyle.height = o.paper.height + "px"; - node.parentNode.insertBefore(div, node); - div.appendChild(node); - node.clipRect = div; - } - } - if (!params["clip-rect"]) { - node.clipRect && (node.clipRect.style.clip = "auto"); - } - } - if (o.textpath) { - var textpathStyle = o.textpath.style; - params.font && (textpathStyle.font = params.font); - params["font-family"] && (textpathStyle.fontFamily = '"' + params["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g, E) + '"'); - params["font-size"] && (textpathStyle.fontSize = params["font-size"]); - params["font-weight"] && (textpathStyle.fontWeight = params["font-weight"]); - params["font-style"] && (textpathStyle.fontStyle = params["font-style"]); - } - if ("arrow-start" in params) { - addArrow(res, params["arrow-start"]); - } - if ("arrow-end" in params) { - addArrow(res, params["arrow-end"], 1); - } - if (params.opacity != null || - params["stroke-width"] != null || - params.fill != null || - params.src != null || - params.stroke != null || - params["stroke-width"] != null || - params["stroke-opacity"] != null || - params["fill-opacity"] != null || - params["stroke-dasharray"] != null || - params["stroke-miterlimit"] != null || - params["stroke-linejoin"] != null || - params["stroke-linecap"] != null) { - var fill = node.getElementsByTagName(fillString), - newfill = false; - fill = fill && fill[0]; - !fill && (newfill = fill = createNode(fillString)); - if (o.type == "image" && params.src) { - fill.src = params.src; - } - params.fill && (fill.on = true); - if (fill.on == null || params.fill == "none" || params.fill === null) { - fill.on = false; - } - if (fill.on && params.fill) { - var isURL = Str(params.fill).match(R._ISURL); - if (isURL) { - fill.parentNode == node && node.removeChild(fill); - fill.rotate = true; - fill.src = isURL[1]; - fill.type = "tile"; - var bbox = o.getBBox(1); - fill.position = bbox.x + S + bbox.y; - o._.fillpos = [bbox.x, bbox.y]; - - R._preload(isURL[1], function () { - o._.fillsize = [this.offsetWidth, this.offsetHeight]; - }); - } else { - fill.color = R.getRGB(params.fill).hex; - fill.src = E; - fill.type = "solid"; - if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != "r") && addGradientFill(res, params.fill, fill)) { - a.fill = "none"; - a.gradient = params.fill; - fill.rotate = false; - } - } - } - if ("fill-opacity" in params || "opacity" in params) { - var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1); - opacity = mmin(mmax(opacity, 0), 1); - fill.opacity = opacity; - if (fill.src) { - fill.color = "none"; - } - } - node.appendChild(fill); - var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]), - newstroke = false; - !stroke && (newstroke = stroke = createNode("stroke")); - if ((params.stroke && params.stroke != "none") || - params["stroke-width"] || - params["stroke-opacity"] != null || - params["stroke-dasharray"] || - params["stroke-miterlimit"] || - params["stroke-linejoin"] || - params["stroke-linecap"]) { - stroke.on = true; - } - (params.stroke == "none" || params.stroke === null || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false); - var strokeColor = R.getRGB(params.stroke); - stroke.on && params.stroke && (stroke.color = strokeColor.hex); - opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1); - var width = (toFloat(params["stroke-width"]) || 1) * .75; - opacity = mmin(mmax(opacity, 0), 1); - params["stroke-width"] == null && (width = a["stroke-width"]); - params["stroke-width"] && (stroke.weight = width); - width && width < 1 && (opacity *= width) && (stroke.weight = 1); - stroke.opacity = opacity; - - params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter"); - stroke.miterlimit = params["stroke-miterlimit"] || 8; - params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round"); - if (params["stroke-dasharray"]) { - var dasharray = { - "-": "shortdash", - ".": "shortdot", - "-.": "shortdashdot", - "-..": "shortdashdotdot", - ". ": "dot", - "- ": "dash", - "--": "longdash", - "- .": "dashdot", - "--.": "longdashdot", - "--..": "longdashdotdot" - }; - stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E; - } - newstroke && node.appendChild(stroke); - } - if (res.type == "text") { - res.paper.canvas.style.display = E; - var span = res.paper.span, - m = 100, - fontSize = a.font && a.font.match(/\d+(?:\.\d*)?(?=px)/); - s = span.style; - a.font && (s.font = a.font); - a["font-family"] && (s.fontFamily = a["font-family"]); - a["font-weight"] && (s.fontWeight = a["font-weight"]); - a["font-style"] && (s.fontStyle = a["font-style"]); - fontSize = toFloat(a["font-size"] || fontSize && fontSize[0]) || 10; - s.fontSize = fontSize * m + "px"; - res.textpath.string && (span.innerHTML = Str(res.textpath.string).replace(/")); - var brect = span.getBoundingClientRect(); - res.W = a.w = (brect.right - brect.left) / m; - res.H = a.h = (brect.bottom - brect.top) / m; - // res.paper.canvas.style.display = "none"; - res.X = a.x; - res.Y = a.y + res.H / 2; - - ("x" in params || "y" in params) && (res.path.v = R.format("m{0},{1}l{2},{1}", round(a.x * zoom), round(a.y * zoom), round(a.x * zoom) + 1)); - var dirtyattrs = ["x", "y", "text", "font", "font-family", "font-weight", "font-style", "font-size"]; - for (var d = 0, dd = dirtyattrs.length; d < dd; d++) if (dirtyattrs[d] in params) { - res._.dirty = 1; - break; - } - - // text-anchor emulation - switch (a["text-anchor"]) { - case "start": - res.textpath.style["v-text-align"] = "left"; - res.bbx = res.W / 2; - break; - case "end": - res.textpath.style["v-text-align"] = "right"; - res.bbx = -res.W / 2; - break; - default: - res.textpath.style["v-text-align"] = "center"; - res.bbx = 0; - break; - } - res.textpath.style["v-text-kern"] = true; - } - // res.paper.canvas.style.display = E; - }, - addGradientFill = function (o, gradient, fill) { - o.attrs = o.attrs || {}; - var attrs = o.attrs, - pow = Math.pow, - opacity, - oindex, - type = "linear", - fxfy = ".5 .5"; - o.attrs.gradient = gradient; - gradient = Str(gradient).replace(R._radial_gradient, function (all, fx, fy) { - type = "radial"; - if (fx && fy) { - fx = toFloat(fx); - fy = toFloat(fy); - pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5); - fxfy = fx + S + fy; - } - return E; - }); - gradient = gradient.split(/\s*\-\s*/); - if (type == "linear") { - var angle = gradient.shift(); - angle = -toFloat(angle); - if (isNaN(angle)) { - return null; - } - } - var dots = R._parseDots(gradient); - if (!dots) { - return null; - } - o = o.shape || o.node; - if (dots.length) { - o.removeChild(fill); - fill.on = true; - fill.method = "none"; - fill.color = dots[0].color; - fill.color2 = dots[dots.length - 1].color; - var clrs = []; - for (var i = 0, ii = dots.length; i < ii; i++) { - dots[i].offset && clrs.push(dots[i].offset + S + dots[i].color); - } - fill.colors = clrs.length ? clrs.join() : "0% " + fill.color; - if (type == "radial") { - fill.type = "gradientTitle"; - fill.focus = "100%"; - fill.focussize = "0 0"; - fill.focusposition = fxfy; - fill.angle = 0; - } else { - // fill.rotate= true; - fill.type = "gradient"; - fill.angle = (270 - angle) % 360; - } - o.appendChild(fill); - } - return 1; - }, - Element = function (node, vml) { - this[0] = this.node = node; - node.raphael = true; - this.id = R._oid++; - node.raphaelid = this.id; - this.X = 0; - this.Y = 0; - this.attrs = {}; - this.paper = vml; - this.matrix = R.matrix(); - this._ = { - transform: [], - sx: 1, - sy: 1, - dx: 0, - dy: 0, - deg: 0, - dirty: 1, - dirtyT: 1 - }; - !vml.bottom && (vml.bottom = this); - this.prev = vml.top; - vml.top && (vml.top.next = this); - vml.top = this; - this.next = null; - }; - var elproto = R.el; - - Element.prototype = elproto; - elproto.constructor = Element; - elproto.transform = function (tstr) { - if (tstr == null) { - return this._.transform; - } - var vbs = this.paper._viewBoxShift, - vbt = vbs ? "s" + [vbs.scale, vbs.scale] + "-1-1t" + [vbs.dx, vbs.dy] : E, - oldt; - if (vbs) { - oldt = tstr = Str(tstr).replace(/\.{3}|\u2026/g, this._.transform || E); - } - R._extractTransform(this, vbt + tstr); - var matrix = this.matrix.clone(), - skew = this.skew, - o = this.node, - split, - isGrad = ~Str(this.attrs.fill).indexOf("-"), - isPatt = !Str(this.attrs.fill).indexOf("url("); - matrix.translate(-.5, -.5); - if (isPatt || isGrad || this.type == "image") { - skew.matrix = "1 0 0 1"; - skew.offset = "0 0"; - split = matrix.split(); - if ((isGrad && split.noRotation) || !split.isSimple) { - o.style.filter = matrix.toFilter(); - var bb = this.getBBox(), - bbt = this.getBBox(1), - dx = bb.x - bbt.x, - dy = bb.y - bbt.y; - o.coordorigin = (dx * -zoom) + S + (dy * -zoom); - setCoords(this, 1, 1, dx, dy, 0); - } else { - o.style.filter = E; - setCoords(this, split.scalex, split.scaley, split.dx, split.dy, split.rotate); - } - } else { - o.style.filter = E; - skew.matrix = Str(matrix); - skew.offset = matrix.offset(); - } - oldt && (this._.transform = oldt); - return this; - }; - elproto.rotate = function (deg, cx, cy) { - if (this.removed) { - return this; - } - if (deg == null) { - return; - } - deg = Str(deg).split(separator); - if (deg.length - 1) { - cx = toFloat(deg[1]); - cy = toFloat(deg[2]); - } - deg = toFloat(deg[0]); - (cy == null) && (cx = cy); - if (cx == null || cy == null) { - var bbox = this.getBBox(1); - cx = bbox.x + bbox.width / 2; - cy = bbox.y + bbox.height / 2; - } - this._.dirtyT = 1; - this.transform(this._.transform.concat([["r", deg, cx, cy]])); - return this; - }; - elproto.translate = function (dx, dy) { - if (this.removed) { - return this; - } - dx = Str(dx).split(separator); - if (dx.length - 1) { - dy = toFloat(dx[1]); - } - dx = toFloat(dx[0]) || 0; - dy = +dy || 0; - if (this._.bbox) { - this._.bbox.x += dx; - this._.bbox.y += dy; - } - this.transform(this._.transform.concat([["t", dx, dy]])); - return this; - }; - elproto.scale = function (sx, sy, cx, cy) { - if (this.removed) { - return this; - } - sx = Str(sx).split(separator); - if (sx.length - 1) { - sy = toFloat(sx[1]); - cx = toFloat(sx[2]); - cy = toFloat(sx[3]); - isNaN(cx) && (cx = null); - isNaN(cy) && (cy = null); - } - sx = toFloat(sx[0]); - (sy == null) && (sy = sx); - (cy == null) && (cx = cy); - if (cx == null || cy == null) { - var bbox = this.getBBox(1); - } - cx = cx == null ? bbox.x + bbox.width / 2 : cx; - cy = cy == null ? bbox.y + bbox.height / 2 : cy; - - this.transform(this._.transform.concat([["s", sx, sy, cx, cy]])); - this._.dirtyT = 1; - return this; - }; - elproto.hide = function () { - !this.removed && (this.node.style.display = "none"); - return this; - }; - elproto.show = function () { - !this.removed && (this.node.style.display = E); - return this; - }; - elproto._getBBox = function () { - if (this.removed) { - return {}; - } - return { - x: this.X + (this.bbx || 0) - this.W / 2, - y: this.Y - this.H, - width: this.W, - height: this.H - }; - }; - elproto.remove = function () { - if (this.removed || !this.node.parentNode) { - return; - } - this.paper.__set__ && this.paper.__set__.exclude(this); - R.eve.unbind("raphael.*.*." + this.id); - R._tear(this, this.paper); - this.node.parentNode.removeChild(this.node); - this.shape && this.shape.parentNode.removeChild(this.shape); - for (var i in this) { - this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; - } - this.removed = true; - }; - elproto.attr = function (name, value) { - if (this.removed) { - return this; - } - if (name == null) { - var res = {}; - for (var a in this.attrs) if (this.attrs[has](a)) { - res[a] = this.attrs[a]; - } - res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; - res.transform = this._.transform; - return res; - } - if (value == null && R.is(name, "string")) { - if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) { - return this.attrs.gradient; - } - var names = name.split(separator), - out = {}; - for (var i = 0, ii = names.length; i < ii; i++) { - name = names[i]; - if (name in this.attrs) { - out[name] = this.attrs[name]; - } else if (R.is(this.paper.customAttributes[name], "function")) { - out[name] = this.paper.customAttributes[name].def; - } else { - out[name] = R._availableAttrs[name]; - } - } - return ii - 1 ? out : out[names[0]]; - } - if (this.attrs && value == null && R.is(name, "array")) { - out = {}; - for (i = 0, ii = name.length; i < ii; i++) { - out[name[i]] = this.attr(name[i]); - } - return out; - } - var params; - if (value != null) { - params = {}; - params[name] = value; - } - value == null && R.is(name, "object") && (params = name); - for (var key in params) { - eve("raphael.attr." + key + "." + this.id, this, params[key]); - } - if (params) { - for (key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { - var par = this.paper.customAttributes[key].apply(this, [].concat(params[key])); - this.attrs[key] = params[key]; - for (var subkey in par) if (par[has](subkey)) { - params[subkey] = par[subkey]; - } - } - // this.paper.canvas.style.display = "none"; - if (params.text && this.type == "text") { - this.textpath.string = params.text; - } - setFillAndStroke(this, params); - // this.paper.canvas.style.display = E; - } - return this; - }; - elproto.toFront = function () { - !this.removed && this.node.parentNode.appendChild(this.node); - this.paper && this.paper.top != this && R._tofront(this, this.paper); - return this; - }; - elproto.toBack = function () { - if (this.removed) { - return this; - } - if (this.node.parentNode.firstChild != this.node) { - this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild); - R._toback(this, this.paper); - } - return this; - }; - elproto.insertAfter = function (element) { - if (this.removed) { - return this; - } - if (element.constructor == R.st.constructor) { - element = element[element.length - 1]; - } - if (element.node.nextSibling) { - element.node.parentNode.insertBefore(this.node, element.node.nextSibling); - } else { - element.node.parentNode.appendChild(this.node); - } - R._insertafter(this, element, this.paper); - return this; - }; - elproto.insertBefore = function (element) { - if (this.removed) { - return this; - } - if (element.constructor == R.st.constructor) { - element = element[0]; - } - element.node.parentNode.insertBefore(this.node, element.node); - R._insertbefore(this, element, this.paper); - return this; - }; - elproto.blur = function (size) { - var s = this.node.runtimeStyle, - f = s.filter; - f = f.replace(blurregexp, E); - if (+size !== 0) { - this.attrs.blur = size; - s.filter = f + S + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")"; - s.margin = R.format("-{0}px 0 0 -{0}px", round(+size || 1.5)); - } else { - s.filter = f; - s.margin = 0; - delete this.attrs.blur; - } - }; - - R._engine.path = function (pathString, vml) { - var el = createNode("shape"); - el.style.cssText = cssDot; - el.coordsize = zoom + S + zoom; - el.coordorigin = vml.coordorigin; - var p = new Element(el, vml), - attr = {fill: "none", stroke: "#000"}; - pathString && (attr.path = pathString); - p.type = "path"; - p.path = []; - p.Path = E; - setFillAndStroke(p, attr); - vml.canvas.appendChild(el); - var skew = createNode("skew"); - skew.on = true; - el.appendChild(skew); - p.skew = skew; - p.transform(E); - return p; - }; - R._engine.rect = function (vml, x, y, w, h, r) { - var path = R._rectPath(x, y, w, h, r), - res = vml.path(path), - a = res.attrs; - res.X = a.x = x; - res.Y = a.y = y; - res.W = a.width = w; - res.H = a.height = h; - a.r = r; - a.path = path; - res.type = "rect"; - return res; - }; - R._engine.ellipse = function (vml, x, y, rx, ry) { - var res = vml.path(), - a = res.attrs; - res.X = x - rx; - res.Y = y - ry; - res.W = rx * 2; - res.H = ry * 2; - res.type = "ellipse"; - setFillAndStroke(res, { - cx: x, - cy: y, - rx: rx, - ry: ry - }); - return res; - }; - R._engine.circle = function (vml, x, y, r) { - var res = vml.path(), - a = res.attrs; - res.X = x - r; - res.Y = y - r; - res.W = res.H = r * 2; - res.type = "circle"; - setFillAndStroke(res, { - cx: x, - cy: y, - r: r - }); - return res; - }; - R._engine.image = function (vml, src, x, y, w, h) { - var path = R._rectPath(x, y, w, h), - res = vml.path(path).attr({stroke: "none"}), - a = res.attrs, - node = res.node, - fill = node.getElementsByTagName(fillString)[0]; - a.src = src; - res.X = a.x = x; - res.Y = a.y = y; - res.W = a.width = w; - res.H = a.height = h; - a.path = path; - res.type = "image"; - fill.parentNode == node && node.removeChild(fill); - fill.rotate = true; - fill.src = src; - fill.type = "tile"; - res._.fillpos = [x, y]; - res._.fillsize = [w, h]; - node.appendChild(fill); - setCoords(res, 1, 1, 0, 0, 0); - return res; - }; - R._engine.text = function (vml, x, y, text) { - var el = createNode("shape"), - path = createNode("path"), - o = createNode("textpath"); - x = x || 0; - y = y || 0; - text = text || ""; - path.v = R.format("m{0},{1}l{2},{1}", round(x * zoom), round(y * zoom), round(x * zoom) + 1); - path.textpathok = true; - o.string = Str(text); - o.on = true; - el.style.cssText = cssDot; - el.coordsize = zoom + S + zoom; - el.coordorigin = "0 0"; - var p = new Element(el, vml), - attr = { - fill: "#000", - stroke: "none", - font: R._availableAttrs.font, - text: text - }; - p.shape = el; - p.path = path; - p.textpath = o; - p.type = "text"; - p.attrs.text = Str(text); - p.attrs.x = x; - p.attrs.y = y; - p.attrs.w = 1; - p.attrs.h = 1; - setFillAndStroke(p, attr); - el.appendChild(o); - el.appendChild(path); - vml.canvas.appendChild(el); - var skew = createNode("skew"); - skew.on = true; - el.appendChild(skew); - p.skew = skew; - p.transform(E); - return p; - }; - R._engine.setSize = function (width, height) { - var cs = this.canvas.style; - this.width = width; - this.height = height; - width == +width && (width += "px"); - height == +height && (height += "px"); - cs.width = width; - cs.height = height; - cs.clip = "rect(0 " + width + " " + height + " 0)"; - if (this._viewBox) { - R._engine.setViewBox.apply(this, this._viewBox); - } - return this; - }; - R._engine.setViewBox = function (x, y, w, h, fit) { - R.eve("raphael.setViewBox", this, this._viewBox, [x, y, w, h, fit]); - var width = this.width, - height = this.height, - size = 1 / mmax(w / width, h / height), - H, W; - if (fit) { - H = height / h; - W = width / w; - if (w * H < width) { - x -= (width - w * H) / 2 / H; - } - if (h * W < height) { - y -= (height - h * W) / 2 / W; - } - } - this._viewBox = [x, y, w, h, !!fit]; - this._viewBoxShift = { - dx: -x, - dy: -y, - scale: size - }; - this.forEach(function (el) { - el.transform("..."); - }); - return this; - }; - var createNode; - R._engine.initWin = function (win) { - var doc = win.document; - doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)"); - try { - !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); - createNode = function (tagName) { - return doc.createElement(''); - }; - } catch (e) { - createNode = function (tagName) { - return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">'); - }; - } - }; - R._engine.initWin(R._g.win); - R._engine.create = function () { - var con = R._getContainer.apply(0, arguments), - container = con.container, - height = con.height, - s, - width = con.width, - x = con.x, - y = con.y; - if (!container) { - throw new Error("VML container not found."); - } - var res = new R._Paper, - c = res.canvas = R._g.doc.createElement("div"), - cs = c.style; - x = x || 0; - y = y || 0; - width = width || 512; - height = height || 342; - res.width = width; - res.height = height; - width == +width && (width += "px"); - height == +height && (height += "px"); - res.coordsize = zoom * 1e3 + S + zoom * 1e3; - res.coordorigin = "0 0"; - res.span = R._g.doc.createElement("span"); - res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;"; - c.appendChild(res.span); - cs.cssText = R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", width, height); - if (container == 1) { - R._g.doc.body.appendChild(c); - cs.left = x + "px"; - cs.top = y + "px"; - cs.position = "absolute"; - } else { - if (container.firstChild) { - container.insertBefore(c, container.firstChild); - } else { - container.appendChild(c); - } - } - res.renderfix = function () {}; - return res; - }; - R.prototype.clear = function () { - R.eve("raphael.clear", this); - this.canvas.innerHTML = E; - this.span = R._g.doc.createElement("span"); - this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;"; - this.canvas.appendChild(this.span); - this.bottom = this.top = null; - }; - R.prototype.remove = function () { - R.eve("raphael.remove", this); - this.canvas.parentNode.removeChild(this.canvas); - for (var i in this) { - this[i] = typeof this[i] == "function" ? R._removedFactory(i) : null; - } - return true; - }; - - var setproto = R.st; - for (var method in elproto) if (elproto[has](method) && !setproto[has](method)) { - setproto[method] = (function (methodname) { - return function () { - var arg = arguments; - return this.forEach(function (el) { - el[methodname].apply(el, arg); - }); - }; - })(method); - } -}(window.Raphael); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael-2.1.2.js b/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael-2.1.2.js deleted file mode 100755 index 7977840f93..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael-2.1.2.js +++ /dev/null @@ -1,11 +0,0 @@ -// ┌────────────────────────────────────────────────────────────────────┠\\ -// │ RaphaĂ«l 2.1.2 - JavaScript Vector Library │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Copyright © 2008-2012 Dmitry Baranovskiy (http://raphaeljs.com) │ \\ -// │ Copyright © 2008-2012 Sencha Labs (http://sencha.com) │ \\ -// ├────────────────────────────────────────────────────────────────────┤ \\ -// │ Licensed under the MIT (http://raphaeljs.com/license.html) license.│ \\ -// └────────────────────────────────────────────────────────────────────┠\\ -!function(a) {var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g="*",h=function(){},i=function(a,b){return a-b},j={n:{}},k=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=k.listeners(a),j=0,l=[],m={},n=[],o=b;b=a,c=0;for(var p=0,q=h.length;q>p;p++)"zIndex"in h[p]&&(l.push(h[p].zIndex),h[p].zIndex<0&&(m[h[p].zIndex]=h[p]));for(l.sort(i);l[j]<0;)if(e=m[l[j++]],n.push(e.apply(d,g)),c)return c=f,n;for(p=0;q>p;p++)if(e=h[p],"zIndex"in e)if(e.zIndex==l[j]){if(n.push(e.apply(d,g)),c)break;do if(j++,e=m[l[j]],e&&n.push(e.apply(d,g)),c)break;while(e)}else m[e.zIndex]=e;else if(n.push(e.apply(d,g)),c)break;return c=f,b=o,n.length?n:null};k._events=j,k.listeners=function(a){var b,c,d,e,h,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,h=m.length;h>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[g]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},k.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(f),d=j,e=0,g=c.length;g>e;e++)d=d.n,d=d.hasOwnProperty(c[e])&&d[c[e]]||(d[c[e]]={n:{}});for(d.f=d.f||[],e=0,g=d.f.length;g>e;e++)if(d.f[e]==b)return h;return d.f.push(b),function(a){+a==+a&&(b.zIndex=+a)}},k.f=function(a){var b=[].slice.call(arguments,1);return function(){k.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},k.stop=function(){c=1},k.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},k.nts=function(){return b.split(f)},k.off=k.unbind=function(a,b){if(!a)return k._events=j={n:{}},void 0;var c,d,h,i,l,m,n,o=a.split(f),p=[j];for(i=0,l=o.length;l>i;i++)for(m=0;mi;i++)for(c=p[i];c.n;){if(b){if(c.f){for(m=0,n=c.f.length;n>m;m++)if(c.f[m]==b){c.f.splice(m,1);break}!c.f.length&&delete c.f}for(d in c.n)if(c.n[e](d)&&c.n[d].f){var q=c.n[d].f;for(m=0,n=q.length;n>m;m++)if(q[m]==b){q.splice(m,1);break}!q.length&&delete c.n[d].f}}else{delete c.f;for(d in c.n)c.n[e](d)&&c.n[d].f&&delete c.n[d].f}c=c.n}},k.once=function(a,b){var c=function(){return k.unbind(a,c),b.apply(this,arguments)};return k.on(a,c)},k.version=d,k.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=k:"undefined"!=typeof define?define("eve",[],function(){return k}):a.eve=k}(this),function(a,b){"function"==typeof define&&define.amd?define(["eve"],function(c){return b(a,c)}):b(a,a.eve)}(this,function(a,b){function c(a){if(c.is(a,"function"))return u?a():b.on("raphael.DOMload",a);if(c.is(a,V))return c._engine.create[D](c,a.splice(0,3+c.is(a[0],T))).add(a);var d=Array.prototype.slice.call(arguments,0);if(c.is(d[d.length-1],"function")){var e=d.pop();return u?e.call(c._engine.create[D](c,d)):b.on("raphael.DOMload",function(){e.call(c._engine.create[D](c,d))})}return c._engine.create[D](c,arguments)}function d(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=d(a[c]));return b}function e(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function f(a,b,c){function d(){var f=Array.prototype.slice.call(arguments,0),g=f.join("â€"),h=d.cache=d.cache||{},i=d.count=d.count||[];return h[z](g)?(e(i,g),c?c(h[g]):h[g]):(i.length>=1e3&&delete h[i.shift()],i.push(g),h[g]=a[D](b,f),c?c(h[g]):h[g])}return d}function g(){return this.hex}function h(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}function i(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function j(a,b,c,d,e,f,g,h,j){null==j&&(j=1),j=j>1?1:0>j?0:j;for(var k=j/2,l=12,m=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;l>p;p++){var q=k*m[p]+k,r=i(q,a,c,e,g),s=i(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return k*o}function k(a,b,c,d,e,f,g,h,i){if(!(0>i||j(a,b,c,d,e,f,g,h)o;)m/=2,n+=(i>k?1:-1)*m,k=j(a,b,c,d,e,f,g,h,n);return n}}function l(a,b,c,d,e,f,g,h){if(!(O(a,c)O(e,g)||O(b,d)O(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+O(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+O(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+O(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+O(f,h).toFixed(2)))return{x:l,y:m}}}}function m(a,b,d){var e=c.bezierBBox(a),f=c.bezierBBox(b);if(!c.isBBoxIntersect(e,f))return d?0:[];for(var g=j.apply(0,a),h=j.apply(0,b),i=O(~~(g/5),1),k=O(~~(h/5),1),m=[],n=[],o={},p=d?0:[],q=0;i+1>q;q++){var r=c.findDotsAtSegment.apply(c,a.concat(q/i));m.push({x:r.x,y:r.y,t:q/i})}for(q=0;k+1>q;q++)r=c.findDotsAtSegment.apply(c,b.concat(q/k)),n.push({x:r.x,y:r.y,t:q/k});for(q=0;i>q;q++)for(var s=0;k>s;s++){var t=m[q],u=m[q+1],v=n[s],w=n[s+1],x=Q(u.x-t.x)<.001?"y":"x",y=Q(w.x-v.x)<.001?"y":"x",z=l(t.x,t.y,u.x,u.y,v.x,v.y,w.x,w.y);if(z){if(o[z.x.toFixed(4)]==z.y.toFixed(4))continue;o[z.x.toFixed(4)]=z.y.toFixed(4);var A=t.t+Q((z[x]-t[x])/(u[x]-t[x]))*(u.t-t.t),B=v.t+Q((z[y]-v[y])/(w[y]-v[y]))*(w.t-v.t);A>=0&&1.001>=A&&B>=0&&1.001>=B&&(d?p++:p.push({x:z.x,y:z.y,t1:P(A,1),t2:P(B,1)}))}}return p}function n(a,b,d){a=c._path2curve(a),b=c._path2curve(b);for(var e,f,g,h,i,j,k,l,n,o,p=d?0:[],q=0,r=a.length;r>q;q++){var s=a[q];if("M"==s[0])e=i=s[1],f=j=s[2];else{"C"==s[0]?(n=[e,f].concat(s.slice(1)),e=n[6],f=n[7]):(n=[e,f,e,f,i,j,i,j],e=i,f=j);for(var t=0,u=b.length;u>t;t++){var v=b[t];if("M"==v[0])g=k=v[1],h=l=v[2];else{"C"==v[0]?(o=[g,h].concat(v.slice(1)),g=o[6],h=o[7]):(o=[g,h,g,h,k,l,k,l],g=k,h=l);var w=m(n,o,d);if(d)p+=w;else{for(var x=0,y=w.length;y>x;x++)w[x].segment1=q,w[x].segment2=t,w[x].bez1=n,w[x].bez2=o;p=p.concat(w)}}}}}return p}function o(a,b,c,d,e,f){null!=a?(this.a=+a,this.b=+b,this.c=+c,this.d=+d,this.e=+e,this.f=+f):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0)}function p(){return this.x+H+this.y+H+this.width+" Ă— "+this.height}function q(a,b,c,d,e,f){function g(a){return((l*a+k)*a+j)*a}function h(a,b){var c=i(a,b);return((o*c+n)*c+m)*c}function i(a,b){var c,d,e,f,h,i;for(e=a,i=0;8>i;i++){if(f=g(e)-a,Q(f)e)return c;if(e>d)return d;for(;d>c;){if(f=g(e),Q(f-a)f?c=e:d=e,e=(d-c)/2+c}return e}var j=3*b,k=3*(d-b)-j,l=1-j-k,m=3*c,n=3*(e-c)-m,o=1-m-n;return h(a,1/(200*f))}function r(a,b){var c=[],d={};if(this.ms=b,this.times=1,a){for(var e in a)a[z](e)&&(d[_(e)]=a[e],c.push(_(e)));c.sort(lb)}this.anim=d,this.top=c[c.length-1],this.percents=c}function s(a,d,e,f,g,h){e=_(e);var i,j,k,l,m,n,p=a.ms,r={},s={},t={};if(f)for(v=0,x=ic.length;x>v;v++){var u=ic[v];if(u.el.id==d.id&&u.anim==a){u.percent!=e?(ic.splice(v,1),k=1):j=u,d.attr(u.totalOrigin);break}}else f=+s;for(var v=0,x=a.percents.length;x>v;v++){if(a.percents[v]==e||a.percents[v]>f*a.top){e=a.percents[v],m=a.percents[v-1]||0,p=p/a.top*(e-m),l=a.percents[v+1],i=a.anim[e];break}f&&d.attr(a.anim[a.percents[v]])}if(i){if(j)j.initstatus=f,j.start=new Date-j.ms*f;else{for(var y in i)if(i[z](y)&&(db[z](y)||d.paper.customAttributes[z](y)))switch(r[y]=d.attr(y),null==r[y]&&(r[y]=cb[y]),s[y]=i[y],db[y]){case T:t[y]=(s[y]-r[y])/p;break;case"colour":r[y]=c.getRGB(r[y]);var A=c.getRGB(s[y]);t[y]={r:(A.r-r[y].r)/p,g:(A.g-r[y].g)/p,b:(A.b-r[y].b)/p};break;case"path":var B=Kb(r[y],s[y]),C=B[1];for(r[y]=B[0],t[y]=[],v=0,x=r[y].length;x>v;v++){t[y][v]=[0];for(var D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(C[v][D]-r[y][v][D])/p}break;case"transform":var G=d._,H=Pb(G[y],s[y]);if(H)for(r[y]=H.from,s[y]=H.to,t[y]=[],t[y].real=!0,v=0,x=r[y].length;x>v;v++)for(t[y][v]=[r[y][v][0]],D=1,F=r[y][v].length;F>D;D++)t[y][v][D]=(s[y][v][D]-r[y][v][D])/p;else{var K=d.matrix||new o,L={_:{transform:G.transform},getBBox:function(){return d.getBBox(1)}};r[y]=[K.a,K.b,K.c,K.d,K.e,K.f],Nb(L,s[y]),s[y]=L._.transform,t[y]=[(L.matrix.a-K.a)/p,(L.matrix.b-K.b)/p,(L.matrix.c-K.c)/p,(L.matrix.d-K.d)/p,(L.matrix.e-K.e)/p,(L.matrix.f-K.f)/p]}break;case"csv":var M=I(i[y])[J](w),N=I(r[y])[J](w);if("clip-rect"==y)for(r[y]=N,t[y]=[],v=N.length;v--;)t[y][v]=(M[v]-r[y][v])/p;s[y]=M;break;default:for(M=[][E](i[y]),N=[][E](r[y]),t[y]=[],v=d.paper.customAttributes[y].length;v--;)t[y][v]=((M[v]||0)-(N[v]||0))/p}var O=i.easing,P=c.easing_formulas[O];if(!P)if(P=I(O).match(Z),P&&5==P.length){var Q=P;P=function(a){return q(a,+Q[1],+Q[2],+Q[3],+Q[4],p)}}else P=nb;if(n=i.start||a.start||+new Date,u={anim:a,percent:e,timestamp:n,start:n+(a.del||0),status:0,initstatus:f||0,stop:!1,ms:p,easing:P,from:r,diff:t,to:s,el:d,callback:i.callback,prev:m,next:l,repeat:h||a.times,origin:d.attr(),totalOrigin:g},ic.push(u),f&&!j&&!k&&(u.stop=!0,u.start=new Date-p*f,1==ic.length))return kc();k&&(u.start=new Date-u.ms*f),1==ic.length&&jc(kc)}b("raphael.anim.start."+d.id,d,a)}}function t(a){for(var b=0;be;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a};if(c._g=A,c.type=A.win.SVGAngle||A.doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")?"SVG":"VML","VML"==c.type){var sb,tb=A.doc.createElement("div");if(tb.innerHTML='',sb=tb.firstChild,sb.style.behavior="url(#default#VML)",!sb||"object"!=typeof sb.adj)return c.type=G;tb=null}c.svg=!(c.vml="VML"==c.type),c._Paper=C,c.fn=v=C.prototype=c.prototype,c._id=0,c._oid=0,c.is=function(a,b){return b=M.call(b),"finite"==b?!Y[z](+a):"array"==b?a instanceof Array:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||"array"==b&&Array.isArray&&Array.isArray(a)||W.call(a).slice(8,-1).toLowerCase()==b},c.angle=function(a,b,d,e,f,g){if(null==f){var h=a-d,i=b-e;return h||i?(180+180*N.atan2(-i,-h)/S+360)%360:0}return c.angle(a,b,f,g)-c.angle(d,e,f,g)},c.rad=function(a){return a%360*S/180},c.deg=function(a){return 180*a/S%360},c.snapTo=function(a,b,d){if(d=c.is(d,"finite")?d:10,c.is(a,V)){for(var e=a.length;e--;)if(Q(a[e]-b)<=d)return a[e]}else{a=+a;var f=b%a;if(d>f)return b-f;if(f>a-d)return b-f+a}return b},c.createUUID=function(a,b){return function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(a,b).toUpperCase()}}(/[xy]/g,function(a){var b=0|16*N.random(),c="x"==a?b:8|3&b;return c.toString(16)}),c.setWindow=function(a){b("raphael.setWindow",c,A.win,a),A.win=a,A.doc=A.win.document,c._engine.initWin&&c._engine.initWin(A.win)};var ub=function(a){if(c.vml){var b,d=/^\s+|\s+$/g;try{var e=new ActiveXObject("htmlfile");e.write(""),e.close(),b=e.body}catch(g){b=createPopup().document.body}var h=b.createTextRange();ub=f(function(a){try{b.style.color=I(a).replace(d,G);var c=h.queryCommandValue("ForeColor");return c=(255&c)<<16|65280&c|(16711680&c)>>>16,"#"+("000000"+c.toString(16)).slice(-6)}catch(e){return"none"}})}else{var i=A.doc.createElement("i");i.title="RaphaĂ«l Colour Picker",i.style.display="none",A.doc.body.appendChild(i),ub=f(function(a){return i.style.color=a,A.doc.defaultView.getComputedStyle(i,G).getPropertyValue("color")})}return ub(a)},vb=function(){return"hsb("+[this.h,this.s,this.b]+")"},wb=function(){return"hsl("+[this.h,this.s,this.l]+")"},xb=function(){return this.hex},yb=function(a,b,d){if(null==b&&c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&c.is(a,U)){var e=c.getRGB(a);a=e.r,b=e.g,d=e.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},zb=function(a,b,d,e){a*=255,b*=255,d*=255;var f={r:a,g:b,b:d,hex:c.rgb(a,b,d),toString:xb};return c.is(e,"finite")&&(f.opacity=e),f};c.color=function(a){var b;return c.is(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):c.is(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.hex=b.hex):(c.is(a,"string")&&(a=c.getRGB(a)),c.is(a,"object")&&"r"in a&&"g"in a&&"b"in a?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1)),a.toString=xb,a},c.hsb2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,a=a.h,d=a.o),a*=360;var e,f,g,h,i;return a=a%360/60,i=c*b,h=i*(1-Q(a%2-1)),e=f=g=c-i,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.hsl2rgb=function(a,b,c,d){this.is(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var e,f,g,h,i;return a=a%360/60,i=2*b*(.5>c?c:1-c),h=i*(1-Q(a%2-1)),e=f=g=c-i/2,a=~~a,e+=[i,h,0,0,h,i][a],f+=[h,i,i,h,0,0][a],g+=[0,0,h,i,i,h][a],zb(e,f,g,d)},c.rgb2hsb=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=O(a,b,c),g=f-P(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=60*((d+360)%6)/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:vb}},c.rgb2hsl=function(a,b,c){c=yb(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=O(a,b,c),h=P(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=60*((d+360)%6)/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:wb}},c._path2string=function(){return this.join(",").replace(gb,"$1")},c._preload=function(a,b){var c=A.doc.createElement("img");c.style.cssText="position:absolute;left:-9999em;top:-9999em",c.onload=function(){b.call(this),this.onload=null,A.doc.body.removeChild(this)},c.onerror=function(){A.doc.body.removeChild(this)},A.doc.body.appendChild(c),c.src=a},c.getRGB=f(function(a){if(!a||(a=I(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:g};!(fb[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=ub(a));var b,d,e,f,h,i,j=a.match(X);return j?(j[2]&&(e=ab(j[2].substring(5),16),d=ab(j[2].substring(3,5),16),b=ab(j[2].substring(1,3),16)),j[3]&&(e=ab((h=j[3].charAt(3))+h,16),d=ab((h=j[3].charAt(2))+h,16),b=ab((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100)),j[5]?(i=j[5][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsb2rgb(b,d,e,f)):j[6]?(i=j[6][J](eb),b=_(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=_(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),e=_(i[2]),"%"==i[2].slice(-1)&&(e*=2.55),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(f=_(i[3])),i[3]&&"%"==i[3].slice(-1)&&(f/=100),c.hsl2rgb(b,d,e,f)):(j={r:b,g:d,b:e,toString:g},j.hex="#"+(16777216|e|d<<8|b<<16).toString(16).slice(1),c.is(f,"finite")&&(j.opacity=f),j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:g}},c),c.hsb=f(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=f(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=f(function(a,b,c){return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)}),c.getColor=function(a){var b=this.getColor.start=this.getColor.start||{h:0,s:1,b:a||.75},c=this.hsb2rgb(b.h,b.s,b.b);return b.h+=.075,b.h>1&&(b.h=0,b.s-=.2,b.s<=0&&(this.getColor.start={h:0,s:1,b:b.b})),c.hex},c.getColor.reset=function(){delete this.start},c.parsePathString=function(a){if(!a)return null;var b=Ab(a);if(b.arr)return Cb(b.arr);var d={a:7,c:6,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,z:0},e=[];return c.is(a,V)&&c.is(a[0],V)&&(e=Cb(a)),e.length||I(a).replace(hb,function(a,b,c){var f=[],g=b.toLowerCase();if(c.replace(jb,function(a,b){b&&f.push(+b)}),"m"==g&&f.length>2&&(e.push([b][E](f.splice(0,2))),g="l",b="m"==b?"l":"L"),"r"==g)e.push([b][E](f));else for(;f.length>=d[g]&&(e.push([b][E](f.splice(0,d[g]))),d[g]););}),e.toString=c._path2string,b.arr=Cb(e),e},c.parseTransformString=f(function(a){if(!a)return null;var b=[];return c.is(a,V)&&c.is(a[0],V)&&(b=Cb(a)),b.length||I(a).replace(ib,function(a,c,d){var e=[];M.call(c),d.replace(jb,function(a,b){b&&e.push(+b)}),b.push([c][E](e))}),b.toString=c._path2string,b});var Ab=function(a){var b=Ab.ps=Ab.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[z](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]};c.findDotsAtSegment=function(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/S;return(q>s||t>r)&&(y+=180),{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}},c.bezierBBox=function(a,b,d,e,f,g,h,i){c.is(a,"array")||(a=[a,b,d,e,f,g,h,i]);var j=Jb.apply(null,a);return{x:j.min.x,y:j.min.y,x2:j.max.x,y2:j.max.y,width:j.max.x-j.min.x,height:j.max.y-j.min.y}},c.isPointInsideBBox=function(a,b,c){return b>=a.x&&b<=a.x2&&c>=a.y&&c<=a.y2},c.isBBoxIntersect=function(a,b){var d=c.isPointInsideBBox;return d(b,a.x,a.y)||d(b,a.x2,a.y)||d(b,a.x,a.y2)||d(b,a.x2,a.y2)||d(a,b.x,b.y)||d(a,b.x2,b.y)||d(a,b.x,b.y2)||d(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)},c.pathIntersection=function(a,b){return n(a,b)},c.pathIntersectionNumber=function(a,b){return n(a,b,1)},c.isPointInsidePath=function(a,b,d){var e=c.pathBBox(a);return c.isPointInsideBBox(e,b,d)&&1==n(a,[["M",b,d],["H",e.x2+10]],1)%2},c._removedFactory=function(a){return function(){b("raphael.log",null,"RaphaĂ«l: you are calling to method “"+a+"” of removed object",a)}};var Bb=c.pathBBox=function(a){var b=Ab(a);if(b.bbox)return d(b.bbox);if(!a)return{x:0,y:0,width:0,height:0,x2:0,y2:0};a=Kb(a);for(var c,e=0,f=0,g=[],h=[],i=0,j=a.length;j>i;i++)if(c=a[i],"M"==c[0])e=c[1],f=c[2],g.push(e),h.push(f);else{var k=Jb(e,f,c[1],c[2],c[3],c[4],c[5],c[6]);g=g[E](k.min.x,k.max.x),h=h[E](k.min.y,k.max.y),e=c[5],f=c[6]}var l=P[D](0,g),m=P[D](0,h),n=O[D](0,g),o=O[D](0,h),p=n-l,q=o-m,r={x:l,y:m,x2:n,y2:o,width:p,height:q,cx:l+p/2,cy:m+q/2};return b.bbox=d(r),r},Cb=function(a){var b=d(a);return b.toString=c._path2string,b},Db=c._pathToRelative=function(a){var b=Ab(a);if(b.rel)return Cb(b.rel);c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a));var d=[],e=0,f=0,g=0,h=0,i=0;"M"==a[0][0]&&(e=a[0][1],f=a[0][2],g=e,h=f,i++,d.push(["M",e,f]));for(var j=i,k=a.length;k>j;j++){var l=d[j]=[],m=a[j];if(m[0]!=M.call(m[0]))switch(l[0]=M.call(m[0]),l[0]){case"a":l[1]=m[1],l[2]=m[2],l[3]=m[3],l[4]=m[4],l[5]=m[5],l[6]=+(m[6]-e).toFixed(3),l[7]=+(m[7]-f).toFixed(3);break;case"v":l[1]=+(m[1]-f).toFixed(3);break;case"m":g=m[1],h=m[2];default:for(var n=1,o=m.length;o>n;n++)l[n]=+(m[n]-(n%2?e:f)).toFixed(3)}else{l=d[j]=[],"m"==m[0]&&(g=m[1]+e,h=m[2]+f);for(var p=0,q=m.length;q>p;p++)d[j][p]=m[p]}var r=d[j].length;switch(d[j][0]){case"z":e=g,f=h;break;case"h":e+=+d[j][r-1];break;case"v":f+=+d[j][r-1];break;default:e+=+d[j][r-2],f+=+d[j][r-1]}}return d.toString=c._path2string,b.rel=Cb(d),d},Eb=c._pathToAbsolute=function(a){var b=Ab(a);if(b.abs)return Cb(b.abs);if(c.is(a,V)&&c.is(a&&a[0],V)||(a=c.parsePathString(a)),!a||!a.length)return[["M",0,0]];var d=[],e=0,f=0,g=0,i=0,j=0;"M"==a[0][0]&&(e=+a[0][1],f=+a[0][2],g=e,i=f,j++,d[0]=["M",e,f]);for(var k,l,m=3==a.length&&"M"==a[0][0]&&"R"==a[1][0].toUpperCase()&&"Z"==a[2][0].toUpperCase(),n=j,o=a.length;o>n;n++){if(d.push(k=[]),l=a[n],l[0]!=bb.call(l[0]))switch(k[0]=bb.call(l[0]),k[0]){case"A":k[1]=l[1],k[2]=l[2],k[3]=l[3],k[4]=l[4],k[5]=l[5],k[6]=+(l[6]+e),k[7]=+(l[7]+f);break;case"V":k[1]=+l[1]+f;break;case"H":k[1]=+l[1]+e;break;case"R":for(var p=[e,f][E](l.slice(1)),q=2,r=p.length;r>q;q++)p[q]=+p[q]+e,p[++q]=+p[q]+f;d.pop(),d=d[E](h(p,m));break;case"M":g=+l[1]+e,i=+l[2]+f;default:for(q=1,r=l.length;r>q;q++)k[q]=+l[q]+(q%2?e:f)}else if("R"==l[0])p=[e,f][E](l.slice(1)),d.pop(),d=d[E](h(p,m)),k=["R"][E](l.slice(-2));else for(var s=0,t=l.length;t>s;s++)k[s]=l[s];switch(k[0]){case"Z":e=g,f=i;break;case"H":e=k[1];break;case"V":f=k[1];break;case"M":g=k[k.length-2],i=k[k.length-1];default:e=k[k.length-2],f=k[k.length-1]}}return d.toString=c._path2string,b.abs=Cb(d),d},Fb=function(a,b,c,d){return[a,b,c,d,c,d]},Gb=function(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]},Hb=function(a,b,c,d,e,g,h,i,j,k){var l,m=120*S/180,n=S/180*(+e||0),o=[],p=f(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(a,b,-n),a=l.x,b=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(S/180*e),N.sin(S/180*e),(a-i)/2),r=(b-j)/2,s=q*q/(c*c)+r*r/(d*d);s>1&&(s=N.sqrt(s),c=s*c,d=s*d);var t=c*c,u=d*d,v=(g==h?-1:1)*N.sqrt(Q((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*c*r/d+(a+i)/2,x=v*-d*q/c+(b+j)/2,y=N.asin(((b-x)/d).toFixed(9)),z=N.asin(((j-x)/d).toFixed(9));y=w>a?S-y:y,z=w>i?S-z:z,0>y&&(y=2*S+y),0>z&&(z=2*S+z),h&&y>z&&(y-=2*S),!h&&z>y&&(z-=2*S)}var A=z-y;if(Q(A)>m){var B=z,C=i,D=j;z=y+m*(h&&z>y?1:-1),i=w+c*N.cos(z),j=x+d*N.sin(z),o=Hb(i,j,c,d,e,0,h,C,D,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),K=N.tan(A/4),L=4/3*c*K,M=4/3*d*K,O=[a,b],P=[a+L*G,b-M*F],R=[i+L*I,j-M*H],T=[i,j];if(P[0]=2*O[0]-P[0],P[1]=2*O[1]-P[1],k)return[P,R,T][E](o);o=[P,R,T][E](o).join()[J](",");for(var U=[],V=0,W=o.length;W>V;V++)U[V]=V%2?p(o[V-1],o[V],n).y:p(o[V],o[V+1],n).x;return U},Ib=function(a,b,c,d,e,f,g,h,i){var j=1-i;return{x:R(j,3)*a+3*R(j,2)*i*c+3*j*i*i*e+R(i,3)*g,y:R(j,3)*b+3*R(j,2)*i*d+3*j*i*i*f+R(i,3)*h}},Jb=f(function(a,b,c,d,e,f,g,h){var i,j=e-2*c+a-(g-2*e+c),k=2*(c-a)-2*(e-c),l=a-c,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,o=[b,h],p=[a,g];return Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),j=f-2*d+b-(h-2*f+d),k=2*(d-b)-2*(f-d),l=b-d,m=(-k+N.sqrt(k*k-4*j*l))/2/j,n=(-k-N.sqrt(k*k-4*j*l))/2/j,Q(m)>"1e12"&&(m=.5),Q(n)>"1e12"&&(n=.5),m>0&&1>m&&(i=Ib(a,b,c,d,e,f,g,h,m),p.push(i.x),o.push(i.y)),n>0&&1>n&&(i=Ib(a,b,c,d,e,f,g,h,n),p.push(i.x),o.push(i.y)),{min:{x:P[D](0,p),y:P[D](0,o)},max:{x:O[D](0,p),y:O[D](0,o)}}}),Kb=c._path2curve=f(function(a,b){var c=!b&&Ab(a);if(!b&&c.curve)return Cb(c.curve);for(var d=Eb(a),e=b&&Eb(b),f={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},g={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},h=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"][E](Hb[D](0,[b.x,b.y][E](a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e][E](a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"][E](Gb(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"][E](Gb(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"][E](Fb(b.x,b.y,a[1],a[2]));break;case"H":a=["C"][E](Fb(b.x,b.y,a[1],b.y));break;case"V":a=["C"][E](Fb(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"][E](Fb(b.x,b.y,b.X,b.Y))}return a}),i=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)a.splice(b++,0,["C"][E](c.splice(0,6)));a.splice(b,1),l=O(d.length,e&&e.length||0)}},j=function(a,b,c,f,g){a&&b&&"M"==a[g][0]&&"M"!=b[g][0]&&(b.splice(g,0,["M",f.x,f.y]),c.bx=0,c.by=0,c.x=a[g][1],c.y=a[g][2],l=O(d.length,e&&e.length||0))},k=0,l=O(d.length,e&&e.length||0);l>k;k++){d[k]=h(d[k],f),i(d,k),e&&(e[k]=h(e[k],g)),e&&i(e,k),j(d,e,f,g,k),j(e,d,g,f,k);var m=d[k],n=e&&e[k],o=m.length,p=e&&n.length;f.x=m[o-2],f.y=m[o-1],f.bx=_(m[o-4])||f.x,f.by=_(m[o-3])||f.y,g.bx=e&&(_(n[p-4])||g.x),g.by=e&&(_(n[p-3])||g.y),g.x=e&&n[p-2],g.y=e&&n[p-1]}return e||(c.curve=Cb(d)),e?[d,e]:d},null,Cb),Lb=(c._parseDots=f(function(a){for(var b=[],d=0,e=a.length;e>d;d++){var f={},g=a[d].match(/^([^:]*):?([\d\.]*)/);if(f.color=c.getRGB(g[1]),f.color.error)return null;f.color=f.color.hex,g[2]&&(f.offset=g[2]+"%"),b.push(f)}for(d=1,e=b.length-1;e>d;d++)if(!b[d].offset){for(var h=_(b[d-1].offset||0),i=0,j=d+1;e>j;j++)if(b[j].offset){i=b[j].offset;break}i||(i=100,j=e),i=_(i);for(var k=(i-h)/(j-d+1);j>d;d++)h+=k,b[d].offset=h+"%"}return b}),c._tear=function(a,b){a==b.top&&(b.top=a.prev),a==b.bottom&&(b.bottom=a.next),a.next&&(a.next.prev=a.prev),a.prev&&(a.prev.next=a.next)}),Mb=(c._tofront=function(a,b){b.top!==a&&(Lb(a,b),a.next=null,a.prev=b.top,b.top.next=a,b.top=a)},c._toback=function(a,b){b.bottom!==a&&(Lb(a,b),a.next=b.bottom,a.prev=null,b.bottom.prev=a,b.bottom=a)},c._insertafter=function(a,b,c){Lb(a,c),b==c.top&&(c.top=a),b.next&&(b.next.prev=a),a.next=b.next,a.prev=b,b.next=a},c._insertbefore=function(a,b,c){Lb(a,c),b==c.bottom&&(c.bottom=a),b.prev&&(b.prev.next=a),a.prev=b.prev,b.prev=a,a.next=b},c.toMatrix=function(a,b){var c=Bb(a),d={_:{transform:G},getBBox:function(){return c}};return Nb(d,b),d.matrix}),Nb=(c.transformPath=function(a,b){return rb(a,Mb(a,b))},c._extractTransform=function(a,b){if(null==b)return a._.transform;b=I(b).replace(/\.{3}|\u2026/g,a._.transform||G);var d=c.parseTransformString(b),e=0,f=0,g=0,h=1,i=1,j=a._,k=new o;if(j.transform=d||[],d)for(var l=0,m=d.length;m>l;l++){var n,p,q,r,s,t=d[l],u=t.length,v=I(t[0]).toLowerCase(),w=t[0]!=v,x=w?k.invert():0;"t"==v&&3==u?w?(n=x.x(0,0),p=x.y(0,0),q=x.x(t[1],t[2]),r=x.y(t[1],t[2]),k.translate(q-n,r-p)):k.translate(t[1],t[2]):"r"==v?2==u?(s=s||a.getBBox(1),k.rotate(t[1],s.x+s.width/2,s.y+s.height/2),e+=t[1]):4==u&&(w?(q=x.x(t[2],t[3]),r=x.y(t[2],t[3]),k.rotate(t[1],q,r)):k.rotate(t[1],t[2],t[3]),e+=t[1]):"s"==v?2==u||3==u?(s=s||a.getBBox(1),k.scale(t[1],t[u-1],s.x+s.width/2,s.y+s.height/2),h*=t[1],i*=t[u-1]):5==u&&(w?(q=x.x(t[3],t[4]),r=x.y(t[3],t[4]),k.scale(t[1],t[2],q,r)):k.scale(t[1],t[2],t[3],t[4]),h*=t[1],i*=t[2]):"m"==v&&7==u&&k.add(t[1],t[2],t[3],t[4],t[5],t[6]),j.dirtyT=1,a.matrix=k}a.matrix=k,j.sx=h,j.sy=i,j.deg=e,j.dx=f=k.e,j.dy=g=k.f,1==h&&1==i&&!e&&j.bbox?(j.bbox.x+=+f,j.bbox.y+=+g):j.dirtyT=1}),Ob=function(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}},Pb=c._equaliseTransform=function(a,b){b=I(b).replace(/\.{3}|\u2026/g,a),a=c.parseTransformString(a)||[],b=c.parseTransformString(b)||[];for(var d,e,f,g,h=O(a.length,b.length),i=[],j=[],k=0;h>k;k++){if(f=a[k]||Ob(b[k]),g=b[k]||Ob(f),f[0]!=g[0]||"r"==f[0].toLowerCase()&&(f[2]!=g[2]||f[3]!=g[3])||"s"==f[0].toLowerCase()&&(f[3]!=g[3]||f[4]!=g[4]))return;for(i[k]=[],j[k]=[],d=0,e=O(f.length,g.length);e>d;d++)d in f&&(i[k][d]=f[d]),d in g&&(j[k][d]=g[d]) -}return{from:i,to:j}};c._getContainer=function(a,b,d,e){var f;return f=null!=e||c.is(a,"object")?a:A.doc.getElementById(a),null!=f?f.tagName?null==b?{container:f,width:f.style.pixelWidth||f.offsetWidth,height:f.style.pixelHeight||f.offsetHeight}:{container:f,width:b,height:d}:{container:1,x:a,y:b,width:d,height:e}:void 0},c.pathToRelative=Db,c._engine={},c.path2curve=Kb,c.matrix=function(a,b,c,d,e,f){return new o(a,b,c,d,e,f)},function(a){function b(a){return a[0]*a[0]+a[1]*a[1]}function d(a){var c=N.sqrt(b(a));a[0]&&(a[0]/=c),a[1]&&(a[1]/=c)}a.add=function(a,b,c,d,e,f){var g,h,i,j,k=[[],[],[]],l=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],m=[[a,c,e],[b,d,f],[0,0,1]];for(a&&a instanceof o&&(m=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),g=0;3>g;g++)for(h=0;3>h;h++){for(j=0,i=0;3>i;i++)j+=l[g][i]*m[i][h];k[g][h]=j}this.a=k[0][0],this.b=k[1][0],this.c=k[0][1],this.d=k[1][1],this.e=k[0][2],this.f=k[1][2]},a.invert=function(){var a=this,b=a.a*a.d-a.b*a.c;return new o(a.d/b,-a.b/b,-a.c/b,a.a/b,(a.c*a.f-a.d*a.e)/b,(a.b*a.e-a.a*a.f)/b)},a.clone=function(){return new o(this.a,this.b,this.c,this.d,this.e,this.f)},a.translate=function(a,b){this.add(1,0,0,1,a,b)},a.scale=function(a,b,c,d){null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d)},a.rotate=function(a,b,d){a=c.rad(a),b=b||0,d=d||0;var e=+N.cos(a).toFixed(9),f=+N.sin(a).toFixed(9);this.add(e,f,-f,e,b,d),this.add(1,0,0,1,-b,-d)},a.x=function(a,b){return a*this.a+b*this.c+this.e},a.y=function(a,b){return a*this.b+b*this.d+this.f},a.get=function(a){return+this[I.fromCharCode(97+a)].toFixed(4)},a.toString=function(){return c.svg?"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")":[this.get(0),this.get(2),this.get(1),this.get(3),0,0].join()},a.toFilter=function(){return"progid:DXImageTransform.Microsoft.Matrix(M11="+this.get(0)+", M12="+this.get(2)+", M21="+this.get(1)+", M22="+this.get(3)+", Dx="+this.get(4)+", Dy="+this.get(5)+", sizingmethod='auto expand')"},a.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},a.split=function(){var a={};a.dx=this.e,a.dy=this.f;var e=[[this.a,this.c],[this.b,this.d]];a.scalex=N.sqrt(b(e[0])),d(e[0]),a.shear=e[0][0]*e[1][0]+e[0][1]*e[1][1],e[1]=[e[1][0]-e[0][0]*a.shear,e[1][1]-e[0][1]*a.shear],a.scaley=N.sqrt(b(e[1])),d(e[1]),a.shear/=a.scaley;var f=-e[0][1],g=e[1][1];return 0>g?(a.rotate=c.deg(N.acos(g)),0>f&&(a.rotate=360-a.rotate)):a.rotate=c.deg(N.asin(f)),a.isSimple=!(+a.shear.toFixed(9)||a.scalex.toFixed(9)!=a.scaley.toFixed(9)&&a.rotate),a.isSuperSimple=!+a.shear.toFixed(9)&&a.scalex.toFixed(9)==a.scaley.toFixed(9)&&!a.rotate,a.noRotation=!+a.shear.toFixed(9)&&!a.rotate,a},a.toTransformString=function(a){var b=a||this[J]();return b.isSimple?(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[b.dx,b.dy]:G)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:G)+(b.rotate?"r"+[b.rotate,0,0]:G)):"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]}}(o.prototype);var Qb=navigator.userAgent.match(/Version\/(.*?)\s/)||navigator.userAgent.match(/Chrome\/(\d+)/);v.safari="Apple Computer, Inc."==navigator.vendor&&(Qb&&Qb[1]<4||"iP"==navigator.platform.slice(0,2))||"Google Inc."==navigator.vendor&&Qb&&Qb[1]<8?function(){var a=this.rect(-99,-99,this.width+99,this.height+99).attr({stroke:"none"});setTimeout(function(){a.remove()})}:mb;for(var Rb=function(){this.returnValue=!1},Sb=function(){return this.originalEvent.preventDefault()},Tb=function(){this.cancelBubble=!0},Ub=function(){return this.originalEvent.stopPropagation()},Vb=function(a){var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,c=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;return{x:a.clientX+c,y:a.clientY+b}},Wb=function(){return A.doc.addEventListener?function(a,b,c,d){var e=function(a){var b=Vb(a);return c.call(d,a,b.x,b.y)};if(a.addEventListener(b,e,!1),F&&L[b]){var f=function(b){for(var e=Vb(b),f=b,g=0,h=b.targetTouches&&b.targetTouches.length;h>g;g++)if(b.targetTouches[g].target==a){b=b.targetTouches[g],b.originalEvent=f,b.preventDefault=Sb,b.stopPropagation=Ub;break}return c.call(d,b,e.x,e.y)};a.addEventListener(L[b],f,!1)}return function(){return a.removeEventListener(b,e,!1),F&&L[b]&&a.removeEventListener(L[b],e,!1),!0}}:A.doc.attachEvent?function(a,b,c,d){var e=function(a){a=a||A.win.event;var b=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,e=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,f=a.clientX+e,g=a.clientY+b;return a.preventDefault=a.preventDefault||Rb,a.stopPropagation=a.stopPropagation||Tb,c.call(d,a,f,g)};a.attachEvent("on"+b,e);var f=function(){return a.detachEvent("on"+b,e),!0};return f}:void 0}(),Xb=[],Yb=function(a){for(var c,d=a.clientX,e=a.clientY,f=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,g=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft,h=Xb.length;h--;){if(c=Xb[h],F&&a.touches){for(var i,j=a.touches.length;j--;)if(i=a.touches[j],i.identifier==c.el._drag.id){d=i.clientX,e=i.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();var k,l=c.el.node,m=l.nextSibling,n=l.parentNode,o=l.style.display;A.win.opera&&n.removeChild(l),l.style.display="none",k=c.el.paper.getElementByPoint(d,e),l.style.display=o,A.win.opera&&(m?n.insertBefore(l,m):n.appendChild(l)),k&&b("raphael.drag.over."+c.el.id,c.el,k),d+=g,e+=f,b("raphael.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},Zb=function(a){c.unmousemove(Yb).unmouseup(Zb);for(var d,e=Xb.length;e--;)d=Xb[e],d.el._drag={},b("raphael.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,a);Xb=[]},$b=c.el={},_b=K.length;_b--;)!function(a){c[a]=$b[a]=function(b,d){return c.is(b,"function")&&(this.events=this.events||[],this.events.push({name:a,f:b,unbind:Wb(this.shape||this.node||A.doc,a,b,d||this)})),this},c["un"+a]=$b["un"+a]=function(b){for(var d=this.events||[],e=d.length;e--;)d[e].name!=a||!c.is(b,"undefined")&&d[e].f!=b||(d[e].unbind(),d.splice(e,1),!d.length&&delete this.events);return this}}(K[_b]);$b.data=function(a,d){var e=kb[this.id]=kb[this.id]||{};if(0==arguments.length)return e;if(1==arguments.length){if(c.is(a,"object")){for(var f in a)a[z](f)&&this.data(f,a[f]);return this}return b("raphael.data.get."+this.id,this,e[a],a),e[a]}return e[a]=d,b("raphael.data.set."+this.id,this,d,a),this},$b.removeData=function(a){return null==a?kb[this.id]={}:kb[this.id]&&delete kb[this.id][a],this},$b.getData=function(){return d(kb[this.id]||{})},$b.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},$b.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var ac=[];$b.drag=function(a,d,e,f,g,h){function i(i){(i.originalEvent||i).preventDefault();var j=i.clientX,k=i.clientY,l=A.doc.documentElement.scrollTop||A.doc.body.scrollTop,m=A.doc.documentElement.scrollLeft||A.doc.body.scrollLeft;if(this._drag.id=i.identifier,F&&i.touches)for(var n,o=i.touches.length;o--;)if(n=i.touches[o],this._drag.id=n.identifier,n.identifier==this._drag.id){j=n.clientX,k=n.clientY;break}this._drag.x=j+m,this._drag.y=k+l,!Xb.length&&c.mousemove(Yb).mouseup(Zb),Xb.push({el:this,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("raphael.drag.start."+this.id,d),a&&b.on("raphael.drag.move."+this.id,a),e&&b.on("raphael.drag.end."+this.id,e),b("raphael.drag.start."+this.id,g||f||this,i.clientX+m,i.clientY+l,i)}return this._drag={},ac.push({el:this,start:i}),this.mousedown(i),this},$b.onDragOver=function(a){a?b.on("raphael.drag.over."+this.id,a):b.unbind("raphael.drag.over."+this.id)},$b.undrag=function(){for(var a=ac.length;a--;)ac[a].el==this&&(this.unmousedown(ac[a].start),ac.splice(a,1),b.unbind("raphael.drag.*."+this.id));!ac.length&&c.unmousemove(Yb).unmouseup(Zb),Xb=[]},v.circle=function(a,b,d){var e=c._engine.circle(this,a||0,b||0,d||0);return this.__set__&&this.__set__.push(e),e},v.rect=function(a,b,d,e,f){var g=c._engine.rect(this,a||0,b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.ellipse=function(a,b,d,e){var f=c._engine.ellipse(this,a||0,b||0,d||0,e||0);return this.__set__&&this.__set__.push(f),f},v.path=function(a){a&&!c.is(a,U)&&!c.is(a[0],V)&&(a+=G);var b=c._engine.path(c.format[D](c,arguments),this);return this.__set__&&this.__set__.push(b),b},v.image=function(a,b,d,e,f){var g=c._engine.image(this,a||"about:blank",b||0,d||0,e||0,f||0);return this.__set__&&this.__set__.push(g),g},v.text=function(a,b,d){var e=c._engine.text(this,a||0,b||0,I(d));return this.__set__&&this.__set__.push(e),e},v.set=function(a){!c.is(a,"array")&&(a=Array.prototype.splice.call(arguments,0,arguments.length));var b=new mc(a);return this.__set__&&this.__set__.push(b),b.paper=this,b.type="set",b},v.setStart=function(a){this.__set__=a||this.set()},v.setFinish=function(){var a=this.__set__;return delete this.__set__,a},v.setSize=function(a,b){return c._engine.setSize.call(this,a,b)},v.setViewBox=function(a,b,d,e,f){return c._engine.setViewBox.call(this,a,b,d,e,f)},v.top=v.bottom=null,v.raphael=c;var bc=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,g=e.clientLeft||d.clientLeft||0,h=b.top+(A.win.pageYOffset||e.scrollTop||d.scrollTop)-f,i=b.left+(A.win.pageXOffset||e.scrollLeft||d.scrollLeft)-g;return{y:h,x:i}};v.getElementByPoint=function(a,b){var c=this,d=c.canvas,e=A.doc.elementFromPoint(a,b);if(A.win.opera&&"svg"==e.tagName){var f=bc(d),g=d.createSVGRect();g.x=a-f.x,g.y=b-f.y,g.width=g.height=1;var h=d.getIntersectionList(g,null);h.length&&(e=h[h.length-1])}if(!e)return null;for(;e.parentNode&&e!=d.parentNode&&!e.raphael;)e=e.parentNode;return e==c.canvas.parentNode&&(e=d),e=e&&e.raphael?c.getById(e.raphaelid):null},v.getElementsByBBox=function(a){var b=this.set();return this.forEach(function(d){c.isBBoxIntersect(d.getBBox(),a)&&b.push(d)}),b},v.getById=function(a){for(var b=this.bottom;b;){if(b.id==a)return b;b=b.next}return null},v.forEach=function(a,b){for(var c=this.bottom;c;){if(a.call(b,c)===!1)return this;c=c.next}return this},v.getElementsByPoint=function(a,b){var c=this.set();return this.forEach(function(d){d.isPointInside(a,b)&&c.push(d)}),c},$b.isPointInside=function(a,b){var d=this.realPath=qb[this.type](this);return this.attr("transform")&&this.attr("transform").length&&(d=c.transformPath(d,this.attr("transform"))),c.isPointInsidePath(d,a,b)},$b.getBBox=function(a){if(this.removed)return{};var b=this._;return a?((b.dirty||!b.bboxwt)&&(this.realPath=qb[this.type](this),b.bboxwt=Bb(this.realPath),b.bboxwt.toString=p,b.dirty=0),b.bboxwt):((b.dirty||b.dirtyT||!b.bbox)&&((b.dirty||!this.realPath)&&(b.bboxwt=0,this.realPath=qb[this.type](this)),b.bbox=Bb(rb(this.realPath,this.matrix)),b.bbox.toString=p,b.dirty=b.dirtyT=0),b.bbox)},$b.clone=function(){if(this.removed)return null;var a=this.paper[this.type]().attr(this.attr());return this.__set__&&this.__set__.push(a),a},$b.glow=function(a){if("text"==this.type)return null;a=a||{};var b={width:(a.width||10)+(+this.attr("stroke-width")||1),fill:a.fill||!1,opacity:a.opacity||.5,offsetx:a.offsetx||0,offsety:a.offsety||0,color:a.color||"#000"},c=b.width/2,d=this.paper,e=d.set(),f=this.realPath||qb[this.type](this);f=this.matrix?rb(f,this.matrix):f;for(var g=1;c+1>g;g++)e.push(d.path(f).attr({stroke:b.color,fill:b.fill?b.color:"none","stroke-linejoin":"round","stroke-linecap":"round","stroke-width":+(b.width/c*g).toFixed(3),opacity:+(b.opacity/c).toFixed(3)}));return e.insertBefore(this).translate(b.offsetx,b.offsety)};var cc=function(a,b,d,e,f,g,h,i,l){return null==l?j(a,b,d,e,f,g,h,i):c.findDotsAtSegment(a,b,d,e,f,g,h,i,k(a,b,d,e,f,g,h,i,l))},dc=function(a,b){return function(d,e,f){d=Kb(d);for(var g,h,i,j,k,l="",m={},n=0,o=0,p=d.length;p>o;o++){if(i=d[o],"M"==i[0])g=+i[1],h=+i[2];else{if(j=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6]),n+j>e){if(b&&!m.start){if(k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),l+=["C"+k.start.x,k.start.y,k.m.x,k.m.y,k.x,k.y],f)return l;m.start=l,l=["M"+k.x,k.y+"C"+k.n.x,k.n.y,k.end.x,k.end.y,i[5],i[6]].join(),n+=j,g=+i[5],h=+i[6];continue}if(!a&&!b)return k=cc(g,h,i[1],i[2],i[3],i[4],i[5],i[6],e-n),{x:k.x,y:k.y,alpha:k.alpha}}n+=j,g=+i[5],h=+i[6]}l+=i.shift()+i}return m.end=l,k=a?n:b?m:c.findDotsAtSegment(g,h,i[0],i[1],i[2],i[3],i[4],i[5],1),k.alpha&&(k={x:k.x,y:k.y,alpha:k.alpha}),k}},ec=dc(1),fc=dc(),gc=dc(0,1);c.getTotalLength=ec,c.getPointAtLength=fc,c.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return gc(a,b).end;var d=gc(a,c,1);return b?gc(d,b).end:d},$b.getTotalLength=function(){var a=this.getPath();if(a)return this.node.getTotalLength?this.node.getTotalLength():ec(a)},$b.getPointAtLength=function(a){var b=this.getPath();if(b)return fc(b,a)},$b.getPath=function(){var a,b=c._getPath[this.type];if("text"!=this.type&&"set"!=this.type)return b&&(a=b(this)),a},$b.getSubpath=function(a,b){var d=this.getPath();if(d)return c.getSubpath(d,a,b)};var hc=c.easing_formulas={linear:function(a){return a},"<":function(a){return R(a,1.7)},">":function(a){return R(a,.48)},"<>":function(a){var b=.48-a/1.04,c=N.sqrt(.1734+b*b),d=c-b,e=R(Q(d),1/3)*(0>d?-1:1),f=-c-b,g=R(Q(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},backIn:function(a){var b=1.70158;return a*a*((b+1)*a-b)},backOut:function(a){a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},elastic:function(a){return a==!!a?a:R(2,-10*a)*N.sin((a-.075)*2*S/.3)+1},bounce:function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b}};hc.easeIn=hc["ease-in"]=hc["<"],hc.easeOut=hc["ease-out"]=hc[">"],hc.easeInOut=hc["ease-in-out"]=hc["<>"],hc["back-in"]=hc.backIn,hc["back-out"]=hc.backOut;var ic=[],jc=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},kc=function(){for(var a=+new Date,d=0;dh))if(i>h){var q=j(h/i);for(var r in k)if(k[z](r)){switch(db[r]){case T:f=+k[r]+q*i*l[r];break;case"colour":f="rgb("+[lc($(k[r].r+q*i*l[r].r)),lc($(k[r].g+q*i*l[r].g)),lc($(k[r].b+q*i*l[r].b))].join(",")+")";break;case"path":f=[];for(var t=0,u=k[r].length;u>t;t++){f[t]=[k[r][t][0]];for(var v=1,w=k[r][t].length;w>v;v++)f[t][v]=+k[r][t][v]+q*i*l[r][t][v];f[t]=f[t].join(H)}f=f.join(H);break;case"transform":if(l[r].real)for(f=[],t=0,u=k[r].length;u>t;t++)for(f[t]=[k[r][t][0]],v=1,w=k[r][t].length;w>v;v++)f[t][v]=k[r][t][v]+q*i*l[r][t][v];else{var x=function(a){return+k[r][a]+q*i*l[r][a]};f=[["m",x(0),x(1),x(2),x(3),x(4),x(5)]]}break;case"csv":if("clip-rect"==r)for(f=[],t=4;t--;)f[t]=+k[r][t]+q*i*l[r][t];break;default:var y=[][E](k[r]);for(f=[],t=n.paper.customAttributes[r].length;t--;)f[t]=+y[t]+q*i*l[r][t]}o[r]=f}n.attr(o),function(a,c,d){setTimeout(function(){b("raphael.anim.frame."+a,c,d)})}(n.id,n,e.anim)}else{if(function(a,d,e){setTimeout(function(){b("raphael.anim.frame."+d.id,d,e),b("raphael.anim.finish."+d.id,d,e),c.is(a,"function")&&a.call(d)})}(e.callback,n,e.anim),n.attr(m),ic.splice(d--,1),e.repeat>1&&!e.next){for(g in m)m[z](g)&&(p[g]=e.totalOrigin[g]);e.el.attr(p),s(e.anim,e.el,e.anim.percents[0],null,e.totalOrigin,e.repeat-1)}e.next&&!e.stop&&s(e.anim,e.el,e.next,null,e.totalOrigin,e.repeat)}}}c.svg&&n&&n.paper&&n.paper.safari(),ic.length&&jc(kc)},lc=function(a){return a>255?255:0>a?0:a};$b.animateWith=function(a,b,d,e,f,g){var h=this;if(h.removed)return g&&g.call(h),h;var i=d instanceof r?d:c.animation(d,e,f,g);s(i,h,i.percents[0],null,h.attr());for(var j=0,k=ic.length;k>j;j++)if(ic[j].anim==b&&ic[j].el==a){ic[k-1].start=ic[j].start;break}return h},$b.onAnimation=function(a){return a?b.on("raphael.anim.frame."+this.id,a):b.unbind("raphael.anim.frame."+this.id),this},r.prototype.delay=function(a){var b=new r(this.anim,this.ms);return b.times=this.times,b.del=+a||0,b},r.prototype.repeat=function(a){var b=new r(this.anim,this.ms);return b.del=this.del,b.times=N.floor(O(a,0))||1,b},c.animation=function(a,b,d,e){if(a instanceof r)return a;(c.is(d,"function")||!d)&&(e=e||d||null,d=null),a=Object(a),b=+b||0;var f,g,h={};for(g in a)a[z](g)&&_(g)!=g&&_(g)+"%"!=g&&(f=!0,h[g]=a[g]);return f?(d&&(h.easing=d),e&&(h.callback=e),new r({100:h},b)):new r(a,b)},$b.animate=function(a,b,d,e){var f=this;if(f.removed)return e&&e.call(f),f;var g=a instanceof r?a:c.animation(a,b,d,e);return s(g,f,g.percents[0],null,f.attr()),f},$b.setTime=function(a,b){return a&&null!=b&&this.status(a,P(b,a.ms)/a.ms),this},$b.status=function(a,b){var c,d,e=[],f=0;if(null!=b)return s(a,this,-1,P(b,1)),this;for(c=ic.length;c>f;f++)if(d=ic[f],d.el.id==this.id&&(!a||d.anim==a)){if(a)return d.status;e.push({anim:d.anim,status:d.status})}return a?0:e},$b.pause=function(a){for(var c=0;cb;b++)!a[b]||a[b].constructor!=$b.constructor&&a[b].constructor!=mc||(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},nc=mc.prototype;nc.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],!a||a.constructor!=$b.constructor&&a.constructor!=mc||(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},nc.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},nc.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this};for(var oc in $b)$b[z](oc)&&(nc[oc]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a][D](c,b)})}}(oc));return nc.attr=function(a,b){if(a&&c.is(a,V)&&c.is(a[0],"object"))for(var d=0,e=a.length;e>d;d++)this.items[d].attr(a[d]);else for(var f=0,g=this.items.length;g>f;f++)this.items[f].attr(a,b);return this},nc.clear=function(){for(;this.length;)this.pop()},nc.splice=function(a,b){a=0>a?O(this.length+a,0):a,b=O(0,P(this.length-a,b));var c,d=[],e=[],f=[];for(c=2;cc;c++)e.push(this[a+c]);for(;cc?f[c]:d[c-g];for(c=this.items.length=this.length-=b-g;this[c];)delete this[c++];return new mc(e)},nc.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0},nc.animate=function(a,b,d,e){(c.is(d,"function")||!d)&&(e=d||null);var f,g,h=this.items.length,i=h,j=this;if(!h)return this;e&&(g=function(){!--h&&e.call(j)}),d=c.is(d,U)?d:g;var k=c.animation(a,b,d,g);for(f=this.items[--i].animate(k);i--;)this.items[i]&&!this.items[i].removed&&this.items[i].animateWith(f,k,k),this.items[i]&&!this.items[i].removed||h--;return this},nc.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},nc.getBBox=function(){for(var a=[],b=[],c=[],d=[],e=this.items.length;e--;)if(!this.items[e].removed){var f=this.items[e].getBBox();a.push(f.x),b.push(f.y),c.push(f.x+f.width),d.push(f.y+f.height)}return a=P[D](0,a),b=P[D](0,b),c=O[D](0,c),d=O[D](0,d),{x:a,y:b,x2:c,y2:d,width:c-a,height:d-b}},nc.clone=function(a){a=this.paper.set();for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},nc.toString=function(){return"RaphaĂ«lâ€s set"},nc.glow=function(a){var b=this.paper.set();return this.forEach(function(c){var d=c.glow(a);null!=d&&d.forEach(function(a){b.push(a)})}),b},nc.isPointInside=function(a,b){var c=!1;return this.forEach(function(d){return d.isPointInside(a,b)?(console.log("runned"),c=!0,!1):void 0}),c},c.registerFont=function(a){if(!a.face)return a;this.fonts=this.fonts||{};var b={w:a.w,face:{},glyphs:{}},c=a.face["font-family"];for(var d in a.face)a.face[z](d)&&(b.face[d]=a.face[d]);if(this.fonts[c]?this.fonts[c].push(b):this.fonts[c]=[b],!a.svg){b.face["units-per-em"]=ab(a.face["units-per-em"],10);for(var e in a.glyphs)if(a.glyphs[z](e)){var f=a.glyphs[e];if(b.glyphs[e]={w:f.w,k:{},d:f.d&&"M"+f.d.replace(/[mlcxtrv]/g,function(a){return{l:"L",c:"C",x:"z",t:"m",r:"l",v:"c"}[a]||"M"})+"z"},f.k)for(var g in f.k)f[z](g)&&(b.glyphs[e].k[g]=f.k[g])}}return a},v.getFont=function(a,b,d,e){if(e=e||"normal",d=d||"normal",b=+b||{normal:400,bold:700,lighter:300,bolder:800}[b]||400,c.fonts){var f=c.fonts[a];if(!f){var g=new RegExp("(^|\\s)"+a.replace(/[^\w\d\s+!~.:_-]/g,G)+"(\\s|$)","i");for(var h in c.fonts)if(c.fonts[z](h)&&g.test(h)){f=c.fonts[h];break}}var i;if(f)for(var j=0,k=f.length;k>j&&(i=f[j],i.face["font-weight"]!=b||i.face["font-style"]!=d&&i.face["font-style"]||i.face["font-stretch"]!=e);j++);return i}},v.print=function(a,b,d,e,f,g,h,i){g=g||"middle",h=O(P(h||0,1),-1),i=O(P(i||1,3),1);var j,k=I(d)[J](G),l=0,m=0,n=G;if(c.is(e,"string")&&(e=this.getFont(e)),e){j=(f||16)/e.face["units-per-em"];for(var o=e.face.bbox[J](w),p=+o[0],q=o[3]-o[1],r=0,s=+o[1]+("baseline"==g?q+ +e.face.descent:q/2),t=0,u=k.length;u>t;t++){if("\n"==k[t])l=0,x=0,m=0,r+=q*i;else{var v=m&&e.glyphs[k[t-1]]||{},x=e.glyphs[k[t]];l+=m?(v.w||e.w)+(v.k&&v.k[k[t]]||0)+e.w*h:0,m=1}x&&x.d&&(n+=c.transformPath(x.d,["t",l*j,r*j,"s",j,j,p,s,"t",(a-p)/j,(b-s)/j]))}}return this.path(n).attr({fill:"#000",stroke:"none"})},v.add=function(a){if(c.is(a,"array"))for(var b,d=this.set(),e=0,f=a.length;f>e;e++)b=a[e]||{},x[z](b.type)&&d.push(this[b.type]().attr(b));return d},c.format=function(a,b){var d=c.is(b,V)?[0][E](b):arguments;return a&&c.is(a,U)&&d.length-1&&(a=a.replace(y,function(a,b){return null==d[++b]?G:d[b]})),a||G},c.fullfill=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return String(b).replace(a,function(a,b){return c(a,b,d)})}}(),c.ninja=function(){return B.was?A.win.Raphael=B.is:delete Raphael,c},c.st=nc,function(a,b,d){function e(){/in/.test(a.readyState)?setTimeout(e,9):c.eve("raphael.DOMload")}null==a.readyState&&a.addEventListener&&(a.addEventListener(b,d=function(){a.removeEventListener(b,d,!1),a.readyState="complete"},!1),a.readyState="loading"),e()}(document,"DOMContentLoaded"),b.on("raphael.DOMload",function(){u=!0}),function(){if(c.svg){var a="hasOwnProperty",b=String,d=parseFloat,e=parseInt,f=Math,g=f.max,h=f.abs,i=f.pow,j=/[, ]+/,k=c.eve,l="",m=" ",n="http://www.w3.org/1999/xlink",o={block:"M5,0 0,2.5 5,5z",classic:"M5,0 0,2.5 5,5 3.5,3 3.5,2z",diamond:"M2.5,0 5,2.5 2.5,5 0,2.5z",open:"M6,1 1,3.5 6,6",oval:"M2.5,0A2.5,2.5,0,0,1,2.5,5 2.5,2.5,0,0,1,2.5,0z"},p={};c.toString=function(){return"Your browser supports SVG.\nYou are running RaphaĂ«l "+this.version};var q=function(d,e){if(e){"string"==typeof d&&(d=q(d));for(var f in e)e[a](f)&&("xlink:"==f.substring(0,6)?d.setAttributeNS(n,f.substring(6),b(e[f])):d.setAttribute(f,b(e[f])))}else d=c._g.doc.createElementNS("http://www.w3.org/2000/svg",d),d.style&&(d.style.webkitTapHighlightColor="rgba(0,0,0,0)");return d},r=function(a,e){var j="linear",k=a.id+e,m=.5,n=.5,o=a.node,p=a.paper,r=o.style,s=c._g.doc.getElementById(k);if(!s){if(e=b(e).replace(c._radial_gradient,function(a,b,c){if(j="radial",b&&c){m=d(b),n=d(c);var e=2*(n>.5)-1;i(m-.5,2)+i(n-.5,2)>.25&&(n=f.sqrt(.25-i(m-.5,2))*e+.5)&&.5!=n&&(n=n.toFixed(5)-1e-5*e)}return l}),e=e.split(/\s*\-\s*/),"linear"==j){var t=e.shift();if(t=-d(t),isNaN(t))return null;var u=[0,0,f.cos(c.rad(t)),f.sin(c.rad(t))],v=1/(g(h(u[2]),h(u[3]))||1);u[2]*=v,u[3]*=v,u[2]<0&&(u[0]=-u[2],u[2]=0),u[3]<0&&(u[1]=-u[3],u[3]=0)}var w=c._parseDots(e);if(!w)return null;if(k=k.replace(/[\(\)\s,\xb0#]/g,"_"),a.gradient&&k!=a.gradient.id&&(p.defs.removeChild(a.gradient),delete a.gradient),!a.gradient){s=q(j+"Gradient",{id:k}),a.gradient=s,q(s,"radial"==j?{fx:m,fy:n}:{x1:u[0],y1:u[1],x2:u[2],y2:u[3],gradientTransform:a.matrix.invert()}),p.defs.appendChild(s);for(var x=0,y=w.length;y>x;x++)s.appendChild(q("stop",{offset:w[x].offset?w[x].offset:x?"100%":"0%","stop-color":w[x].color||"#fff"}))}}return q(o,{fill:"url(#"+k+")",opacity:1,"fill-opacity":1}),r.fill=l,r.opacity=1,r.fillOpacity=1,1},s=function(a){var b=a.getBBox(1);q(a.pattern,{patternTransform:a.matrix.invert()+" translate("+b.x+","+b.y+")"})},t=function(d,e,f){if("path"==d.type){for(var g,h,i,j,k,m=b(e).toLowerCase().split("-"),n=d.paper,r=f?"end":"start",s=d.node,t=d.attrs,u=t["stroke-width"],v=m.length,w="classic",x=3,y=3,z=5;v--;)switch(m[v]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":w=m[v];break;case"wide":y=5;break;case"narrow":y=2;break;case"long":x=5;break;case"short":x=2}if("open"==w?(x+=2,y+=2,z+=2,i=1,j=f?4:1,k={fill:"none",stroke:t.stroke}):(j=i=x/2,k={fill:t.stroke,stroke:"none"}),d._.arrows?f?(d._.arrows.endPath&&p[d._.arrows.endPath]--,d._.arrows.endMarker&&p[d._.arrows.endMarker]--):(d._.arrows.startPath&&p[d._.arrows.startPath]--,d._.arrows.startMarker&&p[d._.arrows.startMarker]--):d._.arrows={},"none"!=w){var A="raphael-marker-"+w,B="raphael-marker-"+r+w+x+y;c._g.doc.getElementById(A)?p[A]++:(n.defs.appendChild(q(q("path"),{"stroke-linecap":"round",d:o[w],id:A})),p[A]=1);var C,D=c._g.doc.getElementById(B);D?(p[B]++,C=D.getElementsByTagName("use")[0]):(D=q(q("marker"),{id:B,markerHeight:y,markerWidth:x,orient:"auto",refX:j,refY:y/2}),C=q(q("use"),{"xlink:href":"#"+A,transform:(f?"rotate(180 "+x/2+" "+y/2+") ":l)+"scale("+x/z+","+y/z+")","stroke-width":(1/((x/z+y/z)/2)).toFixed(4)}),D.appendChild(C),n.defs.appendChild(D),p[B]=1),q(C,k);var E=i*("diamond"!=w&&"oval"!=w);f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-E*u):(g=E*u,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),k={},k["marker-"+r]="url(#"+B+")",(h||g)&&(k.d=c.getSubpath(t.path,g,h)),q(s,k),d._.arrows[r+"Path"]=A,d._.arrows[r+"Marker"]=B,d._.arrows[r+"dx"]=E,d._.arrows[r+"Type"]=w,d._.arrows[r+"String"]=e}else f?(g=d._.arrows.startdx*u||0,h=c.getTotalLength(t.path)-g):(g=0,h=c.getTotalLength(t.path)-(d._.arrows.enddx*u||0)),d._.arrows[r+"Path"]&&q(s,{d:c.getSubpath(t.path,g,h)}),delete d._.arrows[r+"Path"],delete d._.arrows[r+"Marker"],delete d._.arrows[r+"dx"],delete d._.arrows[r+"Type"],delete d._.arrows[r+"String"];for(k in p)if(p[a](k)&&!p[k]){var F=c._g.doc.getElementById(k);F&&F.parentNode.removeChild(F)}}},u={"":[0],none:[0],"-":[3,1],".":[1,1],"-.":[3,1,1,1],"-..":[3,1,1,1,1,1],". ":[1,3],"- ":[4,3],"--":[8,3],"- .":[4,3,1,3],"--.":[8,3,1,3],"--..":[8,3,1,3,1,3]},v=function(a,c,d){if(c=u[b(c).toLowerCase()]){for(var e=a.attrs["stroke-width"]||"1",f={round:e,square:e,butt:0}[a.attrs["stroke-linecap"]||d["stroke-linecap"]]||0,g=[],h=c.length;h--;)g[h]=c[h]*e+(h%2?1:-1)*f;q(a.node,{"stroke-dasharray":g.join(",")})}},w=function(d,f){var i=d.node,k=d.attrs,m=i.style.visibility;i.style.visibility="hidden";for(var o in f)if(f[a](o)){if(!c._availableAttrs[a](o))continue;var p=f[o];switch(k[o]=p,o){case"blur":d.blur(p);break;case"href":case"title":var u=q("title"),w=c._g.doc.createTextNode(p);u.appendChild(w),i.appendChild(u);break;case"target":var x=i.parentNode;if("a"!=x.tagName.toLowerCase()){var u=q("a");x.insertBefore(u,i),u.appendChild(i),x=u}"target"==o?x.setAttributeNS(n,"show","blank"==p?"new":p):x.setAttributeNS(n,o,p);break;case"cursor":i.style.cursor=p;break;case"transform":d.transform(p);break;case"arrow-start":t(d,p);break;case"arrow-end":t(d,p,1);break;case"clip-rect":var z=b(p).split(j);if(4==z.length){d.clip&&d.clip.parentNode.parentNode.removeChild(d.clip.parentNode);var A=q("clipPath"),B=q("rect");A.id=c.createUUID(),q(B,{x:z[0],y:z[1],width:z[2],height:z[3]}),A.appendChild(B),d.paper.defs.appendChild(A),q(i,{"clip-path":"url(#"+A.id+")"}),d.clip=B}if(!p){var C=i.getAttribute("clip-path");if(C){var D=c._g.doc.getElementById(C.replace(/(^url\(#|\)$)/g,l));D&&D.parentNode.removeChild(D),q(i,{"clip-path":l}),delete d.clip}}break;case"path":"path"==d.type&&(q(i,{d:p?k.path=c._pathToAbsolute(p):"M0,0"}),d._.dirty=1,d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1)));break;case"width":if(i.setAttribute(o,p),d._.dirty=1,!k.fx)break;o="x",p=k.x;case"x":k.fx&&(p=-k.x-(k.width||0));case"rx":if("rx"==o&&"rect"==d.type)break;case"cx":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"height":if(i.setAttribute(o,p),d._.dirty=1,!k.fy)break;o="y",p=k.y;case"y":k.fy&&(p=-k.y-(k.height||0));case"ry":if("ry"==o&&"rect"==d.type)break;case"cy":i.setAttribute(o,p),d.pattern&&s(d),d._.dirty=1;break;case"r":"rect"==d.type?q(i,{rx:p,ry:p}):i.setAttribute(o,p),d._.dirty=1;break;case"src":"image"==d.type&&i.setAttributeNS(n,"href",p);break;case"stroke-width":(1!=d._.sx||1!=d._.sy)&&(p/=g(h(d._.sx),h(d._.sy))||1),d.paper._vbSize&&(p*=d.paper._vbSize),i.setAttribute(o,p),k["stroke-dasharray"]&&v(d,k["stroke-dasharray"],f),d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"stroke-dasharray":v(d,p,f);break;case"fill":var E=b(p).match(c._ISURL);if(E){A=q("pattern");var F=q("image");A.id=c.createUUID(),q(A,{x:0,y:0,patternUnits:"userSpaceOnUse",height:1,width:1}),q(F,{x:0,y:0,"xlink:href":E[1]}),A.appendChild(F),function(a){c._preload(E[1],function(){var b=this.offsetWidth,c=this.offsetHeight;q(a,{width:b,height:c}),q(F,{width:b,height:c}),d.paper.safari()})}(A),d.paper.defs.appendChild(A),q(i,{fill:"url(#"+A.id+")"}),d.pattern=A,d.pattern&&s(d);break}var G=c.getRGB(p);if(G.error){if(("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p)){if("opacity"in k||"fill-opacity"in k){var H=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l));if(H){var I=H.getElementsByTagName("stop");q(I[I.length-1],{"stop-opacity":("opacity"in k?k.opacity:1)*("fill-opacity"in k?k["fill-opacity"]:1)})}}k.gradient=p,k.fill="none";break}}else delete f.gradient,delete k.gradient,!c.is(k.opacity,"undefined")&&c.is(f.opacity,"undefined")&&q(i,{opacity:k.opacity}),!c.is(k["fill-opacity"],"undefined")&&c.is(f["fill-opacity"],"undefined")&&q(i,{"fill-opacity":k["fill-opacity"]});G[a]("opacity")&&q(i,{"fill-opacity":G.opacity>1?G.opacity/100:G.opacity});case"stroke":G=c.getRGB(p),i.setAttribute(o,G.hex),"stroke"==o&&G[a]("opacity")&&q(i,{"stroke-opacity":G.opacity>1?G.opacity/100:G.opacity}),"stroke"==o&&d._.arrows&&("startString"in d._.arrows&&t(d,d._.arrows.startString),"endString"in d._.arrows&&t(d,d._.arrows.endString,1));break;case"gradient":("circle"==d.type||"ellipse"==d.type||"r"!=b(p).charAt())&&r(d,p);break;case"opacity":k.gradient&&!k[a]("stroke-opacity")&&q(i,{"stroke-opacity":p>1?p/100:p});case"fill-opacity":if(k.gradient){H=c._g.doc.getElementById(i.getAttribute("fill").replace(/^url\(#|\)$/g,l)),H&&(I=H.getElementsByTagName("stop"),q(I[I.length-1],{"stop-opacity":p}));break}default:"font-size"==o&&(p=e(p,10)+"px");var J=o.replace(/(\-.)/g,function(a){return a.substring(1).toUpperCase()});i.style[J]=p,d._.dirty=1,i.setAttribute(o,p)}}y(d,f),i.style.visibility=m},x=1.2,y=function(d,f){if("text"==d.type&&(f[a]("text")||f[a]("font")||f[a]("font-size")||f[a]("x")||f[a]("y"))){var g=d.attrs,h=d.node,i=h.firstChild?e(c._g.doc.defaultView.getComputedStyle(h.firstChild,l).getPropertyValue("font-size"),10):10; - if(f[a]("text")){for(g.text=f.text;h.firstChild;)h.removeChild(h.firstChild);for(var j,k=b(f.text).split("\n"),m=[],n=0,o=k.length;o>n;n++)j=q("tspan"),n&&q(j,{dy:i*x,x:g.x}),j.appendChild(c._g.doc.createTextNode(k[n])),h.appendChild(j),m[n]=j}else for(m=h.getElementsByTagName("tspan"),n=0,o=m.length;o>n;n++)n?q(m[n],{dy:i*x,x:g.x}):q(m[0],{dy:0});q(h,{x:g.x,y:g.y}),d._.dirty=1;var p=d._getBBox(),r=g.y-(p.y+p.height/2);r&&c.is(r,"finite")&&q(m[0],{dy:r})}},z=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.matrix=c.matrix(),this.realPath=null,this.paper=b,this.attrs=this.attrs||{},this._={transform:[],sx:1,sy:1,deg:0,dx:0,dy:0,dirty:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},A=c.el;z.prototype=A,A.constructor=z,c._engine.path=function(a,b){var c=q("path");b.canvas&&b.canvas.appendChild(c);var d=new z(c,b);return d.type="path",w(d,{fill:"none",stroke:"#000",path:a}),d},A.rotate=function(a,c,e){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this.transform(this._.transform.concat([["r",a,c,e]])),this},A.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(j),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3])),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this},A.translate=function(a,c){return this.removed?this:(a=b(a).split(j),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this.transform(this._.transform.concat([["t",a,c]])),this)},A.transform=function(b){var d=this._;if(null==b)return d.transform;if(c._extractTransform(this,b),this.clip&&q(this.clip,{transform:this.matrix.invert()}),this.pattern&&s(this),this.node&&q(this.node,{transform:this.matrix}),1!=d.sx||1!=d.sy){var e=this.attrs[a]("stroke-width")?this.attrs["stroke-width"]:1;this.attr({"stroke-width":e})}return this},A.hide=function(){return!this.removed&&this.paper.safari(this.node.style.display="none"),this},A.show=function(){return!this.removed&&this.paper.safari(this.node.style.display=""),this},A.remove=function(){if(!this.removed&&this.node.parentNode){var a=this.paper;a.__set__&&a.__set__.exclude(this),k.unbind("raphael.*.*."+this.id),this.gradient&&a.defs.removeChild(this.gradient),c._tear(this,a),"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.removeChild(this.node.parentNode):this.node.parentNode.removeChild(this.node);for(var b in this)this[b]="function"==typeof this[b]?c._removedFactory(b):null;this.removed=!0}},A._getBBox=function(){if("none"==this.node.style.display){this.show();var a=!0}var b={};try{b=this.node.getBBox()}catch(c){}finally{b=b||{}}return a&&this.hide(),b},A.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if("fill"==b&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;if("transform"==b)return this._.transform;for(var g=b.split(j),h={},i=0,l=g.length;l>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return l-1?h:h[g[0]]}if(null==d&&c.is(b,"array")){for(h={},i=0,l=b.length;l>i;i++)h[b[i]]=this.attr(b[i]);return h}if(null!=d){var m={};m[b]=d}else null!=b&&c.is(b,"object")&&(m=b);for(var n in m)k("raphael.attr."+n+"."+this.id,this,m[n]);for(n in this.paper.customAttributes)if(this.paper.customAttributes[a](n)&&m[a](n)&&c.is(this.paper.customAttributes[n],"function")){var o=this.paper.customAttributes[n].apply(this,[].concat(m[n]));this.attrs[n]=m[n];for(var p in o)o[a](p)&&(m[p]=o[p])}return w(this,m),this},A.toFront=function(){if(this.removed)return this;"a"==this.node.parentNode.tagName.toLowerCase()?this.node.parentNode.parentNode.appendChild(this.node.parentNode):this.node.parentNode.appendChild(this.node);var a=this.paper;return a.top!=this&&c._tofront(this,a),this},A.toBack=function(){if(this.removed)return this;var a=this.node.parentNode;return"a"==a.tagName.toLowerCase()?a.parentNode.insertBefore(this.node.parentNode,this.node.parentNode.parentNode.firstChild):a.firstChild!=this.node&&a.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper),this.paper,this},A.insertAfter=function(a){if(this.removed)return this;var b=a.node||a[a.length-1].node;return b.nextSibling?b.parentNode.insertBefore(this.node,b.nextSibling):b.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this},A.insertBefore=function(a){if(this.removed)return this;var b=a.node||a[0].node;return b.parentNode.insertBefore(this.node,b),c._insertbefore(this,a,this.paper),this},A.blur=function(a){var b=this;if(0!==+a){var d=q("filter"),e=q("feGaussianBlur");b.attrs.blur=a,d.id=c.createUUID(),q(e,{stdDeviation:+a||1.5}),d.appendChild(e),b.paper.defs.appendChild(d),b._blur=d,q(b.node,{filter:"url(#"+d.id+")"})}else b._blur&&(b._blur.parentNode.removeChild(b._blur),delete b._blur,delete b.attrs.blur),b.node.removeAttribute("filter");return b},c._engine.circle=function(a,b,c,d){var e=q("circle");a.canvas&&a.canvas.appendChild(e);var f=new z(e,a);return f.attrs={cx:b,cy:c,r:d,fill:"none",stroke:"#000"},f.type="circle",q(e,f.attrs),f},c._engine.rect=function(a,b,c,d,e,f){var g=q("rect");a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:b,y:c,width:d,height:e,r:f||0,rx:f||0,ry:f||0,fill:"none",stroke:"#000"},h.type="rect",q(g,h.attrs),h},c._engine.ellipse=function(a,b,c,d,e){var f=q("ellipse");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={cx:b,cy:c,rx:d,ry:e,fill:"none",stroke:"#000"},g.type="ellipse",q(f,g.attrs),g},c._engine.image=function(a,b,c,d,e,f){var g=q("image");q(g,{x:c,y:d,width:e,height:f,preserveAspectRatio:"none"}),g.setAttributeNS(n,"href",b),a.canvas&&a.canvas.appendChild(g);var h=new z(g,a);return h.attrs={x:c,y:d,width:e,height:f,src:b},h.type="image",h},c._engine.text=function(a,b,d,e){var f=q("text");a.canvas&&a.canvas.appendChild(f);var g=new z(f,a);return g.attrs={x:b,y:d,"text-anchor":"middle",text:e,font:c._availableAttrs.font,stroke:"none",fill:"#000"},g.type="text",w(g,g.attrs),g},c._engine.setSize=function(a,b){return this.width=a||this.width,this.height=b||this.height,this.canvas.setAttribute("width",this.width),this.canvas.setAttribute("height",this.height),this._viewBox&&this.setViewBox.apply(this,this._viewBox),this},c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a&&a.container,d=a.x,e=a.y,f=a.width,g=a.height;if(!b)throw new Error("SVG container not found.");var h,i=q("svg"),j="overflow:hidden;";return d=d||0,e=e||0,f=f||512,g=g||342,q(i,{height:g,version:1.1,width:f,xmlns:"http://www.w3.org/2000/svg"}),1==b?(i.style.cssText=j+"position:absolute;left:"+d+"px;top:"+e+"px",c._g.doc.body.appendChild(i),h=1):(i.style.cssText=j+"position:relative",b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i)),b=new c._Paper,b.width=f,b.height=g,b.canvas=i,b.clear(),b._left=b._top=0,h&&(b.renderfix=function(){}),b.renderfix(),b},c._engine.setViewBox=function(a,b,c,d,e){k("raphael.setViewBox",this,this._viewBox,[a,b,c,d,e]);var f,h,i=g(c/this.width,d/this.height),j=this.top,l=e?"meet":"xMinYMin";for(null==a?(this._vbSize&&(i=1),delete this._vbSize,f="0 0 "+this.width+m+this.height):(this._vbSize=i,f=a+m+b+m+c+m+d),q(this.canvas,{viewBox:f,preserveAspectRatio:l});i&&j;)h="stroke-width"in j.attrs?j.attrs["stroke-width"]:1,j.attr({"stroke-width":h}),j._.dirty=1,j._.dirtyT=1,j=j.prev;return this._viewBox=[a,b,c,d,!!e],this},c.prototype.renderfix=function(){var a,b=this.canvas,c=b.style;try{a=b.getScreenCTM()||b.createSVGMatrix()}catch(d){a=b.createSVGMatrix()}var e=-a.e%1,f=-a.f%1;(e||f)&&(e&&(this._left=(this._left+e)%1,c.left=this._left+"px"),f&&(this._top=(this._top+f)%1,c.top=this._top+"px"))},c.prototype.clear=function(){c.eve("raphael.clear",this);for(var a=this.canvas;a.firstChild;)a.removeChild(a.firstChild);this.bottom=this.top=null,(this.desc=q("desc")).appendChild(c._g.doc.createTextNode("Created with RaphaĂ«l "+c.version)),a.appendChild(this.desc),a.appendChild(this.defs=q("defs"))},c.prototype.remove=function(){k("raphael.remove",this),this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null};var B=c.st;for(var C in A)A[a](C)&&!B[a](C)&&(B[C]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(C))}}(),function(){if(c.vml){var a="hasOwnProperty",b=String,d=parseFloat,e=Math,f=e.round,g=e.max,h=e.min,i=e.abs,j="fill",k=/[, ]+/,l=c.eve,m=" progid:DXImageTransform.Microsoft",n=" ",o="",p={M:"m",L:"l",C:"c",Z:"x",m:"t",l:"r",c:"v",z:"x"},q=/([clmz]),?([^clmz]*)/gi,r=/ progid:\S+Blur\([^\)]+\)/g,s=/-?[^,\s-]+/g,t="position:absolute;left:0;top:0;width:1px;height:1px",u=21600,v={path:1,rect:1,image:1},w={circle:1,ellipse:1},x=function(a){var d=/[ahqstv]/gi,e=c._pathToAbsolute;if(b(a).match(d)&&(e=c._path2curve),d=/[clmz]/g,e==c._pathToAbsolute&&!b(a).match(d)){var g=b(a).replace(q,function(a,b,c){var d=[],e="m"==b.toLowerCase(),g=p[b];return c.replace(s,function(a){e&&2==d.length&&(g+=d+p["m"==b?"l":"L"],d=[]),d.push(f(a*u))}),g+d});return g}var h,i,j=e(a);g=[];for(var k=0,l=j.length;l>k;k++){h=j[k],i=j[k][0].toLowerCase(),"z"==i&&(i="x");for(var m=1,r=h.length;r>m;m++)i+=f(h[m]*u)+(m!=r-1?",":o);g.push(i)}return g.join(n)},y=function(a,b,d){var e=c.matrix();return e.rotate(-a,.5,.5),{dx:e.x(b,d),dy:e.y(b,d)}},z=function(a,b,c,d,e,f){var g=a._,h=a.matrix,k=g.fillpos,l=a.node,m=l.style,o=1,p="",q=u/b,r=u/c;if(m.visibility="hidden",b&&c){if(l.coordsize=i(q)+n+i(r),m.rotation=f*(0>b*c?-1:1),f){var s=y(f,d,e);d=s.dx,e=s.dy}if(0>b&&(p+="x"),0>c&&(p+=" y")&&(o=-1),m.flip=p,l.coordorigin=d*-q+n+e*-r,k||g.fillsize){var t=l.getElementsByTagName(j);t=t&&t[0],l.removeChild(t),k&&(s=y(f,h.x(k[0],k[1]),h.y(k[0],k[1])),t.position=s.dx*o+n+s.dy*o),g.fillsize&&(t.size=g.fillsize[0]*i(b)+n+g.fillsize[1]*i(c)),l.appendChild(t)}m.visibility="visible"}};c.toString=function(){return"Your browser doesn’t support SVG. Falling down to VML.\nYou are running RaphaĂ«l "+this.version};var A=function(a,c,d){for(var e=b(c).toLowerCase().split("-"),f=d?"end":"start",g=e.length,h="classic",i="medium",j="medium";g--;)switch(e[g]){case"block":case"classic":case"oval":case"diamond":case"open":case"none":h=e[g];break;case"wide":case"narrow":j=e[g];break;case"long":case"short":i=e[g]}var k=a.node.getElementsByTagName("stroke")[0];k[f+"arrow"]=h,k[f+"arrowlength"]=i,k[f+"arrowwidth"]=j},B=function(e,i){e.attrs=e.attrs||{};var l=e.node,m=e.attrs,p=l.style,q=v[e.type]&&(i.x!=m.x||i.y!=m.y||i.width!=m.width||i.height!=m.height||i.cx!=m.cx||i.cy!=m.cy||i.rx!=m.rx||i.ry!=m.ry||i.r!=m.r),r=w[e.type]&&(m.cx!=i.cx||m.cy!=i.cy||m.r!=i.r||m.rx!=i.rx||m.ry!=i.ry),s=e;for(var t in i)i[a](t)&&(m[t]=i[t]);if(q&&(m.path=c._getPath[e.type](e),e._.dirty=1),i.href&&(l.href=i.href),i.title&&(l.title=i.title),i.target&&(l.target=i.target),i.cursor&&(p.cursor=i.cursor),"blur"in i&&e.blur(i.blur),(i.path&&"path"==e.type||q)&&(l.path=x(~b(m.path).toLowerCase().indexOf("r")?c._pathToAbsolute(m.path):m.path),"image"==e.type&&(e._.fillpos=[m.x,m.y],e._.fillsize=[m.width,m.height],z(e,1,1,0,0,0))),"transform"in i&&e.transform(i.transform),r){var y=+m.cx,B=+m.cy,D=+m.rx||+m.r||0,E=+m.ry||+m.r||0;l.path=c.format("ar{0},{1},{2},{3},{4},{1},{4},{1}x",f((y-D)*u),f((B-E)*u),f((y+D)*u),f((B+E)*u),f(y*u)),e._.dirty=1}if("clip-rect"in i){var G=b(i["clip-rect"]).split(k);if(4==G.length){G[2]=+G[2]+ +G[0],G[3]=+G[3]+ +G[1];var H=l.clipRect||c._g.doc.createElement("div"),I=H.style;I.clip=c.format("rect({1}px {2}px {3}px {0}px)",G),l.clipRect||(I.position="absolute",I.top=0,I.left=0,I.width=e.paper.width+"px",I.height=e.paper.height+"px",l.parentNode.insertBefore(H,l),H.appendChild(l),l.clipRect=H)}i["clip-rect"]||l.clipRect&&(l.clipRect.style.clip="auto")}if(e.textpath){var J=e.textpath.style;i.font&&(J.font=i.font),i["font-family"]&&(J.fontFamily='"'+i["font-family"].split(",")[0].replace(/^['"]+|['"]+$/g,o)+'"'),i["font-size"]&&(J.fontSize=i["font-size"]),i["font-weight"]&&(J.fontWeight=i["font-weight"]),i["font-style"]&&(J.fontStyle=i["font-style"])}if("arrow-start"in i&&A(s,i["arrow-start"]),"arrow-end"in i&&A(s,i["arrow-end"],1),null!=i.opacity||null!=i["stroke-width"]||null!=i.fill||null!=i.src||null!=i.stroke||null!=i["stroke-width"]||null!=i["stroke-opacity"]||null!=i["fill-opacity"]||null!=i["stroke-dasharray"]||null!=i["stroke-miterlimit"]||null!=i["stroke-linejoin"]||null!=i["stroke-linecap"]){var K=l.getElementsByTagName(j),L=!1;if(K=K&&K[0],!K&&(L=K=F(j)),"image"==e.type&&i.src&&(K.src=i.src),i.fill&&(K.on=!0),(null==K.on||"none"==i.fill||null===i.fill)&&(K.on=!1),K.on&&i.fill){var M=b(i.fill).match(c._ISURL);if(M){K.parentNode==l&&l.removeChild(K),K.rotate=!0,K.src=M[1],K.type="tile";var N=e.getBBox(1);K.position=N.x+n+N.y,e._.fillpos=[N.x,N.y],c._preload(M[1],function(){e._.fillsize=[this.offsetWidth,this.offsetHeight]})}else K.color=c.getRGB(i.fill).hex,K.src=o,K.type="solid",c.getRGB(i.fill).error&&(s.type in{circle:1,ellipse:1}||"r"!=b(i.fill).charAt())&&C(s,i.fill,K)&&(m.fill="none",m.gradient=i.fill,K.rotate=!1)}if("fill-opacity"in i||"opacity"in i){var O=((+m["fill-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+c.getRGB(i.fill).o+1||2)-1);O=h(g(O,0),1),K.opacity=O,K.src&&(K.color="none")}l.appendChild(K);var P=l.getElementsByTagName("stroke")&&l.getElementsByTagName("stroke")[0],Q=!1;!P&&(Q=P=F("stroke")),(i.stroke&&"none"!=i.stroke||i["stroke-width"]||null!=i["stroke-opacity"]||i["stroke-dasharray"]||i["stroke-miterlimit"]||i["stroke-linejoin"]||i["stroke-linecap"])&&(P.on=!0),("none"==i.stroke||null===i.stroke||null==P.on||0==i.stroke||0==i["stroke-width"])&&(P.on=!1);var R=c.getRGB(i.stroke);P.on&&i.stroke&&(P.color=R.hex),O=((+m["stroke-opacity"]+1||2)-1)*((+m.opacity+1||2)-1)*((+R.o+1||2)-1);var S=.75*(d(i["stroke-width"])||1);if(O=h(g(O,0),1),null==i["stroke-width"]&&(S=m["stroke-width"]),i["stroke-width"]&&(P.weight=S),S&&1>S&&(O*=S)&&(P.weight=1),P.opacity=O,i["stroke-linejoin"]&&(P.joinstyle=i["stroke-linejoin"]||"miter"),P.miterlimit=i["stroke-miterlimit"]||8,i["stroke-linecap"]&&(P.endcap="butt"==i["stroke-linecap"]?"flat":"square"==i["stroke-linecap"]?"square":"round"),i["stroke-dasharray"]){var T={"-":"shortdash",".":"shortdot","-.":"shortdashdot","-..":"shortdashdotdot",". ":"dot","- ":"dash","--":"longdash","- .":"dashdot","--.":"longdashdot","--..":"longdashdotdot"};P.dashstyle=T[a](i["stroke-dasharray"])?T[i["stroke-dasharray"]]:o}Q&&l.appendChild(P)}if("text"==s.type){s.paper.canvas.style.display=o;var U=s.paper.span,V=100,W=m.font&&m.font.match(/\d+(?:\.\d*)?(?=px)/);p=U.style,m.font&&(p.font=m.font),m["font-family"]&&(p.fontFamily=m["font-family"]),m["font-weight"]&&(p.fontWeight=m["font-weight"]),m["font-style"]&&(p.fontStyle=m["font-style"]),W=d(m["font-size"]||W&&W[0])||10,p.fontSize=W*V+"px",s.textpath.string&&(U.innerHTML=b(s.textpath.string).replace(/"));var X=U.getBoundingClientRect();s.W=m.w=(X.right-X.left)/V,s.H=m.h=(X.bottom-X.top)/V,s.X=m.x,s.Y=m.y+s.H/2,("x"in i||"y"in i)&&(s.path.v=c.format("m{0},{1}l{2},{1}",f(m.x*u),f(m.y*u),f(m.x*u)+1));for(var Y=["x","y","text","font","font-family","font-weight","font-style","font-size"],Z=0,$=Y.length;$>Z;Z++)if(Y[Z]in i){s._.dirty=1;break}switch(m["text-anchor"]){case"start":s.textpath.style["v-text-align"]="left",s.bbx=s.W/2;break;case"end":s.textpath.style["v-text-align"]="right",s.bbx=-s.W/2;break;default:s.textpath.style["v-text-align"]="center",s.bbx=0}s.textpath.style["v-text-kern"]=!0}},C=function(a,f,g){a.attrs=a.attrs||{};var h=(a.attrs,Math.pow),i="linear",j=".5 .5";if(a.attrs.gradient=f,f=b(f).replace(c._radial_gradient,function(a,b,c){return i="radial",b&&c&&(b=d(b),c=d(c),h(b-.5,2)+h(c-.5,2)>.25&&(c=e.sqrt(.25-h(b-.5,2))*(2*(c>.5)-1)+.5),j=b+n+c),o}),f=f.split(/\s*\-\s*/),"linear"==i){var k=f.shift();if(k=-d(k),isNaN(k))return null}var l=c._parseDots(f);if(!l)return null;if(a=a.shape||a.node,l.length){a.removeChild(g),g.on=!0,g.method="none",g.color=l[0].color,g.color2=l[l.length-1].color;for(var m=[],p=0,q=l.length;q>p;p++)l[p].offset&&m.push(l[p].offset+n+l[p].color);g.colors=m.length?m.join():"0% "+g.color,"radial"==i?(g.type="gradientTitle",g.focus="100%",g.focussize="0 0",g.focusposition=j,g.angle=0):(g.type="gradient",g.angle=(270-k)%360),a.appendChild(g)}return 1},D=function(a,b){this[0]=this.node=a,a.raphael=!0,this.id=c._oid++,a.raphaelid=this.id,this.X=0,this.Y=0,this.attrs={},this.paper=b,this.matrix=c.matrix(),this._={transform:[],sx:1,sy:1,dx:0,dy:0,deg:0,dirty:1,dirtyT:1},!b.bottom&&(b.bottom=this),this.prev=b.top,b.top&&(b.top.next=this),b.top=this,this.next=null},E=c.el;D.prototype=E,E.constructor=D,E.transform=function(a){if(null==a)return this._.transform;var d,e=this.paper._viewBoxShift,f=e?"s"+[e.scale,e.scale]+"-1-1t"+[e.dx,e.dy]:o;e&&(d=a=b(a).replace(/\.{3}|\u2026/g,this._.transform||o)),c._extractTransform(this,f+a);var g,h=this.matrix.clone(),i=this.skew,j=this.node,k=~b(this.attrs.fill).indexOf("-"),l=!b(this.attrs.fill).indexOf("url(");if(h.translate(1,1),l||k||"image"==this.type)if(i.matrix="1 0 0 1",i.offset="0 0",g=h.split(),k&&g.noRotation||!g.isSimple){j.style.filter=h.toFilter();var m=this.getBBox(),p=this.getBBox(1),q=m.x-p.x,r=m.y-p.y;j.coordorigin=q*-u+n+r*-u,z(this,1,1,q,r,0)}else j.style.filter=o,z(this,g.scalex,g.scaley,g.dx,g.dy,g.rotate);else j.style.filter=o,i.matrix=b(h),i.offset=h.offset();return d&&(this._.transform=d),this},E.rotate=function(a,c,e){if(this.removed)return this;if(null!=a){if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2])),a=d(a[0]),null==e&&(c=e),null==c||null==e){var f=this.getBBox(1);c=f.x+f.width/2,e=f.y+f.height/2}return this._.dirtyT=1,this.transform(this._.transform.concat([["r",a,c,e]])),this}},E.translate=function(a,c){return this.removed?this:(a=b(a).split(k),a.length-1&&(c=d(a[1])),a=d(a[0])||0,c=+c||0,this._.bbox&&(this._.bbox.x+=a,this._.bbox.y+=c),this.transform(this._.transform.concat([["t",a,c]])),this)},E.scale=function(a,c,e,f){if(this.removed)return this;if(a=b(a).split(k),a.length-1&&(c=d(a[1]),e=d(a[2]),f=d(a[3]),isNaN(e)&&(e=null),isNaN(f)&&(f=null)),a=d(a[0]),null==c&&(c=a),null==f&&(e=f),null==e||null==f)var g=this.getBBox(1);return e=null==e?g.x+g.width/2:e,f=null==f?g.y+g.height/2:f,this.transform(this._.transform.concat([["s",a,c,e,f]])),this._.dirtyT=1,this},E.hide=function(){return!this.removed&&(this.node.style.display="none"),this},E.show=function(){return!this.removed&&(this.node.style.display=o),this},E._getBBox=function(){return this.removed?{}:{x:this.X+(this.bbx||0)-this.W/2,y:this.Y-this.H,width:this.W,height:this.H}},E.remove=function(){if(!this.removed&&this.node.parentNode){this.paper.__set__&&this.paper.__set__.exclude(this),c.eve.unbind("raphael.*.*."+this.id),c._tear(this,this.paper),this.node.parentNode.removeChild(this.node),this.shape&&this.shape.parentNode.removeChild(this.shape);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;this.removed=!0}},E.attr=function(b,d){if(this.removed)return this;if(null==b){var e={};for(var f in this.attrs)this.attrs[a](f)&&(e[f]=this.attrs[f]);return e.gradient&&"none"==e.fill&&(e.fill=e.gradient)&&delete e.gradient,e.transform=this._.transform,e}if(null==d&&c.is(b,"string")){if(b==j&&"none"==this.attrs.fill&&this.attrs.gradient)return this.attrs.gradient;for(var g=b.split(k),h={},i=0,m=g.length;m>i;i++)b=g[i],h[b]=b in this.attrs?this.attrs[b]:c.is(this.paper.customAttributes[b],"function")?this.paper.customAttributes[b].def:c._availableAttrs[b];return m-1?h:h[g[0]]}if(this.attrs&&null==d&&c.is(b,"array")){for(h={},i=0,m=b.length;m>i;i++)h[b[i]]=this.attr(b[i]);return h}var n;null!=d&&(n={},n[b]=d),null==d&&c.is(b,"object")&&(n=b);for(var o in n)l("raphael.attr."+o+"."+this.id,this,n[o]);if(n){for(o in this.paper.customAttributes)if(this.paper.customAttributes[a](o)&&n[a](o)&&c.is(this.paper.customAttributes[o],"function")){var p=this.paper.customAttributes[o].apply(this,[].concat(n[o]));this.attrs[o]=n[o];for(var q in p)p[a](q)&&(n[q]=p[q])}n.text&&"text"==this.type&&(this.textpath.string=n.text),B(this,n)}return this},E.toFront=function(){return!this.removed&&this.node.parentNode.appendChild(this.node),this.paper&&this.paper.top!=this&&c._tofront(this,this.paper),this},E.toBack=function(){return this.removed?this:(this.node.parentNode.firstChild!=this.node&&(this.node.parentNode.insertBefore(this.node,this.node.parentNode.firstChild),c._toback(this,this.paper)),this)},E.insertAfter=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[a.length-1]),a.node.nextSibling?a.node.parentNode.insertBefore(this.node,a.node.nextSibling):a.node.parentNode.appendChild(this.node),c._insertafter(this,a,this.paper),this)},E.insertBefore=function(a){return this.removed?this:(a.constructor==c.st.constructor&&(a=a[0]),a.node.parentNode.insertBefore(this.node,a.node),c._insertbefore(this,a,this.paper),this)},E.blur=function(a){var b=this.node.runtimeStyle,d=b.filter;return d=d.replace(r,o),0!==+a?(this.attrs.blur=a,b.filter=d+n+m+".Blur(pixelradius="+(+a||1.5)+")",b.margin=c.format("-{0}px 0 0 -{0}px",f(+a||1.5))):(b.filter=d,b.margin=0,delete this.attrs.blur),this},c._engine.path=function(a,b){var c=F("shape");c.style.cssText=t,c.coordsize=u+n+u,c.coordorigin=b.coordorigin;var d=new D(c,b),e={fill:"none",stroke:"#000"};a&&(e.path=a),d.type="path",d.path=[],d.Path=o,B(d,e),b.canvas.appendChild(c);var f=F("skew");return f.on=!0,c.appendChild(f),d.skew=f,d.transform(o),d},c._engine.rect=function(a,b,d,e,f,g){var h=c._rectPath(b,d,e,f,g),i=a.path(h),j=i.attrs;return i.X=j.x=b,i.Y=j.y=d,i.W=j.width=e,i.H=j.height=f,j.r=g,j.path=h,i.type="rect",i},c._engine.ellipse=function(a,b,c,d,e){var f=a.path();return f.attrs,f.X=b-d,f.Y=c-e,f.W=2*d,f.H=2*e,f.type="ellipse",B(f,{cx:b,cy:c,rx:d,ry:e}),f},c._engine.circle=function(a,b,c,d){var e=a.path();return e.attrs,e.X=b-d,e.Y=c-d,e.W=e.H=2*d,e.type="circle",B(e,{cx:b,cy:c,r:d}),e},c._engine.image=function(a,b,d,e,f,g){var h=c._rectPath(d,e,f,g),i=a.path(h).attr({stroke:"none"}),k=i.attrs,l=i.node,m=l.getElementsByTagName(j)[0];return k.src=b,i.X=k.x=d,i.Y=k.y=e,i.W=k.width=f,i.H=k.height=g,k.path=h,i.type="image",m.parentNode==l&&l.removeChild(m),m.rotate=!0,m.src=b,m.type="tile",i._.fillpos=[d,e],i._.fillsize=[f,g],l.appendChild(m),z(i,1,1,0,0,0),i},c._engine.text=function(a,d,e,g){var h=F("shape"),i=F("path"),j=F("textpath");d=d||0,e=e||0,g=g||"",i.v=c.format("m{0},{1}l{2},{1}",f(d*u),f(e*u),f(d*u)+1),i.textpathok=!0,j.string=b(g),j.on=!0,h.style.cssText=t,h.coordsize=u+n+u,h.coordorigin="0 0";var k=new D(h,a),l={fill:"#000",stroke:"none",font:c._availableAttrs.font,text:g};k.shape=h,k.path=i,k.textpath=j,k.type="text",k.attrs.text=b(g),k.attrs.x=d,k.attrs.y=e,k.attrs.w=1,k.attrs.h=1,B(k,l),h.appendChild(j),h.appendChild(i),a.canvas.appendChild(h);var m=F("skew");return m.on=!0,h.appendChild(m),k.skew=m,k.transform(o),k},c._engine.setSize=function(a,b){var d=this.canvas.style;return this.width=a,this.height=b,a==+a&&(a+="px"),b==+b&&(b+="px"),d.width=a,d.height=b,d.clip="rect(0 "+a+" "+b+" 0)",this._viewBox&&c._engine.setViewBox.apply(this,this._viewBox),this},c._engine.setViewBox=function(a,b,d,e,f){c.eve("raphael.setViewBox",this,this._viewBox,[a,b,d,e,f]);var h,i,j=this.width,k=this.height,l=1/g(d/j,e/k);return f&&(h=k/e,i=j/d,j>d*h&&(a-=(j-d*h)/2/h),k>e*i&&(b-=(k-e*i)/2/i)),this._viewBox=[a,b,d,e,!!f],this._viewBoxShift={dx:-a,dy:-b,scale:l},this.forEach(function(a){a.transform("...")}),this};var F;c._engine.initWin=function(a){var b=a.document;b.createStyleSheet().addRule(".rvml","behavior:url(#default#VML)");try{!b.namespaces.rvml&&b.namespaces.add("rvml","urn:schemas-microsoft-com:vml"),F=function(a){return b.createElement("')}}catch(c){F=function(a){return b.createElement("<"+a+' xmlns="urn:schemas-microsoft.com:vml" class="rvml">')}}},c._engine.initWin(c._g.win),c._engine.create=function(){var a=c._getContainer.apply(0,arguments),b=a.container,d=a.height,e=a.width,f=a.x,g=a.y;if(!b)throw new Error("VML container not found.");var h=new c._Paper,i=h.canvas=c._g.doc.createElement("div"),j=i.style;return f=f||0,g=g||0,e=e||512,d=d||342,h.width=e,h.height=d,e==+e&&(e+="px"),d==+d&&(d+="px"),h.coordsize=1e3*u+n+1e3*u,h.coordorigin="0 0",h.span=c._g.doc.createElement("span"),h.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;",i.appendChild(h.span),j.cssText=c.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden",e,d),1==b?(c._g.doc.body.appendChild(i),j.left=f+"px",j.top=g+"px",j.position="absolute"):b.firstChild?b.insertBefore(i,b.firstChild):b.appendChild(i),h.renderfix=function(){},h},c.prototype.clear=function(){c.eve("raphael.clear",this),this.canvas.innerHTML=o,this.span=c._g.doc.createElement("span"),this.span.style.cssText="position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;",this.canvas.appendChild(this.span),this.bottom=this.top=null},c.prototype.remove=function(){c.eve("raphael.remove",this),this.canvas.parentNode.removeChild(this.canvas);for(var a in this)this[a]="function"==typeof this[a]?c._removedFactory(a):null;return!0};var G=c.st;for(var H in E)E[a](H)&&!G[a](H)&&(G[H]=function(a){return function(){var b=arguments;return this.forEach(function(c){c[a].apply(c,b)})}}(H))}}(),B.was?A.win.Raphael=c:Raphael=c,c}); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael.js b/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael.js deleted file mode 100755 index 385562e3ce..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/raphael.js +++ /dev/null @@ -1,3725 +0,0 @@ -/*! - * Raphael 1.5.2 - JavaScript Vector Library - * - * Copyright (c) 2010 Dmitry Baranovskiy (http://raphaeljs.com) - * Licensed under the MIT (http://raphaeljs.com/license.html) license. - */ -(function () { - function R() { - if (R.is(arguments[0], array)) { - var a = arguments[0], - cnv = create[apply](R, a.splice(0, 3 + R.is(a[0], nu))), - res = cnv.set(); - for (var i = 0, ii = a[length]; i < ii; i++) { - var j = a[i] || {}; - elements[has](j.type) && res[push](cnv[j.type]().attr(j)); - } - return res; - } - return create[apply](R, arguments); - } - R.version = "1.5.2"; - var separator = /[, ]+/, - elements = {circle: 1, rect: 1, path: 1, ellipse: 1, text: 1, image: 1}, - formatrg = /\{(\d+)\}/g, - proto = "prototype", - has = "hasOwnProperty", - doc = document, - win = window, - oldRaphael = { - was: Object[proto][has].call(win, "Raphael"), - is: win.Raphael - }, - Paper = function () { - this.customAttributes = {}; - }, - paperproto, - appendChild = "appendChild", - apply = "apply", - concat = "concat", - supportsTouch = "createTouch" in doc, - E = "", - S = " ", - Str = String, - split = "split", - events = "click dblclick mousedown mousemove mouseout mouseover mouseup touchstart touchmove touchend orientationchange touchcancel gesturestart gesturechange gestureend"[split](S), - touchMap = { - mousedown: "touchstart", - mousemove: "touchmove", - mouseup: "touchend" - }, - join = "join", - length = "length", - lowerCase = Str[proto].toLowerCase, - math = Math, - mmax = math.max, - mmin = math.min, - abs = math.abs, - pow = math.pow, - PI = math.PI, - nu = "number", - string = "string", - array = "array", - toString = "toString", - fillString = "fill", - objectToString = Object[proto][toString], - paper = {}, - push = "push", - ISURL = /^url\(['"]?([^\)]+?)['"]?\)$/i, - colourRegExp = /^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?)%?\s*\))\s*$/i, - isnan = {"NaN": 1, "Infinity": 1, "-Infinity": 1}, - bezierrg = /^(?:cubic-)?bezier\(([^,]+),([^,]+),([^,]+),([^\)]+)\)/, - round = math.round, - setAttribute = "setAttribute", - toFloat = parseFloat, - toInt = parseInt, - ms = " progid:DXImageTransform.Microsoft", - upperCase = Str[proto].toUpperCase, - availableAttrs = {blur: 0, "clip-rect": "0 0 1e9 1e9", cursor: "default", cx: 0, cy: 0, fill: "#fff", "fill-opacity": 1, font: '10px "Arial"', "font-family": '"Arial"', "font-size": "10", "font-style": "normal", "font-weight": 400, gradient: 0, height: 0, href: "http://raphaeljs.com/", opacity: 1, path: "M0,0", r: 0, rotation: 0, rx: 0, ry: 0, scale: "1 1", src: "", stroke: "#000", "stroke-dasharray": "", "stroke-linecap": "butt", "stroke-linejoin": "butt", "stroke-miterlimit": 0, "stroke-opacity": 1, "stroke-width": 1, target: "_blank", "text-anchor": "middle", title: "Raphael", translation: "0 0", width: 0, x: 0, y: 0}, - availableAnimAttrs = {along: "along", blur: nu, "clip-rect": "csv", cx: nu, cy: nu, fill: "colour", "fill-opacity": nu, "font-size": nu, height: nu, opacity: nu, path: "path", r: nu, rotation: "csv", rx: nu, ry: nu, scale: "csv", stroke: "colour", "stroke-opacity": nu, "stroke-width": nu, translation: "csv", width: nu, x: nu, y: nu}, - rp = "replace", - animKeyFrames= /^(from|to|\d+%?)$/, - commaSpaces = /\s*,\s*/, - hsrg = {hs: 1, rg: 1}, - p2s = /,?([achlmqrstvxz]),?/gi, - pathCommand = /([achlmqstvz])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?\s*,?\s*)+)/ig, - pathValues = /(-?\d*\.?\d*(?:e[-+]?\d+)?)\s*,?\s*/ig, - radial_gradient = /^r(?:\(([^,]+?)\s*,\s*([^\)]+?)\))?/, - sortByKey = function (a, b) { - return a.key - b.key; - }; - - R.type = (win.SVGAngle || doc.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1") ? "SVG" : "VML"); - if (R.type == "VML") { - var d = doc.createElement("div"), - b; - d.innerHTML = ''; - b = d.firstChild; - b.style.behavior = "url(#default#VML)"; - if (!(b && typeof b.adj == "object")) { - return R.type = null; - } - d = null; - } - R.svg = !(R.vml = R.type == "VML"); - Paper[proto] = R[proto]; - paperproto = Paper[proto]; - R._id = 0; - R._oid = 0; - R.fn = {}; - R.is = function (o, type) { - type = lowerCase.call(type); - if (type == "finite") { - return !isnan[has](+o); - } - return (type == "null" && o === null) || - (type == typeof o) || - (type == "object" && o === Object(o)) || - (type == "array" && Array.isArray && Array.isArray(o)) || - objectToString.call(o).slice(8, -1).toLowerCase() == type; - }; - R.angle = function (x1, y1, x2, y2, x3, y3) { - if (x3 == null) { - var x = x1 - x2, - y = y1 - y2; - if (!x && !y) { - return 0; - } - return ((x < 0) * 180 + math.atan(-y / -x) * 180 / PI + 360) % 360; - } else { - return R.angle(x1, y1, x3, y3) - R.angle(x2, y2, x3, y3); - } - }; - R.rad = function (deg) { - return deg % 360 * PI / 180; - }; - R.deg = function (rad) { - return rad * 180 / PI % 360; - }; - R.snapTo = function (values, value, tolerance) { - tolerance = R.is(tolerance, "finite") ? tolerance : 10; - if (R.is(values, array)) { - var i = values.length; - while (i--) if (abs(values[i] - value) <= tolerance) { - return values[i]; - } - } else { - values = +values; - var rem = value % values; - if (rem < tolerance) { - return value - rem; - } - if (rem > values - tolerance) { - return value - rem + values; - } - } - return value; - }; - function createUUID() { - // http://www.ietf.org/rfc/rfc4122.txt - var s = [], - i = 0; - for (; i < 32; i++) { - s[i] = (~~(math.random() * 16))[toString](16); - } - s[12] = 4; // bits 12-15 of the time_hi_and_version field to 0010 - s[16] = ((s[16] & 3) | 8)[toString](16); // bits 6-7 of the clock_seq_hi_and_reserved to 01 - return "r-" + s[join](""); - } - - R.setWindow = function (newwin) { - win = newwin; - doc = win.document; - }; - // colour utilities - var toHex = function (color) { - if (R.vml) { - // http://dean.edwards.name/weblog/2009/10/convert-any-colour-value-to-hex-in-msie/ - var trim = /^\s+|\s+$/g; - var bod; - try { - var docum = new ActiveXObject("htmlfile"); - docum.write(""); - docum.close(); - bod = docum.body; - } catch(e) { - bod = createPopup().document.body; - } - var range = bod.createTextRange(); - toHex = cacher(function (color) { - try { - bod.style.color = Str(color)[rp](trim, E); - var value = range.queryCommandValue("ForeColor"); - value = ((value & 255) << 16) | (value & 65280) | ((value & 16711680) >>> 16); - return "#" + ("000000" + value[toString](16)).slice(-6); - } catch(e) { - return "none"; - } - }); - } else { - var i = doc.createElement("i"); - i.title = "Rapha\xebl Colour Picker"; - i.style.display = "none"; - doc.body[appendChild](i); - toHex = cacher(function (color) { - i.style.color = color; - return doc.defaultView.getComputedStyle(i, E).getPropertyValue("color"); - }); - } - return toHex(color); - }, - hsbtoString = function () { - return "hsb(" + [this.h, this.s, this.b] + ")"; - }, - hsltoString = function () { - return "hsl(" + [this.h, this.s, this.l] + ")"; - }, - rgbtoString = function () { - return this.hex; - }; - R.hsb2rgb = function (h, s, b, o) { - if (R.is(h, "object") && "h" in h && "s" in h && "b" in h) { - b = h.b; - s = h.s; - h = h.h; - o = h.o; - } - return R.hsl2rgb(h, s, b / 2, o); - }; - R.hsl2rgb = function (h, s, l, o) { - if (R.is(h, "object") && "h" in h && "s" in h && "l" in h) { - l = h.l; - s = h.s; - h = h.h; - } - if (h > 1 || s > 1 || l > 1) { - h /= 360; - s /= 100; - l /= 100; - } - var rgb = {}, - channels = ["r", "g", "b"], - t2, t1, t3, r, g, b; - if (!s) { - rgb = { - r: l, - g: l, - b: l - }; - } else { - if (l < .5) { - t2 = l * (1 + s); - } else { - t2 = l + s - l * s; - } - t1 = 2 * l - t2; - for (var i = 0; i < 3; i++) { - t3 = h + 1 / 3 * -(i - 1); - t3 < 0 && t3++; - t3 > 1 && t3--; - if (t3 * 6 < 1) { - rgb[channels[i]] = t1 + (t2 - t1) * 6 * t3; - } else if (t3 * 2 < 1) { - rgb[channels[i]] = t2; - } else if (t3 * 3 < 2) { - rgb[channels[i]] = t1 + (t2 - t1) * (2 / 3 - t3) * 6; - } else { - rgb[channels[i]] = t1; - } - } - } - rgb.r *= 255; - rgb.g *= 255; - rgb.b *= 255; - rgb.hex = "#" + (16777216 | rgb.b | (rgb.g << 8) | (rgb.r << 16)).toString(16).slice(1); - R.is(o, "finite") && (rgb.opacity = o); - rgb.toString = rgbtoString; - return rgb; - }; - R.rgb2hsb = function (red, green, blue) { - if (green == null && R.is(red, "object") && "r" in red && "g" in red && "b" in red) { - blue = red.b; - green = red.g; - red = red.r; - } - if (green == null && R.is(red, string)) { - var clr = R.getRGB(red); - red = clr.r; - green = clr.g; - blue = clr.b; - } - if (red > 1 || green > 1 || blue > 1) { - red /= 255; - green /= 255; - blue /= 255; - } - var max = mmax(red, green, blue), - min = mmin(red, green, blue), - hue, - saturation, - brightness = max; - if (min == max) { - return {h: 0, s: 0, b: max, toString: hsbtoString}; - } else { - var delta = (max - min); - saturation = delta / max; - if (red == max) { - hue = (green - blue) / delta; - } else if (green == max) { - hue = 2 + ((blue - red) / delta); - } else { - hue = 4 + ((red - green) / delta); - } - hue /= 6; - hue < 0 && hue++; - hue > 1 && hue--; - } - return {h: hue, s: saturation, b: brightness, toString: hsbtoString}; - }; - R.rgb2hsl = function (red, green, blue) { - if (green == null && R.is(red, "object") && "r" in red && "g" in red && "b" in red) { - blue = red.b; - green = red.g; - red = red.r; - } - if (green == null && R.is(red, string)) { - var clr = R.getRGB(red); - red = clr.r; - green = clr.g; - blue = clr.b; - } - if (red > 1 || green > 1 || blue > 1) { - red /= 255; - green /= 255; - blue /= 255; - } - var max = mmax(red, green, blue), - min = mmin(red, green, blue), - h, - s, - l = (max + min) / 2, - hsl; - if (min == max) { - hsl = {h: 0, s: 0, l: l}; - } else { - var delta = max - min; - s = l < .5 ? delta / (max + min) : delta / (2 - max - min); - if (red == max) { - h = (green - blue) / delta; - } else if (green == max) { - h = 2 + (blue - red) / delta; - } else { - h = 4 + (red - green) / delta; - } - h /= 6; - h < 0 && h++; - h > 1 && h--; - hsl = {h: h, s: s, l: l}; - } - hsl.toString = hsltoString; - return hsl; - }; - R._path2string = function () { - return this.join(",")[rp](p2s, "$1"); - }; - function cacher(f, scope, postprocessor) { - function newf() { - var arg = Array[proto].slice.call(arguments, 0), - args = arg[join]("\u25ba"), - cache = newf.cache = newf.cache || {}, - count = newf.count = newf.count || []; - if (cache[has](args)) { - return postprocessor ? postprocessor(cache[args]) : cache[args]; - } - count[length] >= 1e3 && delete cache[count.shift()]; - count[push](args); - cache[args] = f[apply](scope, arg); - return postprocessor ? postprocessor(cache[args]) : cache[args]; - } - return newf; - } - - R.getRGB = cacher(function (colour) { - if (!colour || !!((colour = Str(colour)).indexOf("-") + 1)) { - return {r: -1, g: -1, b: -1, hex: "none", error: 1}; - } - if (colour == "none") { - return {r: -1, g: -1, b: -1, hex: "none"}; - } - !(hsrg[has](colour.toLowerCase().substring(0, 2)) || colour.charAt() == "#") && (colour = toHex(colour)); - var res, - red, - green, - blue, - opacity, - t, - values, - rgb = colour.match(colourRegExp); - if (rgb) { - if (rgb[2]) { - blue = toInt(rgb[2].substring(5), 16); - green = toInt(rgb[2].substring(3, 5), 16); - red = toInt(rgb[2].substring(1, 3), 16); - } - if (rgb[3]) { - blue = toInt((t = rgb[3].charAt(3)) + t, 16); - green = toInt((t = rgb[3].charAt(2)) + t, 16); - red = toInt((t = rgb[3].charAt(1)) + t, 16); - } - if (rgb[4]) { - values = rgb[4][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - rgb[1].toLowerCase().slice(0, 4) == "rgba" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - } - if (rgb[5]) { - values = rgb[5][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); - rgb[1].toLowerCase().slice(0, 4) == "hsba" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - return R.hsb2rgb(red, green, blue, opacity); - } - if (rgb[6]) { - values = rgb[6][split](commaSpaces); - red = toFloat(values[0]); - values[0].slice(-1) == "%" && (red *= 2.55); - green = toFloat(values[1]); - values[1].slice(-1) == "%" && (green *= 2.55); - blue = toFloat(values[2]); - values[2].slice(-1) == "%" && (blue *= 2.55); - (values[0].slice(-3) == "deg" || values[0].slice(-1) == "\xb0") && (red /= 360); - rgb[1].toLowerCase().slice(0, 4) == "hsla" && (opacity = toFloat(values[3])); - values[3] && values[3].slice(-1) == "%" && (opacity /= 100); - return R.hsl2rgb(red, green, blue, opacity); - } - rgb = {r: red, g: green, b: blue}; - rgb.hex = "#" + (16777216 | blue | (green << 8) | (red << 16)).toString(16).slice(1); - R.is(opacity, "finite") && (rgb.opacity = opacity); - return rgb; - } - return {r: -1, g: -1, b: -1, hex: "none", error: 1}; - }, R); - R.getColor = function (value) { - var start = this.getColor.start = this.getColor.start || {h: 0, s: 1, b: value || .75}, - rgb = this.hsb2rgb(start.h, start.s, start.b); - start.h += .075; - if (start.h > 1) { - start.h = 0; - start.s -= .2; - start.s <= 0 && (this.getColor.start = {h: 0, s: 1, b: start.b}); - } - return rgb.hex; - }; - R.getColor.reset = function () { - delete this.start; - }; - // path utilities - R.parsePathString = cacher(function (pathString) { - if (!pathString) { - return null; - } - var paramCounts = {a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0}, - data = []; - if (R.is(pathString, array) && R.is(pathString[0], array)) { // rough assumption - data = pathClone(pathString); - } - if (!data[length]) { - Str(pathString)[rp](pathCommand, function (a, b, c) { - var params = [], - name = lowerCase.call(b); - c[rp](pathValues, function (a, b) { - b && params[push](+b); - }); - if (name == "m" && params[length] > 2) { - data[push]([b][concat](params.splice(0, 2))); - name = "l"; - b = b == "m" ? "l" : "L"; - } - while (params[length] >= paramCounts[name]) { - data[push]([b][concat](params.splice(0, paramCounts[name]))); - if (!paramCounts[name]) { - break; - } - } - }); - } - data[toString] = R._path2string; - return data; - }); - R.findDotsAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { - var t1 = 1 - t, - x = pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, - y = pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y, - mx = p1x + 2 * t * (c1x - p1x) + t * t * (c2x - 2 * c1x + p1x), - my = p1y + 2 * t * (c1y - p1y) + t * t * (c2y - 2 * c1y + p1y), - nx = c1x + 2 * t * (c2x - c1x) + t * t * (p2x - 2 * c2x + c1x), - ny = c1y + 2 * t * (c2y - c1y) + t * t * (p2y - 2 * c2y + c1y), - ax = (1 - t) * p1x + t * c1x, - ay = (1 - t) * p1y + t * c1y, - cx = (1 - t) * c2x + t * p2x, - cy = (1 - t) * c2y + t * p2y, - alpha = (90 - math.atan((mx - nx) / (my - ny)) * 180 / PI); - (mx > nx || my < ny) && (alpha += 180); - return {x: x, y: y, m: {x: mx, y: my}, n: {x: nx, y: ny}, start: {x: ax, y: ay}, end: {x: cx, y: cy}, alpha: alpha}; - }; - var pathDimensions = cacher(function (path) { - if (!path) { - return {x: 0, y: 0, width: 0, height: 0}; - } - path = path2curve(path); - var x = 0, - y = 0, - X = [], - Y = [], - p; - for (var i = 0, ii = path[length]; i < ii; i++) { - p = path[i]; - if (p[0] == "M") { - x = p[1]; - y = p[2]; - X[push](x); - Y[push](y); - } else { - var dim = curveDim(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); - X = X[concat](dim.min.x, dim.max.x); - Y = Y[concat](dim.min.y, dim.max.y); - x = p[5]; - y = p[6]; - } - } - var xmin = mmin[apply](0, X), - ymin = mmin[apply](0, Y); - return { - x: xmin, - y: ymin, - width: mmax[apply](0, X) - xmin, - height: mmax[apply](0, Y) - ymin - }; - }), - pathClone = function (pathArray) { - var res = []; - if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption - pathArray = R.parsePathString(pathArray); - } - for (var i = 0, ii = pathArray[length]; i < ii; i++) { - res[i] = []; - for (var j = 0, jj = pathArray[i][length]; j < jj; j++) { - res[i][j] = pathArray[i][j]; - } - } - res[toString] = R._path2string; - return res; - }, - pathToRelative = cacher(function (pathArray) { - if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption - pathArray = R.parsePathString(pathArray); - } - var res = [], - x = 0, - y = 0, - mx = 0, - my = 0, - start = 0; - if (pathArray[0][0] == "M") { - x = pathArray[0][1]; - y = pathArray[0][2]; - mx = x; - my = y; - start++; - res[push](["M", x, y]); - } - for (var i = start, ii = pathArray[length]; i < ii; i++) { - var r = res[i] = [], - pa = pathArray[i]; - if (pa[0] != lowerCase.call(pa[0])) { - r[0] = lowerCase.call(pa[0]); - switch (r[0]) { - case "a": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] - x).toFixed(3); - r[7] = +(pa[7] - y).toFixed(3); - break; - case "v": - r[1] = +(pa[1] - y).toFixed(3); - break; - case "m": - mx = pa[1]; - my = pa[2]; - default: - for (var j = 1, jj = pa[length]; j < jj; j++) { - r[j] = +(pa[j] - ((j % 2) ? x : y)).toFixed(3); - } - } - } else { - r = res[i] = []; - if (pa[0] == "m") { - mx = pa[1] + x; - my = pa[2] + y; - } - for (var k = 0, kk = pa[length]; k < kk; k++) { - res[i][k] = pa[k]; - } - } - var len = res[i][length]; - switch (res[i][0]) { - case "z": - x = mx; - y = my; - break; - case "h": - x += +res[i][len - 1]; - break; - case "v": - y += +res[i][len - 1]; - break; - default: - x += +res[i][len - 2]; - y += +res[i][len - 1]; - } - } - res[toString] = R._path2string; - return res; - }, 0, pathClone), - pathToAbsolute = cacher(function (pathArray) { - if (!R.is(pathArray, array) || !R.is(pathArray && pathArray[0], array)) { // rough assumption - pathArray = R.parsePathString(pathArray); - } - var res = [], - x = 0, - y = 0, - mx = 0, - my = 0, - start = 0; - if (pathArray[0][0] == "M") { - x = +pathArray[0][1]; - y = +pathArray[0][2]; - mx = x; - my = y; - start++; - res[0] = ["M", x, y]; - } - for (var i = start, ii = pathArray[length]; i < ii; i++) { - var r = res[i] = [], - pa = pathArray[i]; - if (pa[0] != upperCase.call(pa[0])) { - r[0] = upperCase.call(pa[0]); - switch (r[0]) { - case "A": - r[1] = pa[1]; - r[2] = pa[2]; - r[3] = pa[3]; - r[4] = pa[4]; - r[5] = pa[5]; - r[6] = +(pa[6] + x); - r[7] = +(pa[7] + y); - break; - case "V": - r[1] = +pa[1] + y; - break; - case "H": - r[1] = +pa[1] + x; - break; - case "M": - mx = +pa[1] + x; - my = +pa[2] + y; - default: - for (var j = 1, jj = pa[length]; j < jj; j++) { - r[j] = +pa[j] + ((j % 2) ? x : y); - } - } - } else { - for (var k = 0, kk = pa[length]; k < kk; k++) { - res[i][k] = pa[k]; - } - } - switch (r[0]) { - case "Z": - x = mx; - y = my; - break; - case "H": - x = r[1]; - break; - case "V": - y = r[1]; - break; - case "M": - mx = res[i][res[i][length] - 2]; - my = res[i][res[i][length] - 1]; - default: - x = res[i][res[i][length] - 2]; - y = res[i][res[i][length] - 1]; - } - } - res[toString] = R._path2string; - return res; - }, null, pathClone), - l2c = function (x1, y1, x2, y2) { - return [x1, y1, x2, y2, x2, y2]; - }, - q2c = function (x1, y1, ax, ay, x2, y2) { - var _13 = 1 / 3, - _23 = 2 / 3; - return [ - _13 * x1 + _23 * ax, - _13 * y1 + _23 * ay, - _13 * x2 + _23 * ax, - _13 * y2 + _23 * ay, - x2, - y2 - ]; - }, - a2c = function (x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { - // for more information of where this math came from visit: - // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - var _120 = PI * 120 / 180, - rad = PI / 180 * (+angle || 0), - res = [], - xy, - rotate = cacher(function (x, y, rad) { - var X = x * math.cos(rad) - y * math.sin(rad), - Y = x * math.sin(rad) + y * math.cos(rad); - return {x: X, y: Y}; - }); - if (!recursive) { - xy = rotate(x1, y1, -rad); - x1 = xy.x; - y1 = xy.y; - xy = rotate(x2, y2, -rad); - x2 = xy.x; - y2 = xy.y; - var cos = math.cos(PI / 180 * angle), - sin = math.sin(PI / 180 * angle), - x = (x1 - x2) / 2, - y = (y1 - y2) / 2; - var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); - if (h > 1) { - h = math.sqrt(h); - rx = h * rx; - ry = h * ry; - } - var rx2 = rx * rx, - ry2 = ry * ry, - k = (large_arc_flag == sweep_flag ? -1 : 1) * - math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), - cx = k * rx * y / ry + (x1 + x2) / 2, - cy = k * -ry * x / rx + (y1 + y2) / 2, - f1 = math.asin(((y1 - cy) / ry).toFixed(9)), - f2 = math.asin(((y2 - cy) / ry).toFixed(9)); - - f1 = x1 < cx ? PI - f1 : f1; - f2 = x2 < cx ? PI - f2 : f2; - f1 < 0 && (f1 = PI * 2 + f1); - f2 < 0 && (f2 = PI * 2 + f2); - if (sweep_flag && f1 > f2) { - f1 = f1 - PI * 2; - } - if (!sweep_flag && f2 > f1) { - f2 = f2 - PI * 2; - } - } else { - f1 = recursive[0]; - f2 = recursive[1]; - cx = recursive[2]; - cy = recursive[3]; - } - var df = f2 - f1; - if (abs(df) > _120) { - var f2old = f2, - x2old = x2, - y2old = y2; - f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); - x2 = cx + rx * math.cos(f2); - y2 = cy + ry * math.sin(f2); - res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); - } - df = f2 - f1; - var c1 = math.cos(f1), - s1 = math.sin(f1), - c2 = math.cos(f2), - s2 = math.sin(f2), - t = math.tan(df / 4), - hx = 4 / 3 * rx * t, - hy = 4 / 3 * ry * t, - m1 = [x1, y1], - m2 = [x1 + hx * s1, y1 - hy * c1], - m3 = [x2 + hx * s2, y2 - hy * c2], - m4 = [x2, y2]; - m2[0] = 2 * m1[0] - m2[0]; - m2[1] = 2 * m1[1] - m2[1]; - if (recursive) { - return [m2, m3, m4][concat](res); - } else { - res = [m2, m3, m4][concat](res)[join]()[split](","); - var newres = []; - for (var i = 0, ii = res[length]; i < ii; i++) { - newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; - } - return newres; - } - }, - findDotAtSegment = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { - var t1 = 1 - t; - return { - x: pow(t1, 3) * p1x + pow(t1, 2) * 3 * t * c1x + t1 * 3 * t * t * c2x + pow(t, 3) * p2x, - y: pow(t1, 3) * p1y + pow(t1, 2) * 3 * t * c1y + t1 * 3 * t * t * c2y + pow(t, 3) * p2y - }; - }, - curveDim = cacher(function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) { - var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x), - b = 2 * (c1x - p1x) - 2 * (c2x - c1x), - c = p1x - c1x, - t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a, - t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a, - y = [p1y, p2y], - x = [p1x, p2x], - dot; - abs(t1) > "1e12" && (t1 = .5); - abs(t2) > "1e12" && (t2 = .5); - if (t1 > 0 && t1 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); - x[push](dot.x); - y[push](dot.y); - } - if (t2 > 0 && t2 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); - x[push](dot.x); - y[push](dot.y); - } - a = (c2y - 2 * c1y + p1y) - (p2y - 2 * c2y + c1y); - b = 2 * (c1y - p1y) - 2 * (c2y - c1y); - c = p1y - c1y; - t1 = (-b + math.sqrt(b * b - 4 * a * c)) / 2 / a; - t2 = (-b - math.sqrt(b * b - 4 * a * c)) / 2 / a; - abs(t1) > "1e12" && (t1 = .5); - abs(t2) > "1e12" && (t2 = .5); - if (t1 > 0 && t1 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t1); - x[push](dot.x); - y[push](dot.y); - } - if (t2 > 0 && t2 < 1) { - dot = findDotAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t2); - x[push](dot.x); - y[push](dot.y); - } - return { - min: {x: mmin[apply](0, x), y: mmin[apply](0, y)}, - max: {x: mmax[apply](0, x), y: mmax[apply](0, y)} - }; - }), - path2curve = cacher(function (path, path2) { - var p = pathToAbsolute(path), - p2 = path2 && pathToAbsolute(path2), - attrs = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, - attrs2 = {x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null}, - processPath = function (path, d) { - var nx, ny; - if (!path) { - return ["C", d.x, d.y, d.x, d.y, d.x, d.y]; - } - !(path[0] in {T:1, Q:1}) && (d.qx = d.qy = null); - switch (path[0]) { - case "M": - d.X = path[1]; - d.Y = path[2]; - break; - case "A": - path = ["C"][concat](a2c[apply](0, [d.x, d.y][concat](path.slice(1)))); - break; - case "S": - nx = d.x + (d.x - (d.bx || d.x)); - ny = d.y + (d.y - (d.by || d.y)); - path = ["C", nx, ny][concat](path.slice(1)); - break; - case "T": - d.qx = d.x + (d.x - (d.qx || d.x)); - d.qy = d.y + (d.y - (d.qy || d.y)); - path = ["C"][concat](q2c(d.x, d.y, d.qx, d.qy, path[1], path[2])); - break; - case "Q": - d.qx = path[1]; - d.qy = path[2]; - path = ["C"][concat](q2c(d.x, d.y, path[1], path[2], path[3], path[4])); - break; - case "L": - path = ["C"][concat](l2c(d.x, d.y, path[1], path[2])); - break; - case "H": - path = ["C"][concat](l2c(d.x, d.y, path[1], d.y)); - break; - case "V": - path = ["C"][concat](l2c(d.x, d.y, d.x, path[1])); - break; - case "Z": - path = ["C"][concat](l2c(d.x, d.y, d.X, d.Y)); - break; - } - return path; - }, - fixArc = function (pp, i) { - if (pp[i][length] > 7) { - pp[i].shift(); - var pi = pp[i]; - while (pi[length]) { - pp.splice(i++, 0, ["C"][concat](pi.splice(0, 6))); - } - pp.splice(i, 1); - ii = mmax(p[length], p2 && p2[length] || 0); - } - }, - fixM = function (path1, path2, a1, a2, i) { - if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") { - path2.splice(i, 0, ["M", a2.x, a2.y]); - a1.bx = 0; - a1.by = 0; - a1.x = path1[i][1]; - a1.y = path1[i][2]; - ii = mmax(p[length], p2 && p2[length] || 0); - } - }; - for (var i = 0, ii = mmax(p[length], p2 && p2[length] || 0); i < ii; i++) { - p[i] = processPath(p[i], attrs); - fixArc(p, i); - p2 && (p2[i] = processPath(p2[i], attrs2)); - p2 && fixArc(p2, i); - fixM(p, p2, attrs, attrs2, i); - fixM(p2, p, attrs2, attrs, i); - var seg = p[i], - seg2 = p2 && p2[i], - seglen = seg[length], - seg2len = p2 && seg2[length]; - attrs.x = seg[seglen - 2]; - attrs.y = seg[seglen - 1]; - attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; - attrs.by = toFloat(seg[seglen - 3]) || attrs.y; - attrs2.bx = p2 && (toFloat(seg2[seg2len - 4]) || attrs2.x); - attrs2.by = p2 && (toFloat(seg2[seg2len - 3]) || attrs2.y); - attrs2.x = p2 && seg2[seg2len - 2]; - attrs2.y = p2 && seg2[seg2len - 1]; - } - return p2 ? [p, p2] : p; - }, null, pathClone), - parseDots = cacher(function (gradient) { - var dots = []; - for (var i = 0, ii = gradient[length]; i < ii; i++) { - var dot = {}, - par = gradient[i].match(/^([^:]*):?([\d\.]*)/); - dot.color = R.getRGB(par[1]); - if (dot.color.error) { - return null; - } - dot.color = dot.color.hex; - par[2] && (dot.offset = par[2] + "%"); - dots[push](dot); - } - for (i = 1, ii = dots[length] - 1; i < ii; i++) { - if (!dots[i].offset) { - var start = toFloat(dots[i - 1].offset || 0), - end = 0; - for (var j = i + 1; j < ii; j++) { - if (dots[j].offset) { - end = dots[j].offset; - break; - } - } - if (!end) { - end = 100; - j = ii; - } - end = toFloat(end); - var d = (end - start) / (j - i + 1); - for (; i < j; i++) { - start += d; - dots[i].offset = start + "%"; - } - } - } - return dots; - }), - getContainer = function (x, y, w, h) { - var container; - if (R.is(x, string) || R.is(x, "object")) { - container = R.is(x, string) ? doc.getElementById(x) : x; - if (container.tagName) { - if (y == null) { - return { - container: container, - width: container.style.pixelWidth || container.offsetWidth, - height: container.style.pixelHeight || container.offsetHeight - }; - } else { - return {container: container, width: y, height: w}; - } - } - } else { - return {container: 1, x: x, y: y, width: w, height: h}; - } - }, - plugins = function (con, add) { - var that = this; - for (var prop in add) { - if (add[has](prop) && !(prop in con)) { - switch (typeof add[prop]) { - case "function": - (function (f) { - con[prop] = con === that ? f : function () { return f[apply](that, arguments); }; - })(add[prop]); - break; - case "object": - con[prop] = con[prop] || {}; - plugins.call(this, con[prop], add[prop]); - break; - default: - con[prop] = add[prop]; - break; - } - } - } - }, - tear = function (el, paper) { - el == paper.top && (paper.top = el.prev); - el == paper.bottom && (paper.bottom = el.next); - el.next && (el.next.prev = el.prev); - el.prev && (el.prev.next = el.next); - }, - tofront = function (el, paper) { - if (paper.top === el) { - return; - } - tear(el, paper); - el.next = null; - el.prev = paper.top; - paper.top.next = el; - paper.top = el; - }, - toback = function (el, paper) { - if (paper.bottom === el) { - return; - } - tear(el, paper); - el.next = paper.bottom; - el.prev = null; - paper.bottom.prev = el; - paper.bottom = el; - }, - insertafter = function (el, el2, paper) { - tear(el, paper); - el2 == paper.top && (paper.top = el); - el2.next && (el2.next.prev = el); - el.next = el2.next; - el.prev = el2; - el2.next = el; - }, - insertbefore = function (el, el2, paper) { - tear(el, paper); - el2 == paper.bottom && (paper.bottom = el); - el2.prev && (el2.prev.next = el); - el.prev = el2.prev; - el2.prev = el; - el.next = el2; - }, - removed = function (methodname) { - return function () { - throw new Error("Rapha\xebl: you are calling to method \u201c" + methodname + "\u201d of removed object"); - }; - }; - R.pathToRelative = pathToRelative; - // SVG - if (R.svg) { - paperproto.svgns = "http://www.w3.org/2000/svg"; - paperproto.xlink = "http://www.w3.org/1999/xlink"; - round = function (num) { - return +num + (~~num === num) * .5; - }; - var $ = function (el, attr) { - if (attr) { - for (var key in attr) { - if (attr[has](key)) { - el[setAttribute](key, Str(attr[key])); - } - } - } else { - el = doc.createElementNS(paperproto.svgns, el); - el.style.webkitTapHighlightColor = "rgba(0,0,0,0)"; - return el; - } - }; - R[toString] = function () { - return "Your browser supports SVG.\nYou are running Rapha\xebl " + this.version; - }; - var thePath = function (pathString, SVG) { - var el = $("path"); - SVG.canvas && SVG.canvas[appendChild](el); - var p = new Element(el, SVG); - p.type = "path"; - setFillAndStroke(p, {fill: "none", stroke: "#000", path: pathString}); - return p; - }; - var addGradientFill = function (o, gradient, SVG) { - var type = "linear", - fx = .5, fy = .5, - s = o.style; - gradient = Str(gradient)[rp](radial_gradient, function (all, _fx, _fy) { - type = "radial"; - if (_fx && _fy) { - fx = toFloat(_fx); - fy = toFloat(_fy); - var dir = ((fy > .5) * 2 - 1); - pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && - (fy = math.sqrt(.25 - pow(fx - .5, 2)) * dir + .5) && - fy != .5 && - (fy = fy.toFixed(5) - 1e-5 * dir); - } - return E; - }); - gradient = gradient[split](/\s*\-\s*/); - if (type == "linear") { - var angle = gradient.shift(); - angle = -toFloat(angle); - if (isNaN(angle)) { - return null; - } - var vector = [0, 0, math.cos(angle * PI / 180), math.sin(angle * PI / 180)], - max = 1 / (mmax(abs(vector[2]), abs(vector[3])) || 1); - vector[2] *= max; - vector[3] *= max; - if (vector[2] < 0) { - vector[0] = -vector[2]; - vector[2] = 0; - } - if (vector[3] < 0) { - vector[1] = -vector[3]; - vector[3] = 0; - } - } - var dots = parseDots(gradient); - if (!dots) { - return null; - } - var id = o.getAttribute(fillString); - id = id.match(/^url\(#(.*)\)$/); - id && SVG.defs.removeChild(doc.getElementById(id[1])); - - var el = $(type + "Gradient"); - el.id = createUUID(); - $(el, type == "radial" ? {fx: fx, fy: fy} : {x1: vector[0], y1: vector[1], x2: vector[2], y2: vector[3]}); - SVG.defs[appendChild](el); - for (var i = 0, ii = dots[length]; i < ii; i++) { - var stop = $("stop"); - $(stop, { - offset: dots[i].offset ? dots[i].offset : !i ? "0%" : "100%", - "stop-color": dots[i].color || "#fff" - }); - el[appendChild](stop); - } - $(o, { - fill: "url(#" + el.id + ")", - opacity: 1, - "fill-opacity": 1 - }); - s.fill = E; - s.opacity = 1; - s.fillOpacity = 1; - return 1; - }; - var updatePosition = function (o) { - var bbox = o.getBBox(); - $(o.pattern, {patternTransform: R.format("translate({0},{1})", bbox.x, bbox.y)}); - }; - var setFillAndStroke = function (o, params) { - var dasharray = { - "": [0], - "none": [0], - "-": [3, 1], - ".": [1, 1], - "-.": [3, 1, 1, 1], - "-..": [3, 1, 1, 1, 1, 1], - ". ": [1, 3], - "- ": [4, 3], - "--": [8, 3], - "- .": [4, 3, 1, 3], - "--.": [8, 3, 1, 3], - "--..": [8, 3, 1, 3, 1, 3] - }, - node = o.node, - attrs = o.attrs, - rot = o.rotate(), - addDashes = function (o, value) { - value = dasharray[lowerCase.call(value)]; - if (value) { - var width = o.attrs["stroke-width"] || "1", - butt = {round: width, square: width, butt: 0}[o.attrs["stroke-linecap"] || params["stroke-linecap"]] || 0, - dashes = []; - var i = value[length]; - while (i--) { - dashes[i] = value[i] * width + ((i % 2) ? 1 : -1) * butt; - } - $(node, {"stroke-dasharray": dashes[join](",")}); - } - }; - params[has]("rotation") && (rot = params.rotation); - var rotxy = Str(rot)[split](separator); - if (!(rotxy.length - 1)) { - rotxy = null; - } else { - rotxy[1] = +rotxy[1]; - rotxy[2] = +rotxy[2]; - } - toFloat(rot) && o.rotate(0, true); - for (var att in params) { - if (params[has](att)) { - if (!availableAttrs[has](att)) { - continue; - } - var value = params[att]; - attrs[att] = value; - switch (att) { - case "blur": - o.blur(value); - break; - case "rotation": - o.rotate(value, true); - break; - case "href": - case "title": - case "target": - var pn = node.parentNode; - if (lowerCase.call(pn.tagName) != "a") { - var hl = $("a"); - pn.insertBefore(hl, node); - hl[appendChild](node); - pn = hl; - } - if (att == "target" && value == "blank") { - pn.setAttributeNS(o.paper.xlink, "show", "new"); - } else { - pn.setAttributeNS(o.paper.xlink, att, value); - } - break; - case "cursor": - node.style.cursor = value; - break; - case "clip-rect": - var rect = Str(value)[split](separator); - if (rect[length] == 4) { - o.clip && o.clip.parentNode.parentNode.removeChild(o.clip.parentNode); - var el = $("clipPath"), - rc = $("rect"); - el.id = createUUID(); - $(rc, { - x: rect[0], - y: rect[1], - width: rect[2], - height: rect[3] - }); - el[appendChild](rc); - o.paper.defs[appendChild](el); - $(node, {"clip-path": "url(#" + el.id + ")"}); - o.clip = rc; - } - if (!value) { - var clip = doc.getElementById(node.getAttribute("clip-path")[rp](/(^url\(#|\)$)/g, E)); - clip && clip.parentNode.removeChild(clip); - $(node, {"clip-path": E}); - delete o.clip; - } - break; - case "path": - if (o.type == "path") { - $(node, {d: value ? attrs.path = pathToAbsolute(value) : "M0,0"}); - } - break; - case "width": - node[setAttribute](att, value); - if (attrs.fx) { - att = "x"; - value = attrs.x; - } else { - break; - } - case "x": - if (attrs.fx) { - value = -attrs.x - (attrs.width || 0); - } - case "rx": - if (att == "rx" && o.type == "rect") { - break; - } - case "cx": - rotxy && (att == "x" || att == "cx") && (rotxy[1] += value - attrs[att]); - node[setAttribute](att, value); - o.pattern && updatePosition(o); - break; - case "height": - node[setAttribute](att, value); - if (attrs.fy) { - att = "y"; - value = attrs.y; - } else { - break; - } - case "y": - if (attrs.fy) { - value = -attrs.y - (attrs.height || 0); - } - case "ry": - if (att == "ry" && o.type == "rect") { - break; - } - case "cy": - rotxy && (att == "y" || att == "cy") && (rotxy[2] += value - attrs[att]); - node[setAttribute](att, value); - o.pattern && updatePosition(o); - break; - case "r": - if (o.type == "rect") { - $(node, {rx: value, ry: value}); - } else { - node[setAttribute](att, value); - } - break; - case "src": - if (o.type == "image") { - node.setAttributeNS(o.paper.xlink, "href", value); - } - break; - case "stroke-width": - node.style.strokeWidth = value; - // Need following line for Firefox - node[setAttribute](att, value); - if (attrs["stroke-dasharray"]) { - addDashes(o, attrs["stroke-dasharray"]); - } - break; - case "stroke-dasharray": - addDashes(o, value); - break; - case "translation": - var xy = Str(value)[split](separator); - xy[0] = +xy[0] || 0; - xy[1] = +xy[1] || 0; - if (rotxy) { - rotxy[1] += xy[0]; - rotxy[2] += xy[1]; - } - translate.call(o, xy[0], xy[1]); - break; - case "scale": - xy = Str(value)[split](separator); - o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, isNaN(toFloat(xy[2])) ? null : +xy[2], isNaN(toFloat(xy[3])) ? null : +xy[3]); - break; - case fillString: - var isURL = Str(value).match(ISURL); - if (isURL) { - el = $("pattern"); - var ig = $("image"); - el.id = createUUID(); - $(el, {x: 0, y: 0, patternUnits: "userSpaceOnUse", height: 1, width: 1}); - $(ig, {x: 0, y: 0}); - ig.setAttributeNS(o.paper.xlink, "href", isURL[1]); - el[appendChild](ig); - - var img = doc.createElement("img"); - img.style.cssText = "position:absolute;left:-9999em;top-9999em"; - img.onload = function () { - $(el, {width: this.offsetWidth, height: this.offsetHeight}); - $(ig, {width: this.offsetWidth, height: this.offsetHeight}); - doc.body.removeChild(this); - o.paper.safari(); - }; - doc.body[appendChild](img); - img.src = isURL[1]; - o.paper.defs[appendChild](el); - node.style.fill = "url(#" + el.id + ")"; - $(node, {fill: "url(#" + el.id + ")"}); - o.pattern = el; - o.pattern && updatePosition(o); - break; - } - var clr = R.getRGB(value); - if (!clr.error) { - delete params.gradient; - delete attrs.gradient; - !R.is(attrs.opacity, "undefined") && - R.is(params.opacity, "undefined") && - $(node, {opacity: attrs.opacity}); - !R.is(attrs["fill-opacity"], "undefined") && - R.is(params["fill-opacity"], "undefined") && - $(node, {"fill-opacity": attrs["fill-opacity"]}); - } else if ((({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != "r") && addGradientFill(node, value, o.paper)) { - attrs.gradient = value; - attrs.fill = "none"; - break; - } - clr[has]("opacity") && $(node, {"fill-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); - case "stroke": - clr = R.getRGB(value); - node[setAttribute](att, clr.hex); - att == "stroke" && clr[has]("opacity") && $(node, {"stroke-opacity": clr.opacity > 1 ? clr.opacity / 100 : clr.opacity}); - break; - case "gradient": - (({circle: 1, ellipse: 1})[has](o.type) || Str(value).charAt() != "r") && addGradientFill(node, value, o.paper); - break; - case "opacity": - if (attrs.gradient && !attrs[has]("stroke-opacity")) { - $(node, {"stroke-opacity": value > 1 ? value / 100 : value}); - } - // fall - case "fill-opacity": - if (attrs.gradient) { - var gradient = doc.getElementById(node.getAttribute(fillString)[rp](/^url\(#|\)$/g, E)); - if (gradient) { - var stops = gradient.getElementsByTagName("stop"); - stops[stops[length] - 1][setAttribute]("stop-opacity", value); - } - break; - } - default: - att == "font-size" && (value = toInt(value, 10) + "px"); - var cssrule = att[rp](/(\-.)/g, function (w) { - return upperCase.call(w.substring(1)); - }); - node.style[cssrule] = value; - // Need following line for Firefox - node[setAttribute](att, value); - break; - } - } - } - - tuneText(o, params); - if (rotxy) { - o.rotate(rotxy.join(S)); - } else { - toFloat(rot) && o.rotate(rot, true); - } - }; - var leading = 1.2, - tuneText = function (el, params) { - if (el.type != "text" || !(params[has]("text") || params[has]("font") || params[has]("font-size") || params[has]("x") || params[has]("y"))) { - return; - } - var a = el.attrs, - node = el.node, - fontSize = node.firstChild ? toInt(doc.defaultView.getComputedStyle(node.firstChild, E).getPropertyValue("font-size"), 10) : 10; - - if (params[has]("text")) { - a.text = params.text; - while (node.firstChild) { - node.removeChild(node.firstChild); - } - var texts = Str(params.text)[split]("\n"); - for (var i = 0, ii = texts[length]; i < ii; i++) if (texts[i]) { - var tspan = $("tspan"); - i && $(tspan, {dy: fontSize * leading, x: a.x}); - tspan[appendChild](doc.createTextNode(texts[i])); - node[appendChild](tspan); - } - } else { - texts = node.getElementsByTagName("tspan"); - for (i = 0, ii = texts[length]; i < ii; i++) { - i && $(texts[i], {dy: fontSize * leading, x: a.x}); - } - } - $(node, {y: a.y}); - var bb = el.getBBox(), - dif = a.y - (bb.y + bb.height / 2); - dif && R.is(dif, "finite") && $(node, {y: a.y + dif}); - }, - Element = function (node, svg) { - var X = 0, - Y = 0; - this[0] = node; - this.id = R._oid++; - this.node = node; - node.raphael = this; - this.paper = svg; - this.attrs = this.attrs || {}; - this.transformations = []; // rotate, translate, scale - this._ = { - tx: 0, - ty: 0, - rt: {deg: 0, cx: 0, cy: 0}, - sx: 1, - sy: 1 - }; - !svg.bottom && (svg.bottom = this); - this.prev = svg.top; - svg.top && (svg.top.next = this); - svg.top = this; - this.next = null; - }; - var elproto = Element[proto]; - Element[proto].rotate = function (deg, cx, cy) { - if (this.removed) { - return this; - } - if (deg == null) { - if (this._.rt.cx) { - return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S); - } - return this._.rt.deg; - } - var bbox = this.getBBox(); - deg = Str(deg)[split](separator); - if (deg[length] - 1) { - cx = toFloat(deg[1]); - cy = toFloat(deg[2]); - } - deg = toFloat(deg[0]); - if (cx != null && cx !== false) { - this._.rt.deg = deg; - } else { - this._.rt.deg += deg; - } - (cy == null) && (cx = null); - this._.rt.cx = cx; - this._.rt.cy = cy; - cx = cx == null ? bbox.x + bbox.width / 2 : cx; - cy = cy == null ? bbox.y + bbox.height / 2 : cy; - if (this._.rt.deg) { - this.transformations[0] = R.format("rotate({0} {1} {2})", this._.rt.deg, cx, cy); - this.clip && $(this.clip, {transform: R.format("rotate({0} {1} {2})", -this._.rt.deg, cx, cy)}); - } else { - this.transformations[0] = E; - this.clip && $(this.clip, {transform: E}); - } - $(this.node, {transform: this.transformations[join](S)}); - return this; - }; - Element[proto].hide = function () { - !this.removed && (this.node.style.display = "none"); - return this; - }; - Element[proto].show = function () { - !this.removed && (this.node.style.display = ""); - return this; - }; - Element[proto].remove = function () { - if (this.removed) { - return; - } - tear(this, this.paper); - this.node.parentNode.removeChild(this.node); - for (var i in this) { - delete this[i]; - } - this.removed = true; - }; - Element[proto].getBBox = function () { - if (this.removed) { - return this; - } - if (this.type == "path") { - return pathDimensions(this.attrs.path); - } - if (this.node.style.display == "none") { - this.show(); - var hide = true; - } - var bbox = {}; - try { - bbox = this.node.getBBox(); - } catch(e) { - // Firefox 3.0.x plays badly here - } finally { - bbox = bbox || {}; - } - if (this.type == "text") { - bbox = {x: bbox.x, y: Infinity, width: 0, height: 0}; - for (var i = 0, ii = this.node.getNumberOfChars(); i < ii; i++) { - var bb = this.node.getExtentOfChar(i); - (bb.y < bbox.y) && (bbox.y = bb.y); - (bb.y + bb.height - bbox.y > bbox.height) && (bbox.height = bb.y + bb.height - bbox.y); - (bb.x + bb.width - bbox.x > bbox.width) && (bbox.width = bb.x + bb.width - bbox.x); - } - } - hide && this.hide(); - return bbox; - }; - Element[proto].attr = function (name, value) { - if (this.removed) { - return this; - } - if (name == null) { - var res = {}; - for (var i in this.attrs) if (this.attrs[has](i)) { - res[i] = this.attrs[i]; - } - this._.rt.deg && (res.rotation = this.rotate()); - (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale()); - res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; - return res; - } - if (value == null && R.is(name, string)) { - if (name == "translation") { - return translate.call(this); - } - if (name == "rotation") { - return this.rotate(); - } - if (name == "scale") { - return this.scale(); - } - if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) { - return this.attrs.gradient; - } - return this.attrs[name]; - } - if (value == null && R.is(name, array)) { - var values = {}; - for (var j = 0, jj = name.length; j < jj; j++) { - values[name[j]] = this.attr(name[j]); - } - return values; - } - if (value != null) { - var params = {}; - params[name] = value; - } else if (name != null && R.is(name, "object")) { - params = name; - } - for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { - var par = this.paper.customAttributes[key].apply(this, [][concat](params[key])); - this.attrs[key] = params[key]; - for (var subkey in par) if (par[has](subkey)) { - params[subkey] = par[subkey]; - } - } - setFillAndStroke(this, params); - return this; - }; - Element[proto].toFront = function () { - if (this.removed) { - return this; - } - this.node.parentNode[appendChild](this.node); - var svg = this.paper; - svg.top != this && tofront(this, svg); - return this; - }; - Element[proto].toBack = function () { - if (this.removed) { - return this; - } - if (this.node.parentNode.firstChild != this.node) { - this.node.parentNode.insertBefore(this.node, this.node.parentNode.firstChild); - toback(this, this.paper); - var svg = this.paper; - } - return this; - }; - Element[proto].insertAfter = function (element) { - if (this.removed) { - return this; - } - var node = element.node || element[element.length - 1].node; - if (node.nextSibling) { - node.parentNode.insertBefore(this.node, node.nextSibling); - } else { - node.parentNode[appendChild](this.node); - } - insertafter(this, element, this.paper); - return this; - }; - Element[proto].insertBefore = function (element) { - if (this.removed) { - return this; - } - var node = element.node || element[0].node; - node.parentNode.insertBefore(this.node, node); - insertbefore(this, element, this.paper); - return this; - }; - Element[proto].blur = function (size) { - // Experimental. No Safari support. Use it on your own risk. - var t = this; - if (+size !== 0) { - var fltr = $("filter"), - blur = $("feGaussianBlur"); - t.attrs.blur = size; - fltr.id = createUUID(); - $(blur, {stdDeviation: +size || 1.5}); - fltr.appendChild(blur); - t.paper.defs.appendChild(fltr); - t._blur = fltr; - $(t.node, {filter: "url(#" + fltr.id + ")"}); - } else { - if (t._blur) { - t._blur.parentNode.removeChild(t._blur); - delete t._blur; - delete t.attrs.blur; - } - t.node.removeAttribute("filter"); - } - }; - var theCircle = function (svg, x, y, r) { - var el = $("circle"); - svg.canvas && svg.canvas[appendChild](el); - var res = new Element(el, svg); - res.attrs = {cx: x, cy: y, r: r, fill: "none", stroke: "#000"}; - res.type = "circle"; - $(el, res.attrs); - return res; - }, - theRect = function (svg, x, y, w, h, r) { - var el = $("rect"); - svg.canvas && svg.canvas[appendChild](el); - var res = new Element(el, svg); - res.attrs = {x: x, y: y, width: w, height: h, r: r || 0, rx: r || 0, ry: r || 0, fill: "none", stroke: "#000"}; - res.type = "rect"; - $(el, res.attrs); - return res; - }, - theEllipse = function (svg, x, y, rx, ry) { - var el = $("ellipse"); - svg.canvas && svg.canvas[appendChild](el); - var res = new Element(el, svg); - res.attrs = {cx: x, cy: y, rx: rx, ry: ry, fill: "none", stroke: "#000"}; - res.type = "ellipse"; - $(el, res.attrs); - return res; - }, - theImage = function (svg, src, x, y, w, h) { - var el = $("image"); - $(el, {x: x, y: y, width: w, height: h, preserveAspectRatio: "none"}); - el.setAttributeNS(svg.xlink, "href", src); - svg.canvas && svg.canvas[appendChild](el); - var res = new Element(el, svg); - res.attrs = {x: x, y: y, width: w, height: h, src: src}; - res.type = "image"; - return res; - }, - theText = function (svg, x, y, text) { - var el = $("text"); - $(el, {x: x, y: y, "text-anchor": "middle"}); - svg.canvas && svg.canvas[appendChild](el); - var res = new Element(el, svg); - res.attrs = {x: x, y: y, "text-anchor": "middle", text: text, font: availableAttrs.font, stroke: "none", fill: "#000"}; - res.type = "text"; - setFillAndStroke(res, res.attrs); - return res; - }, - setSize = function (width, height) { - this.width = width || this.width; - this.height = height || this.height; - this.canvas[setAttribute]("width", this.width); - this.canvas[setAttribute]("height", this.height); - return this; - }, - create = function () { - var con = getContainer[apply](0, arguments), - container = con && con.container, - x = con.x, - y = con.y, - width = con.width, - height = con.height; - if (!container) { - throw new Error("SVG container not found."); - } - var cnvs = $("svg"); - x = x || 0; - y = y || 0; - width = width || 512; - height = height || 342; - $(cnvs, { - xmlns: "http://www.w3.org/2000/svg", - version: 1.1, - width: width, - height: height - }); - if (container == 1) { - cnvs.style.cssText = "position:absolute;left:" + x + "px;top:" + y + "px"; - doc.body[appendChild](cnvs); - } else { - if (container.firstChild) { - container.insertBefore(cnvs, container.firstChild); - } else { - container[appendChild](cnvs); - } - } - container = new Paper; - container.width = width; - container.height = height; - container.canvas = cnvs; - plugins.call(container, container, R.fn); - container.clear(); - return container; - }; - paperproto.clear = function () { - var c = this.canvas; - while (c.firstChild) { - c.removeChild(c.firstChild); - } - this.bottom = this.top = null; - (this.desc = $("desc"))[appendChild](doc.createTextNode("Created with Rapha\xebl")); - c[appendChild](this.desc); - c[appendChild](this.defs = $("defs")); - }; - paperproto.remove = function () { - this.canvas.parentNode && this.canvas.parentNode.removeChild(this.canvas); - for (var i in this) { - this[i] = removed(i); - } - }; - } - - // VML - if (R.vml) { - var map = {M: "m", L: "l", C: "c", Z: "x", m: "t", l: "r", c: "v", z: "x"}, - bites = /([clmz]),?([^clmz]*)/gi, - blurregexp = / progid:\S+Blur\([^\)]+\)/g, - val = /-?[^,\s-]+/g, - coordsize = 1e3 + S + 1e3, - zoom = 10, - pathlike = {path: 1, rect: 1}, - path2vml = function (path) { - var total = /[ahqstv]/ig, - command = pathToAbsolute; - Str(path).match(total) && (command = path2curve); - total = /[clmz]/g; - if (command == pathToAbsolute && !Str(path).match(total)) { - var res = Str(path)[rp](bites, function (all, command, args) { - var vals = [], - isMove = lowerCase.call(command) == "m", - res = map[command]; - args[rp](val, function (value) { - if (isMove && vals[length] == 2) { - res += vals + map[command == "m" ? "l" : "L"]; - vals = []; - } - vals[push](round(value * zoom)); - }); - return res + vals; - }); - return res; - } - var pa = command(path), p, r; - res = []; - for (var i = 0, ii = pa[length]; i < ii; i++) { - p = pa[i]; - r = lowerCase.call(pa[i][0]); - r == "z" && (r = "x"); - for (var j = 1, jj = p[length]; j < jj; j++) { - r += round(p[j] * zoom) + (j != jj - 1 ? "," : E); - } - res[push](r); - } - return res[join](S); - }; - - R[toString] = function () { - return "Your browser doesn\u2019t support SVG. Falling down to VML.\nYou are running Rapha\xebl " + this.version; - }; - thePath = function (pathString, vml) { - var g = createNode("group"); - g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px"; - g.coordsize = vml.coordsize; - g.coordorigin = vml.coordorigin; - var el = createNode("shape"), ol = el.style; - ol.width = vml.width + "px"; - ol.height = vml.height + "px"; - el.coordsize = coordsize; - el.coordorigin = vml.coordorigin; - g[appendChild](el); - var p = new Element(el, g, vml), - attr = {fill: "none", stroke: "#000"}; - pathString && (attr.path = pathString); - p.type = "path"; - p.path = []; - p.Path = E; - setFillAndStroke(p, attr); - vml.canvas[appendChild](g); - return p; - }; - setFillAndStroke = function (o, params) { - o.attrs = o.attrs || {}; - var node = o.node, - a = o.attrs, - s = node.style, - xy, - newpath = (params.x != a.x || params.y != a.y || params.width != a.width || params.height != a.height || params.r != a.r) && o.type == "rect", - res = o; - - for (var par in params) if (params[has](par)) { - a[par] = params[par]; - } - if (newpath) { - a.path = rectPath(a.x, a.y, a.width, a.height, a.r); - o.X = a.x; - o.Y = a.y; - o.W = a.width; - o.H = a.height; - } - params.href && (node.href = params.href); - params.title && (node.title = params.title); - params.target && (node.target = params.target); - params.cursor && (s.cursor = params.cursor); - "blur" in params && o.blur(params.blur); - if (params.path && o.type == "path" || newpath) { - node.path = path2vml(a.path); - } - if (params.rotation != null) { - o.rotate(params.rotation, true); - } - if (params.translation) { - xy = Str(params.translation)[split](separator); - translate.call(o, xy[0], xy[1]); - if (o._.rt.cx != null) { - o._.rt.cx +=+ xy[0]; - o._.rt.cy +=+ xy[1]; - o.setBox(o.attrs, xy[0], xy[1]); - } - } - if (params.scale) { - xy = Str(params.scale)[split](separator); - o.scale(+xy[0] || 1, +xy[1] || +xy[0] || 1, +xy[2] || null, +xy[3] || null); - } - if ("clip-rect" in params) { - var rect = Str(params["clip-rect"])[split](separator); - if (rect[length] == 4) { - rect[2] = +rect[2] + (+rect[0]); - rect[3] = +rect[3] + (+rect[1]); - var div = node.clipRect || doc.createElement("div"), - dstyle = div.style, - group = node.parentNode; - dstyle.clip = R.format("rect({1}px {2}px {3}px {0}px)", rect); - if (!node.clipRect) { - dstyle.position = "absolute"; - dstyle.top = 0; - dstyle.left = 0; - dstyle.width = o.paper.width + "px"; - dstyle.height = o.paper.height + "px"; - group.parentNode.insertBefore(div, group); - div[appendChild](group); - node.clipRect = div; - } - } - if (!params["clip-rect"]) { - node.clipRect && (node.clipRect.style.clip = E); - } - } - if (o.type == "image" && params.src) { - node.src = params.src; - } - if (o.type == "image" && params.opacity) { - node.filterOpacity = ms + ".Alpha(opacity=" + (params.opacity * 100) + ")"; - s.filter = (node.filterMatrix || E) + (node.filterOpacity || E); - } - params.font && (s.font = params.font); - params["font-family"] && (s.fontFamily = '"' + params["font-family"][split](",")[0][rp](/^['"]+|['"]+$/g, E) + '"'); - params["font-size"] && (s.fontSize = params["font-size"]); - params["font-weight"] && (s.fontWeight = params["font-weight"]); - params["font-style"] && (s.fontStyle = params["font-style"]); - if (params.opacity != null || - params["stroke-width"] != null || - params.fill != null || - params.stroke != null || - params["stroke-width"] != null || - params["stroke-opacity"] != null || - params["fill-opacity"] != null || - params["stroke-dasharray"] != null || - params["stroke-miterlimit"] != null || - params["stroke-linejoin"] != null || - params["stroke-linecap"] != null) { - node = o.shape || node; - var fill = (node.getElementsByTagName(fillString) && node.getElementsByTagName(fillString)[0]), - newfill = false; - !fill && (newfill = fill = createNode(fillString)); - if ("fill-opacity" in params || "opacity" in params) { - var opacity = ((+a["fill-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+R.getRGB(params.fill).o + 1 || 2) - 1); - opacity = mmin(mmax(opacity, 0), 1); - fill.opacity = opacity; - } - params.fill && (fill.on = true); - if (fill.on == null || params.fill == "none") { - fill.on = false; - } - if (fill.on && params.fill) { - var isURL = Str(params.fill).match(ISURL); - if (isURL) { - fill.src = isURL[1]; - fill.type = "tile"; - } else { - fill.color = R.getRGB(params.fill).hex; - fill.src = E; - fill.type = "solid"; - if (R.getRGB(params.fill).error && (res.type in {circle: 1, ellipse: 1} || Str(params.fill).charAt() != "r") && addGradientFill(res, params.fill)) { - a.fill = "none"; - a.gradient = params.fill; - } - } - } - newfill && node[appendChild](fill); - var stroke = (node.getElementsByTagName("stroke") && node.getElementsByTagName("stroke")[0]), - newstroke = false; - !stroke && (newstroke = stroke = createNode("stroke")); - if ((params.stroke && params.stroke != "none") || - params["stroke-width"] || - params["stroke-opacity"] != null || - params["stroke-dasharray"] || - params["stroke-miterlimit"] || - params["stroke-linejoin"] || - params["stroke-linecap"]) { - stroke.on = true; - } - (params.stroke == "none" || stroke.on == null || params.stroke == 0 || params["stroke-width"] == 0) && (stroke.on = false); - var strokeColor = R.getRGB(params.stroke); - stroke.on && params.stroke && (stroke.color = strokeColor.hex); - opacity = ((+a["stroke-opacity"] + 1 || 2) - 1) * ((+a.opacity + 1 || 2) - 1) * ((+strokeColor.o + 1 || 2) - 1); - var width = (toFloat(params["stroke-width"]) || 1) * .75; - opacity = mmin(mmax(opacity, 0), 1); - params["stroke-width"] == null && (width = a["stroke-width"]); - params["stroke-width"] && (stroke.weight = width); - width && width < 1 && (opacity *= width) && (stroke.weight = 1); - stroke.opacity = opacity; - - params["stroke-linejoin"] && (stroke.joinstyle = params["stroke-linejoin"] || "miter"); - stroke.miterlimit = params["stroke-miterlimit"] || 8; - params["stroke-linecap"] && (stroke.endcap = params["stroke-linecap"] == "butt" ? "flat" : params["stroke-linecap"] == "square" ? "square" : "round"); - if (params["stroke-dasharray"]) { - var dasharray = { - "-": "shortdash", - ".": "shortdot", - "-.": "shortdashdot", - "-..": "shortdashdotdot", - ". ": "dot", - "- ": "dash", - "--": "longdash", - "- .": "dashdot", - "--.": "longdashdot", - "--..": "longdashdotdot" - }; - stroke.dashstyle = dasharray[has](params["stroke-dasharray"]) ? dasharray[params["stroke-dasharray"]] : E; - } - newstroke && node[appendChild](stroke); - } - if (res.type == "text") { - s = res.paper.span.style; - a.font && (s.font = a.font); - a["font-family"] && (s.fontFamily = a["font-family"]); - a["font-size"] && (s.fontSize = a["font-size"]); - a["font-weight"] && (s.fontWeight = a["font-weight"]); - a["font-style"] && (s.fontStyle = a["font-style"]); - res.node.string && (res.paper.span.innerHTML = Str(res.node.string)[rp](/")); - res.W = a.w = res.paper.span.offsetWidth; - res.H = a.h = res.paper.span.offsetHeight; - res.X = a.x; - res.Y = a.y + round(res.H / 2); - - // text-anchor emulationm - switch (a["text-anchor"]) { - case "start": - res.node.style["v-text-align"] = "left"; - res.bbx = round(res.W / 2); - break; - case "end": - res.node.style["v-text-align"] = "right"; - res.bbx = -round(res.W / 2); - break; - default: - res.node.style["v-text-align"] = "center"; - break; - } - } - }; - addGradientFill = function (o, gradient) { - o.attrs = o.attrs || {}; - var attrs = o.attrs, - fill, - type = "linear", - fxfy = ".5 .5"; - o.attrs.gradient = gradient; - gradient = Str(gradient)[rp](radial_gradient, function (all, fx, fy) { - type = "radial"; - if (fx && fy) { - fx = toFloat(fx); - fy = toFloat(fy); - pow(fx - .5, 2) + pow(fy - .5, 2) > .25 && (fy = math.sqrt(.25 - pow(fx - .5, 2)) * ((fy > .5) * 2 - 1) + .5); - fxfy = fx + S + fy; - } - return E; - }); - gradient = gradient[split](/\s*\-\s*/); - if (type == "linear") { - var angle = gradient.shift(); - angle = -toFloat(angle); - if (isNaN(angle)) { - return null; - } - } - var dots = parseDots(gradient); - if (!dots) { - return null; - } - o = o.shape || o.node; - fill = o.getElementsByTagName(fillString)[0] || createNode(fillString); - !fill.parentNode && o.appendChild(fill); - if (dots[length]) { - fill.on = true; - fill.method = "none"; - fill.color = dots[0].color; - fill.color2 = dots[dots[length] - 1].color; - var clrs = []; - for (var i = 0, ii = dots[length]; i < ii; i++) { - dots[i].offset && clrs[push](dots[i].offset + S + dots[i].color); - } - fill.colors && (fill.colors.value = clrs[length] ? clrs[join]() : "0% " + fill.color); - if (type == "radial") { - fill.type = "gradientradial"; - fill.focus = "100%"; - fill.focussize = fxfy; - fill.focusposition = fxfy; - } else { - fill.type = "gradient"; - fill.angle = (270 - angle) % 360; - } - } - return 1; - }; - Element = function (node, group, vml) { - var Rotation = 0, - RotX = 0, - RotY = 0, - Scale = 1; - this[0] = node; - this.id = R._oid++; - this.node = node; - node.raphael = this; - this.X = 0; - this.Y = 0; - this.attrs = {}; - this.Group = group; - this.paper = vml; - this._ = { - tx: 0, - ty: 0, - rt: {deg:0}, - sx: 1, - sy: 1 - }; - !vml.bottom && (vml.bottom = this); - this.prev = vml.top; - vml.top && (vml.top.next = this); - vml.top = this; - this.next = null; - }; - elproto = Element[proto]; - elproto.rotate = function (deg, cx, cy) { - if (this.removed) { - return this; - } - if (deg == null) { - if (this._.rt.cx) { - return [this._.rt.deg, this._.rt.cx, this._.rt.cy][join](S); - } - return this._.rt.deg; - } - deg = Str(deg)[split](separator); - if (deg[length] - 1) { - cx = toFloat(deg[1]); - cy = toFloat(deg[2]); - } - deg = toFloat(deg[0]); - if (cx != null) { - this._.rt.deg = deg; - } else { - this._.rt.deg += deg; - } - cy == null && (cx = null); - this._.rt.cx = cx; - this._.rt.cy = cy; - this.setBox(this.attrs, cx, cy); - this.Group.style.rotation = this._.rt.deg; - // gradient fix for rotation. TODO - // var fill = (this.shape || this.node).getElementsByTagName(fillString); - // fill = fill[0] || {}; - // var b = ((360 - this._.rt.deg) - 270) % 360; - // !R.is(fill.angle, "undefined") && (fill.angle = b); - return this; - }; - elproto.setBox = function (params, cx, cy) { - if (this.removed) { - return this; - } - var gs = this.Group.style, - os = (this.shape && this.shape.style) || this.node.style; - params = params || {}; - for (var i in params) if (params[has](i)) { - this.attrs[i] = params[i]; - } - cx = cx || this._.rt.cx; - cy = cy || this._.rt.cy; - var attr = this.attrs, - x, - y, - w, - h; - switch (this.type) { - case "circle": - x = attr.cx - attr.r; - y = attr.cy - attr.r; - w = h = attr.r * 2; - break; - case "ellipse": - x = attr.cx - attr.rx; - y = attr.cy - attr.ry; - w = attr.rx * 2; - h = attr.ry * 2; - break; - case "image": - x = +attr.x; - y = +attr.y; - w = attr.width || 0; - h = attr.height || 0; - break; - case "text": - this.textpath.v = ["m", round(attr.x), ", ", round(attr.y - 2), "l", round(attr.x) + 1, ", ", round(attr.y - 2)][join](E); - x = attr.x - round(this.W / 2); - y = attr.y - this.H / 2; - w = this.W; - h = this.H; - break; - case "rect": - case "path": - if (!this.attrs.path) { - x = 0; - y = 0; - w = this.paper.width; - h = this.paper.height; - } else { - var dim = pathDimensions(this.attrs.path); - x = dim.x; - y = dim.y; - w = dim.width; - h = dim.height; - } - break; - default: - x = 0; - y = 0; - w = this.paper.width; - h = this.paper.height; - break; - } - cx = (cx == null) ? x + w / 2 : cx; - cy = (cy == null) ? y + h / 2 : cy; - var left = cx - this.paper.width / 2, - top = cy - this.paper.height / 2, t; - gs.left != (t = left + "px") && (gs.left = t); - gs.top != (t = top + "px") && (gs.top = t); - this.X = pathlike[has](this.type) ? -left : x; - this.Y = pathlike[has](this.type) ? -top : y; - this.W = w; - this.H = h; - if (pathlike[has](this.type)) { - os.left != (t = -left * zoom + "px") && (os.left = t); - os.top != (t = -top * zoom + "px") && (os.top = t); - } else if (this.type == "text") { - os.left != (t = -left + "px") && (os.left = t); - os.top != (t = -top + "px") && (os.top = t); - } else { - gs.width != (t = this.paper.width + "px") && (gs.width = t); - gs.height != (t = this.paper.height + "px") && (gs.height = t); - os.left != (t = x - left + "px") && (os.left = t); - os.top != (t = y - top + "px") && (os.top = t); - os.width != (t = w + "px") && (os.width = t); - os.height != (t = h + "px") && (os.height = t); - } - }; - elproto.hide = function () { - !this.removed && (this.Group.style.display = "none"); - return this; - }; - elproto.show = function () { - !this.removed && (this.Group.style.display = "block"); - return this; - }; - elproto.getBBox = function () { - if (this.removed) { - return this; - } - if (pathlike[has](this.type)) { - return pathDimensions(this.attrs.path); - } - return { - x: this.X + (this.bbx || 0), - y: this.Y, - width: this.W, - height: this.H - }; - }; - elproto.remove = function () { - if (this.removed) { - return; - } - tear(this, this.paper); - this.node.parentNode.removeChild(this.node); - this.Group.parentNode.removeChild(this.Group); - this.shape && this.shape.parentNode.removeChild(this.shape); - for (var i in this) { - delete this[i]; - } - this.removed = true; - }; - elproto.attr = function (name, value) { - if (this.removed) { - return this; - } - if (name == null) { - var res = {}; - for (var i in this.attrs) if (this.attrs[has](i)) { - res[i] = this.attrs[i]; - } - this._.rt.deg && (res.rotation = this.rotate()); - (this._.sx != 1 || this._.sy != 1) && (res.scale = this.scale()); - res.gradient && res.fill == "none" && (res.fill = res.gradient) && delete res.gradient; - return res; - } - if (value == null && R.is(name, "string")) { - if (name == "translation") { - return translate.call(this); - } - if (name == "rotation") { - return this.rotate(); - } - if (name == "scale") { - return this.scale(); - } - if (name == fillString && this.attrs.fill == "none" && this.attrs.gradient) { - return this.attrs.gradient; - } - return this.attrs[name]; - } - if (this.attrs && value == null && R.is(name, array)) { - var ii, values = {}; - for (i = 0, ii = name[length]; i < ii; i++) { - values[name[i]] = this.attr(name[i]); - } - return values; - } - var params; - if (value != null) { - params = {}; - params[name] = value; - } - value == null && R.is(name, "object") && (params = name); - if (params) { - for (var key in this.paper.customAttributes) if (this.paper.customAttributes[has](key) && params[has](key) && R.is(this.paper.customAttributes[key], "function")) { - var par = this.paper.customAttributes[key].apply(this, [][concat](params[key])); - this.attrs[key] = params[key]; - for (var subkey in par) if (par[has](subkey)) { - params[subkey] = par[subkey]; - } - } - if (params.text && this.type == "text") { - this.node.string = params.text; - } - setFillAndStroke(this, params); - if (params.gradient && (({circle: 1, ellipse: 1})[has](this.type) || Str(params.gradient).charAt() != "r")) { - addGradientFill(this, params.gradient); - } - (!pathlike[has](this.type) || this._.rt.deg) && this.setBox(this.attrs); - } - return this; - }; - elproto.toFront = function () { - !this.removed && this.Group.parentNode[appendChild](this.Group); - this.paper.top != this && tofront(this, this.paper); - return this; - }; - elproto.toBack = function () { - if (this.removed) { - return this; - } - if (this.Group.parentNode.firstChild != this.Group) { - this.Group.parentNode.insertBefore(this.Group, this.Group.parentNode.firstChild); - toback(this, this.paper); - } - return this; - }; - elproto.insertAfter = function (element) { - if (this.removed) { - return this; - } - if (element.constructor == Set) { - element = element[element.length - 1]; - } - if (element.Group.nextSibling) { - element.Group.parentNode.insertBefore(this.Group, element.Group.nextSibling); - } else { - element.Group.parentNode[appendChild](this.Group); - } - insertafter(this, element, this.paper); - return this; - }; - elproto.insertBefore = function (element) { - if (this.removed) { - return this; - } - if (element.constructor == Set) { - element = element[0]; - } - element.Group.parentNode.insertBefore(this.Group, element.Group); - insertbefore(this, element, this.paper); - return this; - }; - elproto.blur = function (size) { - var s = this.node.runtimeStyle, - f = s.filter; - f = f.replace(blurregexp, E); - if (+size !== 0) { - this.attrs.blur = size; - s.filter = f + S + ms + ".Blur(pixelradius=" + (+size || 1.5) + ")"; - s.margin = R.format("-{0}px 0 0 -{0}px", round(+size || 1.5)); - } else { - s.filter = f; - s.margin = 0; - delete this.attrs.blur; - } - }; - - theCircle = function (vml, x, y, r) { - var g = createNode("group"), - o = createNode("oval"), - ol = o.style; - g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px"; - g.coordsize = coordsize; - g.coordorigin = vml.coordorigin; - g[appendChild](o); - var res = new Element(o, g, vml); - res.type = "circle"; - setFillAndStroke(res, {stroke: "#000", fill: "none"}); - res.attrs.cx = x; - res.attrs.cy = y; - res.attrs.r = r; - res.setBox({x: x - r, y: y - r, width: r * 2, height: r * 2}); - vml.canvas[appendChild](g); - return res; - }; - function rectPath(x, y, w, h, r) { - if (r) { - return R.format("M{0},{1}l{2},0a{3},{3},0,0,1,{3},{3}l0,{5}a{3},{3},0,0,1,{4},{3}l{6},0a{3},{3},0,0,1,{4},{4}l0,{7}a{3},{3},0,0,1,{3},{4}z", x + r, y, w - r * 2, r, -r, h - r * 2, r * 2 - w, r * 2 - h); - } else { - return R.format("M{0},{1}l{2},0,0,{3},{4},0z", x, y, w, h, -w); - } - } - theRect = function (vml, x, y, w, h, r) { - var path = rectPath(x, y, w, h, r), - res = vml.path(path), - a = res.attrs; - res.X = a.x = x; - res.Y = a.y = y; - res.W = a.width = w; - res.H = a.height = h; - a.r = r; - a.path = path; - res.type = "rect"; - return res; - }; - theEllipse = function (vml, x, y, rx, ry) { - var g = createNode("group"), - o = createNode("oval"), - ol = o.style; - g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px"; - g.coordsize = coordsize; - g.coordorigin = vml.coordorigin; - g[appendChild](o); - var res = new Element(o, g, vml); - res.type = "ellipse"; - setFillAndStroke(res, {stroke: "#000"}); - res.attrs.cx = x; - res.attrs.cy = y; - res.attrs.rx = rx; - res.attrs.ry = ry; - res.setBox({x: x - rx, y: y - ry, width: rx * 2, height: ry * 2}); - vml.canvas[appendChild](g); - return res; - }; - theImage = function (vml, src, x, y, w, h) { - var g = createNode("group"), - o = createNode("image"); - g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px"; - g.coordsize = coordsize; - g.coordorigin = vml.coordorigin; - o.src = src; - g[appendChild](o); - var res = new Element(o, g, vml); - res.type = "image"; - res.attrs.src = src; - res.attrs.x = x; - res.attrs.y = y; - res.attrs.w = w; - res.attrs.h = h; - res.setBox({x: x, y: y, width: w, height: h}); - vml.canvas[appendChild](g); - return res; - }; - theText = function (vml, x, y, text) { - var g = createNode("group"), - el = createNode("shape"), - ol = el.style, - path = createNode("path"), - ps = path.style, - o = createNode("textpath"); - g.style.cssText = "position:absolute;left:0;top:0;width:" + vml.width + "px;height:" + vml.height + "px"; - g.coordsize = coordsize; - g.coordorigin = vml.coordorigin; - path.v = R.format("m{0},{1}l{2},{1}", round(x * 10), round(y * 10), round(x * 10) + 1); - path.textpathok = true; - ol.width = vml.width; - ol.height = vml.height; - o.string = Str(text); - o.on = true; - el[appendChild](o); - el[appendChild](path); - g[appendChild](el); - var res = new Element(o, g, vml); - res.shape = el; - res.textpath = path; - res.type = "text"; - res.attrs.text = text; - res.attrs.x = x; - res.attrs.y = y; - res.attrs.w = 1; - res.attrs.h = 1; - setFillAndStroke(res, {font: availableAttrs.font, stroke: "none", fill: "#000"}); - res.setBox(); - vml.canvas[appendChild](g); - return res; - }; - setSize = function (width, height) { - var cs = this.canvas.style; - width == +width && (width += "px"); - height == +height && (height += "px"); - cs.width = width; - cs.height = height; - cs.clip = "rect(0 " + width + " " + height + " 0)"; - return this; - }; - var createNode; - doc.createStyleSheet().addRule(".rvml", "behavior:url(#default#VML)"); - try { - !doc.namespaces.rvml && doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml"); - createNode = function (tagName) { - return doc.createElement(''); - }; - } catch (e) { - createNode = function (tagName) { - return doc.createElement('<' + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">'); - }; - } - create = function () { - var con = getContainer[apply](0, arguments), - container = con.container, - height = con.height, - s, - width = con.width, - x = con.x, - y = con.y; - if (!container) { - throw new Error("VML container not found."); - } - var res = new Paper, - c = res.canvas = doc.createElement("div"), - cs = c.style; - x = x || 0; - y = y || 0; - width = width || 512; - height = height || 342; - width == +width && (width += "px"); - height == +height && (height += "px"); - res.width = 1e3; - res.height = 1e3; - res.coordsize = zoom * 1e3 + S + zoom * 1e3; - res.coordorigin = "0 0"; - res.span = doc.createElement("span"); - res.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;"; - c[appendChild](res.span); - cs.cssText = R.format("top:0;left:0;width:{0};height:{1};display:inline-block;position:relative;clip:rect(0 {0} {1} 0);overflow:hidden", width, height); - if (container == 1) { - doc.body[appendChild](c); - cs.left = x + "px"; - cs.top = y + "px"; - cs.position = "absolute"; - } else { - if (container.firstChild) { - container.insertBefore(c, container.firstChild); - } else { - container[appendChild](c); - } - } - plugins.call(res, res, R.fn); - return res; - }; - paperproto.clear = function () { - this.canvas.innerHTML = E; - this.span = doc.createElement("span"); - this.span.style.cssText = "position:absolute;left:-9999em;top:-9999em;padding:0;margin:0;line-height:1;display:inline;"; - this.canvas[appendChild](this.span); - this.bottom = this.top = null; - }; - paperproto.remove = function () { - this.canvas.parentNode.removeChild(this.canvas); - for (var i in this) { - this[i] = removed(i); - } - return true; - }; - } - - // rest - // WebKit rendering bug workaround method - var version = navigator.userAgent.match(/Version\/(.*?)\s/); - if ((navigator.vendor == "Apple Computer, Inc.") && (version && version[1] < 4 || navigator.platform.slice(0, 2) == "iP")) { - paperproto.safari = function () { - var rect = this.rect(-99, -99, this.width + 99, this.height + 99).attr({stroke: "none"}); - win.setTimeout(function () {rect.remove();}); - }; - } else { - paperproto.safari = function () {}; - } - - // Events - var preventDefault = function () { - this.returnValue = false; - }, - preventTouch = function () { - return this.originalEvent.preventDefault(); - }, - stopPropagation = function () { - this.cancelBubble = true; - }, - stopTouch = function () { - return this.originalEvent.stopPropagation(); - }, - addEvent = (function () { - if (doc.addEventListener) { - return function (obj, type, fn, element) { - var realName = supportsTouch && touchMap[type] ? touchMap[type] : type; - var f = function (e) { - if (supportsTouch && touchMap[has](type)) { - for (var i = 0, ii = e.targetTouches && e.targetTouches.length; i < ii; i++) { - if (e.targetTouches[i].target == obj) { - var olde = e; - e = e.targetTouches[i]; - e.originalEvent = olde; - e.preventDefault = preventTouch; - e.stopPropagation = stopTouch; - break; - } - } - } - return fn.call(element, e); - }; - obj.addEventListener(realName, f, false); - return function () { - obj.removeEventListener(realName, f, false); - return true; - }; - }; - } else if (doc.attachEvent) { - return function (obj, type, fn, element) { - var f = function (e) { - e = e || win.event; - e.preventDefault = e.preventDefault || preventDefault; - e.stopPropagation = e.stopPropagation || stopPropagation; - return fn.call(element, e); - }; - obj.attachEvent("on" + type, f); - var detacher = function () { - obj.detachEvent("on" + type, f); - return true; - }; - return detacher; - }; - } - })(), - drag = [], - dragMove = function (e) { - var x = e.clientX, - y = e.clientY, - scrollY = doc.documentElement.scrollTop || doc.body.scrollTop, - scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft, - dragi, - j = drag.length; - while (j--) { - dragi = drag[j]; - if (supportsTouch) { - var i = e.touches.length, - touch; - while (i--) { - touch = e.touches[i]; - if (touch.identifier == dragi.el._drag.id) { - x = touch.clientX; - y = touch.clientY; - (e.originalEvent ? e.originalEvent : e).preventDefault(); - break; - } - } - } else { - e.preventDefault(); - } - x += scrollX; - y += scrollY; - dragi.move && dragi.move.call(dragi.move_scope || dragi.el, x - dragi.el._drag.x, y - dragi.el._drag.y, x, y, e); - } - }, - dragUp = function (e) { - R.unmousemove(dragMove).unmouseup(dragUp); - var i = drag.length, - dragi; - while (i--) { - dragi = drag[i]; - dragi.el._drag = {}; - dragi.end && dragi.end.call(dragi.end_scope || dragi.start_scope || dragi.move_scope || dragi.el, e); - } - drag = []; - }; - for (var i = events[length]; i--;) { - (function (eventName) { - R[eventName] = Element[proto][eventName] = function (fn, scope) { - if (R.is(fn, "function")) { - this.events = this.events || []; - this.events.push({name: eventName, f: fn, unbind: addEvent(this.shape || this.node || doc, eventName, fn, scope || this)}); - } - return this; - }; - R["un" + eventName] = Element[proto]["un" + eventName] = function (fn) { - var events = this.events, - l = events[length]; - while (l--) if (events[l].name == eventName && events[l].f == fn) { - events[l].unbind(); - events.splice(l, 1); - !events.length && delete this.events; - return this; - } - return this; - }; - })(events[i]); - } - elproto.hover = function (f_in, f_out, scope_in, scope_out) { - return this.mouseover(f_in, scope_in).mouseout(f_out, scope_out || scope_in); - }; - elproto.unhover = function (f_in, f_out) { - return this.unmouseover(f_in).unmouseout(f_out); - }; - elproto.drag = function (onmove, onstart, onend, move_scope, start_scope, end_scope) { - this._drag = {}; - this.mousedown(function (e) { - (e.originalEvent || e).preventDefault(); - var scrollY = doc.documentElement.scrollTop || doc.body.scrollTop, - scrollX = doc.documentElement.scrollLeft || doc.body.scrollLeft; - this._drag.x = e.clientX + scrollX; - this._drag.y = e.clientY + scrollY; - this._drag.id = e.identifier; - onstart && onstart.call(start_scope || move_scope || this, e.clientX + scrollX, e.clientY + scrollY, e); - !drag.length && R.mousemove(dragMove).mouseup(dragUp); - drag.push({el: this, move: onmove, end: onend, move_scope: move_scope, start_scope: start_scope, end_scope: end_scope}); - }); - return this; - }; - elproto.undrag = function (onmove, onstart, onend) { - var i = drag.length; - while (i--) { - drag[i].el == this && (drag[i].move == onmove && drag[i].end == onend) && drag.splice(i++, 1); - } - !drag.length && R.unmousemove(dragMove).unmouseup(dragUp); - }; - paperproto.circle = function (x, y, r) { - return theCircle(this, x || 0, y || 0, r || 0); - }; - paperproto.rect = function (x, y, w, h, r) { - return theRect(this, x || 0, y || 0, w || 0, h || 0, r || 0); - }; - paperproto.ellipse = function (x, y, rx, ry) { - return theEllipse(this, x || 0, y || 0, rx || 0, ry || 0); - }; - paperproto.path = function (pathString) { - pathString && !R.is(pathString, string) && !R.is(pathString[0], array) && (pathString += E); - return thePath(R.format[apply](R, arguments), this); - }; - paperproto.image = function (src, x, y, w, h) { - return theImage(this, src || "about:blank", x || 0, y || 0, w || 0, h || 0); - }; - paperproto.text = function (x, y, text) { - return theText(this, x || 0, y || 0, Str(text)); - }; - paperproto.set = function (itemsArray) { - arguments[length] > 1 && (itemsArray = Array[proto].splice.call(arguments, 0, arguments[length])); - return new Set(itemsArray); - }; - paperproto.setSize = setSize; - paperproto.top = paperproto.bottom = null; - paperproto.raphael = R; - function x_y() { - return this.x + S + this.y; - } - elproto.resetScale = function () { - if (this.removed) { - return this; - } - this._.sx = 1; - this._.sy = 1; - this.attrs.scale = "1 1"; - }; - elproto.scale = function (x, y, cx, cy) { - if (this.removed) { - return this; - } - if (x == null && y == null) { - return { - x: this._.sx, - y: this._.sy, - toString: x_y - }; - } - y = y || x; - !+y && (y = x); - var dx, - dy, - dcx, - dcy, - a = this.attrs; - if (x != 0) { - var bb = this.getBBox(), - rcx = bb.x + bb.width / 2, - rcy = bb.y + bb.height / 2, - kx = abs(x / this._.sx), - ky = abs(y / this._.sy); - cx = (+cx || cx == 0) ? cx : rcx; - cy = (+cy || cy == 0) ? cy : rcy; - var posx = this._.sx > 0, - posy = this._.sy > 0, - dirx = ~~(x / abs(x)), - diry = ~~(y / abs(y)), - dkx = kx * dirx, - dky = ky * diry, - s = this.node.style, - ncx = cx + abs(rcx - cx) * dkx * (rcx > cx == posx ? 1 : -1), - ncy = cy + abs(rcy - cy) * dky * (rcy > cy == posy ? 1 : -1), - fr = (x * dirx > y * diry ? ky : kx); - switch (this.type) { - case "rect": - case "image": - var neww = a.width * kx, - newh = a.height * ky; - this.attr({ - height: newh, - r: a.r * fr, - width: neww, - x: ncx - neww / 2, - y: ncy - newh / 2 - }); - break; - case "circle": - case "ellipse": - this.attr({ - rx: a.rx * kx, - ry: a.ry * ky, - r: a.r * fr, - cx: ncx, - cy: ncy - }); - break; - case "text": - this.attr({ - x: ncx, - y: ncy - }); - break; - case "path": - var path = pathToRelative(a.path), - skip = true, - fx = posx ? dkx : kx, - fy = posy ? dky : ky; - for (var i = 0, ii = path[length]; i < ii; i++) { - var p = path[i], - P0 = upperCase.call(p[0]); - if (P0 == "M" && skip) { - continue; - } else { - skip = false; - } - if (P0 == "A") { - p[path[i][length] - 2] *= fx; - p[path[i][length] - 1] *= fy; - p[1] *= kx; - p[2] *= ky; - p[5] = +(dirx + diry ? !!+p[5] : !+p[5]); - } else if (P0 == "H") { - for (var j = 1, jj = p[length]; j < jj; j++) { - p[j] *= fx; - } - } else if (P0 == "V") { - for (j = 1, jj = p[length]; j < jj; j++) { - p[j] *= fy; - } - } else { - for (j = 1, jj = p[length]; j < jj; j++) { - p[j] *= (j % 2) ? fx : fy; - } - } - } - var dim2 = pathDimensions(path); - dx = ncx - dim2.x - dim2.width / 2; - dy = ncy - dim2.y - dim2.height / 2; - path[0][1] += dx; - path[0][2] += dy; - this.attr({path: path}); - break; - } - if (this.type in {text: 1, image:1} && (dirx != 1 || diry != 1)) { - if (this.transformations) { - this.transformations[2] = "scale("[concat](dirx, ",", diry, ")"); - this.node[setAttribute]("transform", this.transformations[join](S)); - dx = (dirx == -1) ? -a.x - (neww || 0) : a.x; - dy = (diry == -1) ? -a.y - (newh || 0) : a.y; - this.attr({x: dx, y: dy}); - a.fx = dirx - 1; - a.fy = diry - 1; - } else { - this.node.filterMatrix = ms + ".Matrix(M11="[concat](dirx, - ", M12=0, M21=0, M22=", diry, - ", Dx=0, Dy=0, sizingmethod='auto expand', filtertype='bilinear')"); - s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E); - } - } else { - if (this.transformations) { - this.transformations[2] = E; - this.node[setAttribute]("transform", this.transformations[join](S)); - a.fx = 0; - a.fy = 0; - } else { - this.node.filterMatrix = E; - s.filter = (this.node.filterMatrix || E) + (this.node.filterOpacity || E); - } - } - a.scale = [x, y, cx, cy][join](S); - this._.sx = x; - this._.sy = y; - } - return this; - }; - elproto.clone = function () { - if (this.removed) { - return null; - } - var attr = this.attr(); - delete attr.scale; - delete attr.translation; - return this.paper[this.type]().attr(attr); - }; - var curveslengths = {}, - getPointAtSegmentLength = function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, length) { - var len = 0, - precision = 100, - name = [p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y].join(), - cache = curveslengths[name], - old, dot; - !cache && (curveslengths[name] = cache = {data: []}); - cache.timer && clearTimeout(cache.timer); - cache.timer = setTimeout(function () {delete curveslengths[name];}, 2000); - if (length != null) { - var total = getPointAtSegmentLength(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y); - precision = ~~total * 10; - } - for (var i = 0; i < precision + 1; i++) { - if (cache.data[length] > i) { - dot = cache.data[i * precision]; - } else { - dot = R.findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, i / precision); - cache.data[i] = dot; - } - i && (len += pow(pow(old.x - dot.x, 2) + pow(old.y - dot.y, 2), .5)); - if (length != null && len >= length) { - return dot; - } - old = dot; - } - if (length == null) { - return len; - } - }, - getLengthFactory = function (istotal, subpath) { - return function (path, length, onlystart) { - path = path2curve(path); - var x, y, p, l, sp = "", subpaths = {}, point, - len = 0; - for (var i = 0, ii = path.length; i < ii; i++) { - p = path[i]; - if (p[0] == "M") { - x = +p[1]; - y = +p[2]; - } else { - l = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6]); - if (len + l > length) { - if (subpath && !subpaths.start) { - point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); - sp += ["C", point.start.x, point.start.y, point.m.x, point.m.y, point.x, point.y]; - if (onlystart) {return sp;} - subpaths.start = sp; - sp = ["M", point.x, point.y + "C", point.n.x, point.n.y, point.end.x, point.end.y, p[5], p[6]][join](); - len += l; - x = +p[5]; - y = +p[6]; - continue; - } - if (!istotal && !subpath) { - point = getPointAtSegmentLength(x, y, p[1], p[2], p[3], p[4], p[5], p[6], length - len); - return {x: point.x, y: point.y, alpha: point.alpha}; - } - } - len += l; - x = +p[5]; - y = +p[6]; - } - sp += p; - } - subpaths.end = sp; - point = istotal ? len : subpath ? subpaths : R.findDotsAtSegment(x, y, p[1], p[2], p[3], p[4], p[5], p[6], 1); - point.alpha && (point = {x: point.x, y: point.y, alpha: point.alpha}); - return point; - }; - }; - var getTotalLength = getLengthFactory(1), - getPointAtLength = getLengthFactory(), - getSubpathsAtLength = getLengthFactory(0, 1); - elproto.getTotalLength = function () { - if (this.type != "path") {return;} - if (this.node.getTotalLength) { - return this.node.getTotalLength(); - } - return getTotalLength(this.attrs.path); - }; - elproto.getPointAtLength = function (length) { - if (this.type != "path") {return;} - return getPointAtLength(this.attrs.path, length); - }; - elproto.getSubpath = function (from, to) { - if (this.type != "path") {return;} - if (abs(this.getTotalLength() - to) < "1e-6") { - return getSubpathsAtLength(this.attrs.path, from).end; - } - var a = getSubpathsAtLength(this.attrs.path, to, 1); - return from ? getSubpathsAtLength(a, from).end : a; - }; - - // animation easing formulas - R.easing_formulas = { - linear: function (n) { - return n; - }, - "<": function (n) { - return pow(n, 3); - }, - ">": function (n) { - return pow(n - 1, 3) + 1; - }, - "<>": function (n) { - n = n * 2; - if (n < 1) { - return pow(n, 3) / 2; - } - n -= 2; - return (pow(n, 3) + 2) / 2; - }, - backIn: function (n) { - var s = 1.70158; - return n * n * ((s + 1) * n - s); - }, - backOut: function (n) { - n = n - 1; - var s = 1.70158; - return n * n * ((s + 1) * n + s) + 1; - }, - elastic: function (n) { - if (n == 0 || n == 1) { - return n; - } - var p = .3, - s = p / 4; - return pow(2, -10 * n) * math.sin((n - s) * (2 * PI) / p) + 1; - }, - bounce: function (n) { - var s = 7.5625, - p = 2.75, - l; - if (n < (1 / p)) { - l = s * n * n; - } else { - if (n < (2 / p)) { - n -= (1.5 / p); - l = s * n * n + .75; - } else { - if (n < (2.5 / p)) { - n -= (2.25 / p); - l = s * n * n + .9375; - } else { - n -= (2.625 / p); - l = s * n * n + .984375; - } - } - } - return l; - } - }; - - var animationElements = [], - animation = function () { - var Now = +new Date; - for (var l = 0; l < animationElements[length]; l++) { - var e = animationElements[l]; - if (e.stop || e.el.removed) { - continue; - } - var time = Now - e.start, - ms = e.ms, - easing = e.easing, - from = e.from, - diff = e.diff, - to = e.to, - t = e.t, - that = e.el, - set = {}, - now; - if (time < ms) { - var pos = easing(time / ms); - for (var attr in from) if (from[has](attr)) { - switch (availableAnimAttrs[attr]) { - case "along": - now = pos * ms * diff[attr]; - to.back && (now = to.len - now); - var point = getPointAtLength(to[attr], now); - that.translate(diff.sx - diff.x || 0, diff.sy - diff.y || 0); - diff.x = point.x; - diff.y = point.y; - that.translate(point.x - diff.sx, point.y - diff.sy); - to.rot && that.rotate(diff.r + point.alpha, point.x, point.y); - break; - case nu: - now = +from[attr] + pos * ms * diff[attr]; - break; - case "colour": - now = "rgb(" + [ - upto255(round(from[attr].r + pos * ms * diff[attr].r)), - upto255(round(from[attr].g + pos * ms * diff[attr].g)), - upto255(round(from[attr].b + pos * ms * diff[attr].b)) - ][join](",") + ")"; - break; - case "path": - now = []; - for (var i = 0, ii = from[attr][length]; i < ii; i++) { - now[i] = [from[attr][i][0]]; - for (var j = 1, jj = from[attr][i][length]; j < jj; j++) { - now[i][j] = +from[attr][i][j] + pos * ms * diff[attr][i][j]; - } - now[i] = now[i][join](S); - } - now = now[join](S); - break; - case "csv": - switch (attr) { - case "translation": - var x = pos * ms * diff[attr][0] - t.x, - y = pos * ms * diff[attr][1] - t.y; - t.x += x; - t.y += y; - now = x + S + y; - break; - case "rotation": - now = +from[attr][0] + pos * ms * diff[attr][0]; - from[attr][1] && (now += "," + from[attr][1] + "," + from[attr][2]); - break; - case "scale": - now = [+from[attr][0] + pos * ms * diff[attr][0], +from[attr][1] + pos * ms * diff[attr][1], (2 in to[attr] ? to[attr][2] : E), (3 in to[attr] ? to[attr][3] : E)][join](S); - break; - case "clip-rect": - now = []; - i = 4; - while (i--) { - now[i] = +from[attr][i] + pos * ms * diff[attr][i]; - } - break; - } - break; - default: - var from2 = [].concat(from[attr]); - now = []; - i = that.paper.customAttributes[attr].length; - while (i--) { - now[i] = +from2[i] + pos * ms * diff[attr][i]; - } - break; - } - set[attr] = now; - } - that.attr(set); - that._run && that._run.call(that); - } else { - if (to.along) { - point = getPointAtLength(to.along, to.len * !to.back); - that.translate(diff.sx - (diff.x || 0) + point.x - diff.sx, diff.sy - (diff.y || 0) + point.y - diff.sy); - to.rot && that.rotate(diff.r + point.alpha, point.x, point.y); - } - (t.x || t.y) && that.translate(-t.x, -t.y); - to.scale && (to.scale += E); - that.attr(to); - animationElements.splice(l--, 1); - } - } - R.svg && that && that.paper && that.paper.safari(); - animationElements[length] && setTimeout(animation); - }, - keyframesRun = function (attr, element, time, prev, prevcallback) { - var dif = time - prev; - element.timeouts.push(setTimeout(function () { - R.is(prevcallback, "function") && prevcallback.call(element); - element.animate(attr, dif, attr.easing); - }, prev)); - }, - upto255 = function (color) { - return mmax(mmin(color, 255), 0); - }, - translate = function (x, y) { - if (x == null) { - return {x: this._.tx, y: this._.ty, toString: x_y}; - } - this._.tx += +x; - this._.ty += +y; - switch (this.type) { - case "circle": - case "ellipse": - this.attr({cx: +x + this.attrs.cx, cy: +y + this.attrs.cy}); - break; - case "rect": - case "image": - case "text": - this.attr({x: +x + this.attrs.x, y: +y + this.attrs.y}); - break; - case "path": - var path = pathToRelative(this.attrs.path); - path[0][1] += +x; - path[0][2] += +y; - this.attr({path: path}); - break; - } - return this; - }; - elproto.animateWith = function (element, params, ms, easing, callback) { - for (var i = 0, ii = animationElements.length; i < ii; i++) { - if (animationElements[i].el.id == element.id) { - params.start = animationElements[i].start; - } - } - return this.animate(params, ms, easing, callback); - }; - elproto.animateAlong = along(); - elproto.animateAlongBack = along(1); - function along(isBack) { - return function (path, ms, rotate, callback) { - var params = {back: isBack}; - R.is(rotate, "function") ? (callback = rotate) : (params.rot = rotate); - path && path.constructor == Element && (path = path.attrs.path); - path && (params.along = path); - return this.animate(params, ms, callback); - }; - } - function CubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) { - var cx = 3 * p1x, - bx = 3 * (p2x - p1x) - cx, - ax = 1 - cx - bx, - cy = 3 * p1y, - by = 3 * (p2y - p1y) - cy, - ay = 1 - cy - by; - function sampleCurveX(t) { - return ((ax * t + bx) * t + cx) * t; - } - function solve(x, epsilon) { - var t = solveCurveX(x, epsilon); - return ((ay * t + by) * t + cy) * t; - } - function solveCurveX(x, epsilon) { - var t0, t1, t2, x2, d2, i; - for(t2 = x, i = 0; i < 8; i++) { - x2 = sampleCurveX(t2) - x; - if (abs(x2) < epsilon) { - return t2; - } - d2 = (3 * ax * t2 + 2 * bx) * t2 + cx; - if (abs(d2) < 1e-6) { - break; - } - t2 = t2 - x2 / d2; - } - t0 = 0; - t1 = 1; - t2 = x; - if (t2 < t0) { - return t0; - } - if (t2 > t1) { - return t1; - } - while (t0 < t1) { - x2 = sampleCurveX(t2); - if (abs(x2 - x) < epsilon) { - return t2; - } - if (x > x2) { - t0 = t2; - } else { - t1 = t2; - } - t2 = (t1 - t0) / 2 + t0; - } - return t2; - } - return solve(t, 1 / (200 * duration)); - } - elproto.onAnimation = function (f) { - this._run = f || 0; - return this; - }; - elproto.animate = function (params, ms, easing, callback) { - var element = this; - element.timeouts = element.timeouts || []; - if (R.is(easing, "function") || !easing) { - callback = easing || null; - } - if (element.removed) { - callback && callback.call(element); - return element; - } - var from = {}, - to = {}, - animateable = false, - diff = {}; - for (var attr in params) if (params[has](attr)) { - if (availableAnimAttrs[has](attr) || element.paper.customAttributes[has](attr)) { - animateable = true; - from[attr] = element.attr(attr); - (from[attr] == null) && (from[attr] = availableAttrs[attr]); - to[attr] = params[attr]; - switch (availableAnimAttrs[attr]) { - case "along": - var len = getTotalLength(params[attr]); - var point = getPointAtLength(params[attr], len * !!params.back); - var bb = element.getBBox(); - diff[attr] = len / ms; - diff.tx = bb.x; - diff.ty = bb.y; - diff.sx = point.x; - diff.sy = point.y; - to.rot = params.rot; - to.back = params.back; - to.len = len; - params.rot && (diff.r = toFloat(element.rotate()) || 0); - break; - case nu: - diff[attr] = (to[attr] - from[attr]) / ms; - break; - case "colour": - from[attr] = R.getRGB(from[attr]); - var toColour = R.getRGB(to[attr]); - diff[attr] = { - r: (toColour.r - from[attr].r) / ms, - g: (toColour.g - from[attr].g) / ms, - b: (toColour.b - from[attr].b) / ms - }; - break; - case "path": - var pathes = path2curve(from[attr], to[attr]); - from[attr] = pathes[0]; - var toPath = pathes[1]; - diff[attr] = []; - for (var i = 0, ii = from[attr][length]; i < ii; i++) { - diff[attr][i] = [0]; - for (var j = 1, jj = from[attr][i][length]; j < jj; j++) { - diff[attr][i][j] = (toPath[i][j] - from[attr][i][j]) / ms; - } - } - break; - case "csv": - var values = Str(params[attr])[split](separator), - from2 = Str(from[attr])[split](separator); - switch (attr) { - case "translation": - from[attr] = [0, 0]; - diff[attr] = [values[0] / ms, values[1] / ms]; - break; - case "rotation": - from[attr] = (from2[1] == values[1] && from2[2] == values[2]) ? from2 : [0, values[1], values[2]]; - diff[attr] = [(values[0] - from[attr][0]) / ms, 0, 0]; - break; - case "scale": - params[attr] = values; - from[attr] = Str(from[attr])[split](separator); - diff[attr] = [(values[0] - from[attr][0]) / ms, (values[1] - from[attr][1]) / ms, 0, 0]; - break; - case "clip-rect": - from[attr] = Str(from[attr])[split](separator); - diff[attr] = []; - i = 4; - while (i--) { - diff[attr][i] = (values[i] - from[attr][i]) / ms; - } - break; - } - to[attr] = values; - break; - default: - values = [].concat(params[attr]); - from2 = [].concat(from[attr]); - diff[attr] = []; - i = element.paper.customAttributes[attr][length]; - while (i--) { - diff[attr][i] = ((values[i] || 0) - (from2[i] || 0)) / ms; - } - break; - } - } - } - if (!animateable) { - var attrs = [], - lastcall; - for (var key in params) if (params[has](key) && animKeyFrames.test(key)) { - attr = {value: params[key]}; - key == "from" && (key = 0); - key == "to" && (key = 100); - attr.key = toInt(key, 10); - attrs.push(attr); - } - attrs.sort(sortByKey); - if (attrs[0].key) { - attrs.unshift({key: 0, value: element.attrs}); - } - for (i = 0, ii = attrs[length]; i < ii; i++) { - keyframesRun(attrs[i].value, element, ms / 100 * attrs[i].key, ms / 100 * (attrs[i - 1] && attrs[i - 1].key || 0), attrs[i - 1] && attrs[i - 1].value.callback); - } - lastcall = attrs[attrs[length] - 1].value.callback; - if (lastcall) { - element.timeouts.push(setTimeout(function () {lastcall.call(element);}, ms)); - } - } else { - var easyeasy = R.easing_formulas[easing]; - if (!easyeasy) { - easyeasy = Str(easing).match(bezierrg); - if (easyeasy && easyeasy[length] == 5) { - var curve = easyeasy; - easyeasy = function (t) { - return CubicBezierAtTime(t, +curve[1], +curve[2], +curve[3], +curve[4], ms); - }; - } else { - easyeasy = function (t) { - return t; - }; - } - } - animationElements.push({ - start: params.start || +new Date, - ms: ms, - easing: easyeasy, - from: from, - diff: diff, - to: to, - el: element, - t: {x: 0, y: 0} - }); - R.is(callback, "function") && (element._ac = setTimeout(function () { - callback.call(element); - }, ms)); - animationElements[length] == 1 && setTimeout(animation); - } - return this; - }; - elproto.stop = function () { - for (var i = 0; i < animationElements.length; i++) { - animationElements[i].el.id == this.id && animationElements.splice(i--, 1); - } - for (i = 0, ii = this.timeouts && this.timeouts.length; i < ii; i++) { - clearTimeout(this.timeouts[i]); - } - this.timeouts = []; - clearTimeout(this._ac); - delete this._ac; - return this; - }; - elproto.translate = function (x, y) { - return this.attr({translation: x + " " + y}); - }; - elproto[toString] = function () { - return "Rapha\xebl\u2019s object"; - }; - R.ae = animationElements; - - // Set - var Set = function (items) { - this.items = []; - this[length] = 0; - this.type = "set"; - if (items) { - for (var i = 0, ii = items[length]; i < ii; i++) { - if (items[i] && (items[i].constructor == Element || items[i].constructor == Set)) { - this[this.items[length]] = this.items[this.items[length]] = items[i]; - this[length]++; - } - } - } - }; - Set[proto][push] = function () { - var item, - len; - for (var i = 0, ii = arguments[length]; i < ii; i++) { - item = arguments[i]; - if (item && (item.constructor == Element || item.constructor == Set)) { - len = this.items[length]; - this[len] = this.items[len] = item; - this[length]++; - } - } - return this; - }; - Set[proto].pop = function () { - delete this[this[length]--]; - return this.items.pop(); - }; - for (var method in elproto) if (elproto[has](method)) { - Set[proto][method] = (function (methodname) { - return function () { - for (var i = 0, ii = this.items[length]; i < ii; i++) { - this.items[i][methodname][apply](this.items[i], arguments); - } - return this; - }; - })(method); - } - Set[proto].attr = function (name, value) { - if (name && R.is(name, array) && R.is(name[0], "object")) { - for (var j = 0, jj = name[length]; j < jj; j++) { - this.items[j].attr(name[j]); - } - } else { - for (var i = 0, ii = this.items[length]; i < ii; i++) { - this.items[i].attr(name, value); - } - } - return this; - }; - Set[proto].animate = function (params, ms, easing, callback) { - (R.is(easing, "function") || !easing) && (callback = easing || null); - var len = this.items[length], - i = len, - item, - set = this, - collector; - callback && (collector = function () { - !--len && callback.call(set); - }); - easing = R.is(easing, string) ? easing : collector; - item = this.items[--i].animate(params, ms, easing, collector); - while (i--) { - this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, params, ms, easing, collector); - } - return this; - }; - Set[proto].insertAfter = function (el) { - var i = this.items[length]; - while (i--) { - this.items[i].insertAfter(el); - } - return this; - }; - Set[proto].getBBox = function () { - var x = [], - y = [], - w = [], - h = []; - for (var i = this.items[length]; i--;) { - var box = this.items[i].getBBox(); - x[push](box.x); - y[push](box.y); - w[push](box.x + box.width); - h[push](box.y + box.height); - } - x = mmin[apply](0, x); - y = mmin[apply](0, y); - return { - x: x, - y: y, - width: mmax[apply](0, w) - x, - height: mmax[apply](0, h) - y - }; - }; - Set[proto].clone = function (s) { - s = new Set; - for (var i = 0, ii = this.items[length]; i < ii; i++) { - s[push](this.items[i].clone()); - } - return s; - }; - - R.registerFont = function (font) { - if (!font.face) { - return font; - } - this.fonts = this.fonts || {}; - var fontcopy = { - w: font.w, - face: {}, - glyphs: {} - }, - family = font.face["font-family"]; - for (var prop in font.face) if (font.face[has](prop)) { - fontcopy.face[prop] = font.face[prop]; - } - if (this.fonts[family]) { - this.fonts[family][push](fontcopy); - } else { - this.fonts[family] = [fontcopy]; - } - if (!font.svg) { - fontcopy.face["units-per-em"] = toInt(font.face["units-per-em"], 10); - for (var glyph in font.glyphs) if (font.glyphs[has](glyph)) { - var path = font.glyphs[glyph]; - fontcopy.glyphs[glyph] = { - w: path.w, - k: {}, - d: path.d && "M" + path.d[rp](/[mlcxtrv]/g, function (command) { - return {l: "L", c: "C", x: "z", t: "m", r: "l", v: "c"}[command] || "M"; - }) + "z" - }; - if (path.k) { - for (var k in path.k) if (path[has](k)) { - fontcopy.glyphs[glyph].k[k] = path.k[k]; - } - } - } - } - return font; - }; - paperproto.getFont = function (family, weight, style, stretch) { - stretch = stretch || "normal"; - style = style || "normal"; - weight = +weight || {normal: 400, bold: 700, lighter: 300, bolder: 800}[weight] || 400; - if (!R.fonts) { - return; - } - var font = R.fonts[family]; - if (!font) { - var name = new RegExp("(^|\\s)" + family[rp](/[^\w\d\s+!~.:_-]/g, E) + "(\\s|$)", "i"); - for (var fontName in R.fonts) if (R.fonts[has](fontName)) { - if (name.test(fontName)) { - font = R.fonts[fontName]; - break; - } - } - } - var thefont; - if (font) { - for (var i = 0, ii = font[length]; i < ii; i++) { - thefont = font[i]; - if (thefont.face["font-weight"] == weight && (thefont.face["font-style"] == style || !thefont.face["font-style"]) && thefont.face["font-stretch"] == stretch) { - break; - } - } - } - return thefont; - }; - paperproto.print = function (x, y, string, font, size, origin, letter_spacing) { - origin = origin || "middle"; // baseline|middle - letter_spacing = mmax(mmin(letter_spacing || 0, 1), -1); - var out = this.set(), - letters = Str(string)[split](E), - shift = 0, - path = E, - scale; - R.is(font, string) && (font = this.getFont(font)); - if (font) { - scale = (size || 16) / font.face["units-per-em"]; - var bb = font.face.bbox.split(separator), - top = +bb[0], - height = +bb[1] + (origin == "baseline" ? bb[3] - bb[1] + (+font.face.descent) : (bb[3] - bb[1]) / 2); - for (var i = 0, ii = letters[length]; i < ii; i++) { - var prev = i && font.glyphs[letters[i - 1]] || {}, - curr = font.glyphs[letters[i]]; - shift += i ? (prev.w || font.w) + (prev.k && prev.k[letters[i]] || 0) + (font.w * letter_spacing) : 0; - curr && curr.d && out[push](this.path(curr.d).attr({fill: "#000", stroke: "none", translation: [shift, 0]})); - } - out.scale(scale, scale, top, height).translate(x - top, y - height); - } - return out; - }; - - R.format = function (token, params) { - var args = R.is(params, array) ? [0][concat](params) : arguments; - token && R.is(token, string) && args[length] - 1 && (token = token[rp](formatrg, function (str, i) { - return args[++i] == null ? E : args[i]; - })); - return token || E; - }; - R.ninja = function () { - oldRaphael.was ? (win.Raphael = oldRaphael.is) : delete Raphael; - return R; - }; - R.el = elproto; - R.st = Set[proto]; - - oldRaphael.was ? (win.Raphael = R) : (Raphael = R); -})(); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/rgbcolor.js b/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/rgbcolor.js deleted file mode 100755 index 04423f29b7..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/graphics/rgbcolor.js +++ /dev/null @@ -1,288 +0,0 @@ -/** - * A class to parse color values - * @author Stoyan Stefanov - * @link http://www.phpied.com/rgb-color-parser-in-javascript/ - * @license Use it if you like it - */ -function RGBColor(color_string) -{ - this.ok = false; - - // strip any leading # - if (color_string.charAt(0) == '#') { // remove # if any - color_string = color_string.substr(1,6); - } - - color_string = color_string.replace(/ /g,''); - color_string = color_string.toLowerCase(); - - // before getting into regexps, try simple matches - // and overwrite the input - var simple_colors = { - aliceblue: 'f0f8ff', - antiquewhite: 'faebd7', - aqua: '00ffff', - aquamarine: '7fffd4', - azure: 'f0ffff', - beige: 'f5f5dc', - bisque: 'ffe4c4', - black: '000000', - blanchedalmond: 'ffebcd', - blue: '0000ff', - blueviolet: '8a2be2', - brown: 'a52a2a', - burlywood: 'deb887', - cadetblue: '5f9ea0', - chartreuse: '7fff00', - chocolate: 'd2691e', - coral: 'ff7f50', - cornflowerblue: '6495ed', - cornsilk: 'fff8dc', - crimson: 'dc143c', - cyan: '00ffff', - darkblue: '00008b', - darkcyan: '008b8b', - darkgoldenrod: 'b8860b', - darkgray: 'a9a9a9', - darkgreen: '006400', - darkkhaki: 'bdb76b', - darkmagenta: '8b008b', - darkolivegreen: '556b2f', - darkorange: 'ff8c00', - darkorchid: '9932cc', - darkred: '8b0000', - darksalmon: 'e9967a', - darkseagreen: '8fbc8f', - darkslateblue: '483d8b', - darkslategray: '2f4f4f', - darkturquoise: '00ced1', - darkviolet: '9400d3', - deeppink: 'ff1493', - deepskyblue: '00bfff', - dimgray: '696969', - dodgerblue: '1e90ff', - feldspar: 'd19275', - firebrick: 'b22222', - floralwhite: 'fffaf0', - forestgreen: '228b22', - fuchsia: 'ff00ff', - gainsboro: 'dcdcdc', - ghostwhite: 'f8f8ff', - gold: 'ffd700', - goldenrod: 'daa520', - gray: '808080', - green: '008000', - greenyellow: 'adff2f', - honeydew: 'f0fff0', - hotpink: 'ff69b4', - indianred : 'cd5c5c', - indigo : '4b0082', - ivory: 'fffff0', - khaki: 'f0e68c', - lavender: 'e6e6fa', - lavenderblush: 'fff0f5', - lawngreen: '7cfc00', - lemonchiffon: 'fffacd', - lightblue: 'add8e6', - lightcoral: 'f08080', - lightcyan: 'e0ffff', - lightgoldenrodyellow: 'fafad2', - lightgrey: 'd3d3d3', - lightgreen: '90ee90', - lightpink: 'ffb6c1', - lightsalmon: 'ffa07a', - lightseagreen: '20b2aa', - lightskyblue: '87cefa', - lightslateblue: '8470ff', - lightslategray: '778899', - lightsteelblue: 'b0c4de', - lightyellow: 'ffffe0', - lime: '00ff00', - limegreen: '32cd32', - linen: 'faf0e6', - magenta: 'ff00ff', - maroon: '800000', - mediumaquamarine: '66cdaa', - mediumblue: '0000cd', - mediumorchid: 'ba55d3', - mediumpurple: '9370d8', - mediumseagreen: '3cb371', - mediumslateblue: '7b68ee', - mediumspringgreen: '00fa9a', - mediumturquoise: '48d1cc', - mediumvioletred: 'c71585', - midnightblue: '191970', - mintcream: 'f5fffa', - mistyrose: 'ffe4e1', - moccasin: 'ffe4b5', - navajowhite: 'ffdead', - navy: '000080', - oldlace: 'fdf5e6', - olive: '808000', - olivedrab: '6b8e23', - orange: 'ffa500', - orangered: 'ff4500', - orchid: 'da70d6', - palegoldenrod: 'eee8aa', - palegreen: '98fb98', - paleturquoise: 'afeeee', - palevioletred: 'd87093', - papayawhip: 'ffefd5', - peachpuff: 'ffdab9', - peru: 'cd853f', - pink: 'ffc0cb', - plum: 'dda0dd', - powderblue: 'b0e0e6', - purple: '800080', - red: 'ff0000', - rosybrown: 'bc8f8f', - royalblue: '4169e1', - saddlebrown: '8b4513', - salmon: 'fa8072', - sandybrown: 'f4a460', - seagreen: '2e8b57', - seashell: 'fff5ee', - sienna: 'a0522d', - silver: 'c0c0c0', - skyblue: '87ceeb', - slateblue: '6a5acd', - slategray: '708090', - snow: 'fffafa', - springgreen: '00ff7f', - steelblue: '4682b4', - tan: 'd2b48c', - teal: '008080', - thistle: 'd8bfd8', - tomato: 'ff6347', - turquoise: '40e0d0', - violet: 'ee82ee', - violetred: 'd02090', - wheat: 'f5deb3', - white: 'ffffff', - whitesmoke: 'f5f5f5', - yellow: 'ffff00', - yellowgreen: '9acd32' - }; - for (var key in simple_colors) { - if (color_string == key) { - color_string = simple_colors[key]; - } - } - // emd of simple type-in colors - - // array of color definition objects - var color_defs = [ - { - re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, - example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], - process: function (bits){ - return [ - parseInt(bits[1]), - parseInt(bits[2]), - parseInt(bits[3]) - ]; - } - }, - { - re: /^(\w{2})(\w{2})(\w{2})$/, - example: ['#00ff00', '336699'], - process: function (bits){ - return [ - parseInt(bits[1], 16), - parseInt(bits[2], 16), - parseInt(bits[3], 16) - ]; - } - }, - { - re: /^(\w{1})(\w{1})(\w{1})$/, - example: ['#fb0', 'f0f'], - process: function (bits){ - return [ - parseInt(bits[1] + bits[1], 16), - parseInt(bits[2] + bits[2], 16), - parseInt(bits[3] + bits[3], 16) - ]; - } - } - ]; - - // search through the definitions to find a match - for (var i = 0; i < color_defs.length; i++) { - var re = color_defs[i].re; - var processor = color_defs[i].process; - var bits = re.exec(color_string); - if (bits) { - channels = processor(bits); - this.r = channels[0]; - this.g = channels[1]; - this.b = channels[2]; - this.ok = true; - } - - } - - // validate/cleanup values - this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r); - this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g); - this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b); - - // some getters - this.toRGB = function () { - return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')'; - } - this.toHex = function () { - var r = this.r.toString(16); - var g = this.g.toString(16); - var b = this.b.toString(16); - if (r.length == 1) r = '0' + r; - if (g.length == 1) g = '0' + g; - if (b.length == 1) b = '0' + b; - return '#' + r + g + b; - } - - // help - this.getHelpXML = function () { - - var examples = new Array(); - // add regexps - for (var i = 0; i < color_defs.length; i++) { - var example = color_defs[i].example; - for (var j = 0; j < example.length; j++) { - examples[examples.length] = example[j]; - } - } - // add type-in colors - for (var sc in simple_colors) { - examples[examples.length] = sc; - } - - var xml = document.createElement('ul'); - xml.setAttribute('id', 'rgbcolor-examples'); - for (var i = 0; i < examples.length; i++) { - try { - var list_item = document.createElement('li'); - var list_color = new RGBColor(examples[i]); - var example_div = document.createElement('div'); - example_div.style.cssText = - 'margin: 3px; ' - + 'border: 1px solid black; ' - + 'background:' + list_color.toHex() + '; ' - + 'color:' + list_color.toHex() - ; - example_div.appendChild(document.createTextNode('test')); - var list_item_value = document.createTextNode( - ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex() - ); - list_item.appendChild(example_div); - list_item.appendChild(list_item_value); - xml.appendChild(list_item); - - } catch(e){} - } - return xml; - - } - -} - diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.js b/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.js deleted file mode 100755 index 35b8d1b577..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.js +++ /dev/null @@ -1,11612 +0,0 @@ -/** - * @summary DataTables - * @description Paginate, search and sort HTML tables - * @version 1.9.0 - * @file jquery.dataTables.js - * @author Allan Jardine (www.sprymedia.co.uk) - * @contact www.sprymedia.co.uk/contact - * - * @copyright Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - * - * For details please refer to: http://www.datatables.net - */ - -/*jslint evil: true, undef: true, browser: true */ -/*globals $, jQuery,_fnExternApiFunc,_fnInitialise,_fnInitComplete,_fnLanguageCompat,_fnAddColumn,_fnColumnOptions,_fnAddData,_fnCreateTr,_fnGatherData,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnServerParams,_fnAddOptionsHtml,_fnFeatureHtmlTable,_fnScrollDraw,_fnAdjustColumnSizing,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnBuildSearchArray,_fnBuildSearchRow,_fnFilterCreateSearch,_fnDataToSearch,_fnSort,_fnSortAttachListener,_fnSortingClasses,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnFeatureHtmlLength,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnNodeToDataIndex,_fnVisbleColumns,_fnCalculateEnd,_fnConvertToWidth,_fnCalculateColumnWidths,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnDetectType,_fnSettingsFromNode,_fnGetDataMaster,_fnGetTrNodes,_fnGetTdNodes,_fnEscapeRegex,_fnDeleteIndex,_fnReOrderIndex,_fnColumnOrdering,_fnLog,_fnClearTable,_fnSaveState,_fnLoadState,_fnCreateCookie,_fnReadCookie,_fnDetectHeader,_fnGetUniqueThs,_fnScrollBarWidth,_fnApplyToChildren,_fnMap,_fnGetRowData,_fnGetCellData,_fnSetCellData,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnApplyColumnDefs,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnJsonString,_fnRender,_fnNodeToColumnIndex*/ - -(/** @lends */function($, window, document, undefined) { - /** - * DataTables is a plug-in for the jQuery Javascript library. It is a - * highly flexible tool, based upon the foundations of progressive - * enhancement, which will add advanced interaction controls to any - * HTML table. For a full list of features please refer to - * DataTables.net. - * - * Note that the DataTable object is not a global variable but is - * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which - * it may be accessed. - * - * @class - * @param {object} [oInit={}] Configuration object for DataTables. Options - * are defined by {@link DataTable.defaults} - * @requires jQuery 1.3+ - * - * @example - * // Basic initialisation - * $(document).ready( function { - * $('#example').dataTable(); - * } ); - * - * @example - * // Initialisation with configuration options - in this case, disable - * // pagination and sorting. - * $(document).ready( function { - * $('#example').dataTable( { - * "bPaginate": false, - * "bSort": false - * } ); - * } ); - */ - var DataTable = function( oInit ) - { - - - /** - * Add a column to the list used for the table with default values - * @param {object} oSettings dataTables settings object - * @param {node} nTh The th element for this column - * @memberof DataTable#oApi - */ - function _fnAddColumn( oSettings, nTh ) - { - var oDefaults = DataTable.defaults.columns; - var iCol = oSettings.aoColumns.length; - var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { - "sSortingClass": oSettings.oClasses.sSortable, - "sSortingClassJUI": oSettings.oClasses.sSortJUI, - "nTh": nTh ? nTh : document.createElement('th'), - "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', - "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], - "mDataProp": oDefaults.mDataProp ? oDefaults.oDefaults : iCol - } ); - oSettings.aoColumns.push( oCol ); - - /* Add a column specific filter */ - if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) - { - oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); - } - else - { - var oPre = oSettings.aoPreSearchCols[ iCol ]; - - /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ - if ( oPre.bRegex === undefined ) - { - oPre.bRegex = true; - } - - if ( oPre.bSmart === undefined ) - { - oPre.bSmart = true; - } - - if ( oPre.bCaseInsensitive === undefined ) - { - oPre.bCaseInsensitive = true; - } - } - - /* Use the column options function to initialise classes etc */ - _fnColumnOptions( oSettings, iCol, null ); - } - - - /** - * Apply options for a column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column index to consider - * @param {object} oOptions object with sType, bVisible and bSearchable - * @memberof DataTable#oApi - */ - function _fnColumnOptions( oSettings, iCol, oOptions ) - { - var oCol = oSettings.aoColumns[ iCol ]; - - /* User specified column options */ - if ( oOptions !== undefined && oOptions !== null ) - { - if ( oOptions.sType !== undefined ) - { - oCol.sType = oOptions.sType; - oCol._bAutoType = false; - } - - $.extend( oCol, oOptions ); - _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); - - /* iDataSort to be applied (backwards compatibility), but aDataSort will take - * priority if defined - */ - if ( oOptions.iDataSort !== undefined ) - { - oCol.aDataSort = [ oOptions.iDataSort ]; - } - _fnMap( oCol, oOptions, "aDataSort" ); - } - - /* Cache the data get and set functions for speed */ - oCol.fnGetData = _fnGetObjectDataFn( oCol.mDataProp ); - oCol.fnSetData = _fnSetObjectDataFn( oCol.mDataProp ); - - /* Feature sorting overrides column specific when off */ - if ( !oSettings.oFeatures.bSort ) - { - oCol.bSortable = false; - } - - /* Check that the class assignment is correct for sorting */ - if ( !oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableNone; - oCol.sSortingClassJUI = ""; - } - else if ( oCol.bSortable || - ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) - { - oCol.sSortingClass = oSettings.oClasses.sSortable; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; - } - else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableAsc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; - } - else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) - { - oCol.sSortingClass = oSettings.oClasses.sSortableDesc; - oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; - } - } - - - /** - * Adjust the table column widths for new data. Note: you would probably want to - * do a redraw after calling this function! - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnAdjustColumnSizing ( oSettings ) - { - /* Not interested in doing column width calculation if autowidth is disabled */ - if ( oSettings.oFeatures.bAutoWidth === false ) - { - return false; - } - - _fnCalculateColumnWidths( oSettings ); - for ( var i=0 , iLen=oSettings.aoColumns.length ; i
              ')[0]; - oSettings.nTable.parentNode.insertBefore( nHolding, oSettings.nTable ); - - /* - * All DataTables are wrapped in a div - */ - oSettings.nTableWrapper = $('
              ')[0]; - oSettings.nTableReinsertBefore = oSettings.nTable.nextSibling; - - /* Track where we want to insert the option */ - var nInsertNode = oSettings.nTableWrapper; - - /* Loop over the user set positioning and place the elements as needed */ - var aDom = oSettings.sDom.split(''); - var nTmp, iPushFeature, cOption, nNewNode, cNext, sAttr, j; - for ( var i=0 ; i
              ')[0]; - - /* Check to see if we should append an id and/or a class name to the container */ - cNext = aDom[i+1]; - if ( cNext == "'" || cNext == '"' ) - { - sAttr = ""; - j = 2; - while ( aDom[i+j] != cNext ) - { - sAttr += aDom[i+j]; - j++; - } - - /* Replace jQuery UI constants */ - if ( sAttr == "H" ) - { - sAttr = "fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix"; - } - else if ( sAttr == "F" ) - { - sAttr = "fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix"; - } - - /* The attribute can be in the format of "#id.class", "#id" or "class" This logic - * breaks the string into parts and applies them as needed - */ - if ( sAttr.indexOf('.') != -1 ) - { - var aSplit = sAttr.split('.'); - nNewNode.id = aSplit[0].substr(1, aSplit[0].length-1); - nNewNode.className = aSplit[1]; - } - else if ( sAttr.charAt(0) == "#" ) - { - nNewNode.id = sAttr.substr(1, sAttr.length-1); - } - else - { - nNewNode.className = sAttr; - } - - i += j; /* Move along the position array */ - } - - nInsertNode.appendChild( nNewNode ); - nInsertNode = nNewNode; - } - else if ( cOption == '>' ) - { - /* End container div */ - nInsertNode = nInsertNode.parentNode; - } - else if ( cOption == 'l' && oSettings.oFeatures.bPaginate && oSettings.oFeatures.bLengthChange ) - { - /* Length */ - nTmp = _fnFeatureHtmlLength( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'f' && oSettings.oFeatures.bFilter ) - { - /* Filter */ - nTmp = _fnFeatureHtmlFilter( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'r' && oSettings.oFeatures.bProcessing ) - { - /* pRocessing */ - nTmp = _fnFeatureHtmlProcessing( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 't' ) - { - /* Table */ - nTmp = _fnFeatureHtmlTable( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'i' && oSettings.oFeatures.bInfo ) - { - /* Info */ - nTmp = _fnFeatureHtmlInfo( oSettings ); - iPushFeature = 1; - } - else if ( cOption == 'p' && oSettings.oFeatures.bPaginate ) - { - /* Pagination */ - nTmp = _fnFeatureHtmlPaginate( oSettings ); - iPushFeature = 1; - } - else if ( DataTable.ext.aoFeatures.length !== 0 ) - { - /* Plug-in features */ - var aoFeatures = DataTable.ext.aoFeatures; - for ( var k=0, kLen=aoFeatures.length ; k') : - sSearchStr==="" ? '' : sSearchStr+' '; - - var nFilter = document.createElement( 'div' ); - nFilter.className = oSettings.oClasses.sFilter; - nFilter.innerHTML = ''; - if ( !oSettings.aanFeatures.f ) - { - nFilter.id = oSettings.sTableId+'_filter'; - } - - var jqFilter = $("input", nFilter); - jqFilter.val( oPreviousSearch.sSearch.replace('"','"') ); - jqFilter.bind( 'keyup.DT', function(e) { - /* Update all other filter input elements for the new display */ - var n = oSettings.aanFeatures.f; - for ( var i=0, iLen=n.length ; i=0 ; i-- ) - { - var sData = _fnDataToSearch( _fnGetCellData( oSettings, oSettings.aiDisplay[i], iColumn, 'filter' ), - oSettings.aoColumns[iColumn].sType ); - if ( ! rpSearch.test( sData ) ) - { - oSettings.aiDisplay.splice( i, 1 ); - iIndexCorrector++; - } - } - } - - - /** - * Filter the data table based on user input and draw the table - * @param {object} oSettings dataTables settings object - * @param {string} sInput string to filter on - * @param {int} iForce optional - force a research of the master array (1) or not (undefined or 0) - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not - * @memberof DataTable#oApi - */ - function _fnFilter( oSettings, sInput, iForce, bRegex, bSmart, bCaseInsensitive ) - { - var i; - var rpSearch = _fnFilterCreateSearch( sInput, bRegex, bSmart, bCaseInsensitive ); - var oPrevSearch = oSettings.oPreviousSearch; - - /* Check if we are forcing or not - optional parameter */ - if ( !iForce ) - { - iForce = 0; - } - - /* Need to take account of custom filtering functions - always filter */ - if ( DataTable.ext.afnFiltering.length !== 0 ) - { - iForce = 1; - } - - /* - * If the input is blank - we want the full data set - */ - if ( sInput.length <= 0 ) - { - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - } - else - { - /* - * We are starting a new search or the new search string is smaller - * then the old one (i.e. delete). Search from the master array - */ - if ( oSettings.aiDisplay.length == oSettings.aiDisplayMaster.length || - oPrevSearch.sSearch.length > sInput.length || iForce == 1 || - sInput.indexOf(oPrevSearch.sSearch) !== 0 ) - { - /* Nuke the old display array - we are going to rebuild it */ - oSettings.aiDisplay.splice( 0, oSettings.aiDisplay.length); - - /* Force a rebuild of the search array */ - _fnBuildSearchArray( oSettings, 1 ); - - /* Search through all records to populate the search array - * The the oSettings.aiDisplayMaster and asDataSearch arrays have 1 to 1 - * mapping - */ - for ( i=0 ; i tag - remove it */ - sSearch = sSearch.replace(/\n/g," ").replace(/\r/g,""); - } - - return sSearch; - } - - /** - * Build a regular expression object suitable for searching a table - * @param {string} sSearch string to search for - * @param {bool} bRegex treat as a regular expression or not - * @param {bool} bSmart perform smart filtering or not - * @param {bool} bCaseInsensitive Do case insenstive matching or not - * @returns {RegExp} constructed object - * @memberof DataTable#oApi - */ - function _fnFilterCreateSearch( sSearch, bRegex, bSmart, bCaseInsensitive ) - { - var asSearch, sRegExpString; - - if ( bSmart ) - { - /* Generate the regular expression to use. Something along the lines of: - * ^(?=.*?\bone\b)(?=.*?\btwo\b)(?=.*?\bthree\b).*$ - */ - asSearch = bRegex ? sSearch.split( ' ' ) : _fnEscapeRegex( sSearch ).split( ' ' ); - sRegExpString = '^(?=.*?'+asSearch.join( ')(?=.*?' )+').*$'; - return new RegExp( sRegExpString, bCaseInsensitive ? "i" : "" ); - } - else - { - sSearch = bRegex ? sSearch : _fnEscapeRegex( sSearch ); - return new RegExp( sSearch, bCaseInsensitive ? "i" : "" ); - } - } - - - /** - * Convert raw data into something that the user can search on - * @param {string} sData data to be modified - * @param {string} sType data type - * @returns {string} search string - * @memberof DataTable#oApi - */ - function _fnDataToSearch ( sData, sType ) - { - if ( typeof DataTable.ext.ofnSearch[sType] === "function" ) - { - return DataTable.ext.ofnSearch[sType]( sData ); - } - else if ( sType == "html" ) - { - return sData.replace(/[\r\n]/g," ").replace( /<.*?>/g, "" ); - } - else if ( typeof sData === "string" ) - { - return sData.replace(/[\r\n]/g," "); - } - else if ( sData === null ) - { - return ''; - } - return sData; - } - - - /** - * scape a string stuch that it can be used in a regular expression - * @param {string} sVal string to escape - * @returns {string} escaped string - * @memberof DataTable#oApi - */ - function _fnEscapeRegex ( sVal ) - { - var acEscape = [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^' ]; - var reReplace = new RegExp( '(\\' + acEscape.join('|\\') + ')', 'g' ); - return sVal.replace(reReplace, '\\$1'); - } - - - - /** - * Generate the node required for the info display - * @param {object} oSettings dataTables settings object - * @returns {node} Information element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlInfo ( oSettings ) - { - var nInfo = document.createElement( 'div' ); - nInfo.className = oSettings.oClasses.sInfo; - - /* Actions that are to be taken once only for this feature */ - if ( !oSettings.aanFeatures.i ) - { - /* Add draw callback */ - oSettings.aoDrawCallback.push( { - "fn": _fnUpdateInfo, - "sName": "information" - } ); - - /* Add id */ - nInfo.id = oSettings.sTableId+'_info'; - } - oSettings.nTable.setAttribute( 'aria-describedby', oSettings.sTableId+'_info' ); - - return nInfo; - } - - - /** - * Update the information elements in the display - * @param {object} oSettings dataTables settings object - * @memberof DataTable#oApi - */ - function _fnUpdateInfo ( oSettings ) - { - /* Show information about the table */ - if ( !oSettings.oFeatures.bInfo || oSettings.aanFeatures.i.length === 0 ) - { - return; - } - - var - iStart = oSettings._iDisplayStart+1, iEnd = oSettings.fnDisplayEnd(), - iMax = oSettings.fnRecordsTotal(), iTotal = oSettings.fnRecordsDisplay(), - sStart = oSettings.fnFormatNumber( iStart ), sEnd = oSettings.fnFormatNumber( iEnd ), - sMax = oSettings.fnFormatNumber( iMax ), sTotal = oSettings.fnFormatNumber( iTotal ), - sOut; - - /* When infinite scrolling, we are always starting at 1. _iDisplayStart is used only - * internally - */ - if ( oSettings.oScroll.bInfinite ) - { - sStart = oSettings.fnFormatNumber( 1 ); - } - - if ( oSettings.fnRecordsDisplay() === 0 && - oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() ) - { - /* Empty record set */ - sOut = oSettings.oLanguage.sInfoEmpty+ oSettings.oLanguage.sInfoPostFix; - } - else if ( oSettings.fnRecordsDisplay() === 0 ) - { - /* Rmpty record set after filtering */ - sOut = oSettings.oLanguage.sInfoEmpty +' '+ - oSettings.oLanguage.sInfoFiltered.replace('_MAX_', sMax)+ - oSettings.oLanguage.sInfoPostFix; - } - else if ( oSettings.fnRecordsDisplay() == oSettings.fnRecordsTotal() ) - { - /* Normal record set */ - sOut = oSettings.oLanguage.sInfo. - replace('_START_', sStart). - replace('_END_', sEnd). - replace('_TOTAL_', sTotal)+ - oSettings.oLanguage.sInfoPostFix; - } - else - { - /* Record set after filtering */ - sOut = oSettings.oLanguage.sInfo. - replace('_START_', sStart). - replace('_END_', sEnd). - replace('_TOTAL_', sTotal) +' '+ - oSettings.oLanguage.sInfoFiltered.replace('_MAX_', - oSettings.fnFormatNumber(oSettings.fnRecordsTotal()))+ - oSettings.oLanguage.sInfoPostFix; - } - - if ( oSettings.oLanguage.fnInfoCallback !== null ) - { - sOut = oSettings.oLanguage.fnInfoCallback.call( oSettings.oInstance, - oSettings, iStart, iEnd, iMax, iTotal, sOut ); - } - - var n = oSettings.aanFeatures.i; - for ( var i=0, iLen=n.length ; i'; - var i, iLen; - var aLengthMenu = oSettings.aLengthMenu; - - if ( aLengthMenu.length == 2 && typeof aLengthMenu[0] === 'object' && - typeof aLengthMenu[1] === 'object' ) - { - for ( i=0, iLen=aLengthMenu[0].length ; i'+aLengthMenu[1][i]+''; - } - } - else - { - for ( i=0, iLen=aLengthMenu.length ; i'+aLengthMenu[i]+''; - } - } - sStdMenu += ''; - - var nLength = document.createElement( 'div' ); - if ( !oSettings.aanFeatures.l ) - { - nLength.id = oSettings.sTableId+'_length'; - } - nLength.className = oSettings.oClasses.sLength; - nLength.innerHTML = ''; - - /* - * Set the length to the current display length - thanks to Andrea Pavlovic for this fix, - * and Stefan Skopnik for fixing the fix! - */ - $('select option[value="'+oSettings._iDisplayLength+'"]', nLength).attr("selected", true); - - $('select', nLength).bind( 'change.DT', function(e) { - var iVal = $(this).val(); - - /* Update all other length options for the new display */ - var n = oSettings.aanFeatures.l; - for ( i=0, iLen=n.length ; i oSettings.aiDisplay.length || - oSettings._iDisplayLength == -1 ) - { - oSettings._iDisplayEnd = oSettings.aiDisplay.length; - } - else - { - oSettings._iDisplayEnd = oSettings._iDisplayStart + oSettings._iDisplayLength; - } - } - } - - - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Note that most of the paging logic is done in - * DataTable.ext.oPagination - */ - - /** - * Generate the node required for default pagination - * @param {object} oSettings dataTables settings object - * @returns {node} Pagination feature node - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlPaginate ( oSettings ) - { - if ( oSettings.oScroll.bInfinite ) - { - return null; - } - - var nPaginate = document.createElement( 'div' ); - nPaginate.className = oSettings.oClasses.sPaging+oSettings.sPaginationType; - - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnInit( oSettings, nPaginate, - function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - ); - - /* Add a draw callback for the pagination on first instance, to update the paging display */ - if ( !oSettings.aanFeatures.p ) - { - oSettings.aoDrawCallback.push( { - "fn": function( oSettings ) { - DataTable.ext.oPagination[ oSettings.sPaginationType ].fnUpdate( oSettings, function( oSettings ) { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } ); - }, - "sName": "pagination" - } ); - } - return nPaginate; - } - - - /** - * Alter the display settings to change the page - * @param {object} oSettings dataTables settings object - * @param {string|int} mAction Paging action to take: "first", "previous", "next" or "last" - * or page number to jump to (integer) - * @returns {bool} true page has changed, false - no change (no effect) eg 'first' on page 1 - * @memberof DataTable#oApi - */ - function _fnPageChange ( oSettings, mAction ) - { - var iOldStart = oSettings._iDisplayStart; - - if ( typeof mAction === "number" ) - { - oSettings._iDisplayStart = mAction * oSettings._iDisplayLength; - if ( oSettings._iDisplayStart > oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "first" ) - { - oSettings._iDisplayStart = 0; - } - else if ( mAction == "previous" ) - { - oSettings._iDisplayStart = oSettings._iDisplayLength>=0 ? - oSettings._iDisplayStart - oSettings._iDisplayLength : - 0; - - /* Correct for underrun */ - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "next" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - /* Make sure we are not over running the display array */ - if ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() ) - { - oSettings._iDisplayStart += oSettings._iDisplayLength; - } - } - else - { - oSettings._iDisplayStart = 0; - } - } - else if ( mAction == "last" ) - { - if ( oSettings._iDisplayLength >= 0 ) - { - var iPages = parseInt( (oSettings.fnRecordsDisplay()-1) / oSettings._iDisplayLength, 10 ) + 1; - oSettings._iDisplayStart = (iPages-1) * oSettings._iDisplayLength; - } - else - { - oSettings._iDisplayStart = 0; - } - } - else - { - _fnLog( oSettings, 0, "Unknown paging action: "+mAction ); - } - $(oSettings.oInstance).trigger('page', oSettings); - - return iOldStart != oSettings._iDisplayStart; - } - - - - /** - * Generate the node required for the processing node - * @param {object} oSettings dataTables settings object - * @returns {node} Processing element - * @memberof DataTable#oApi - */ - function _fnFeatureHtmlProcessing ( oSettings ) - { - var nProcessing = document.createElement( 'div' ); - - if ( !oSettings.aanFeatures.r ) - { - nProcessing.id = oSettings.sTableId+'_processing'; - } - nProcessing.innerHTML = oSettings.oLanguage.sProcessing; - nProcessing.className = oSettings.oClasses.sProcessing; - oSettings.nTable.parentNode.insertBefore( nProcessing, oSettings.nTable ); - - return nProcessing; - } - - - /** - * Display or hide the processing indicator - * @param {object} oSettings dataTables settings object - * @param {bool} bShow Show the processing indicator (true) or not (false) - * @memberof DataTable#oApi - */ - function _fnProcessingDisplay ( oSettings, bShow ) - { - if ( oSettings.oFeatures.bProcessing ) - { - var an = oSettings.aanFeatures.r; - for ( var i=0, iLen=an.length ; i - $(oSettings.nTable).height() - oSettings.oScroll.iLoadGap ) - { - /* Only do the redraw if we have to - we might be at the end of the data */ - if ( oSettings.fnDisplayEnd() < oSettings.fnRecordsDisplay() ) - { - _fnPageChange( oSettings, 'next' ); - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - } - } ); - } - - oSettings.nScrollHead = nScrollHead; - oSettings.nScrollFoot = nScrollFoot; - - return nScroller; - } - - - /** - * Update the various tables for resizing. It's a bit of a pig this function, but - * basically the idea to: - * 1. Re-create the table inside the scrolling div - * 2. Take live measurements from the DOM - * 3. Apply the measurements - * 4. Clean up - * @param {object} o dataTables settings object - * @returns {node} Node to add to the DOM - * @memberof DataTable#oApi - */ - function _fnScrollDraw ( o ) - { - var - nScrollHeadInner = o.nScrollHead.getElementsByTagName('div')[0], - nScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0], - nScrollBody = o.nTable.parentNode, - i, iLen, j, jLen, anHeadToSize, anHeadSizers, anFootSizers, anFootToSize, oStyle, iVis, - iWidth, aApplied=[], iSanityWidth, - nScrollFootInner = (o.nTFoot !== null) ? o.nScrollFoot.getElementsByTagName('div')[0] : null, - nScrollFootTable = (o.nTFoot !== null) ? nScrollFootInner.getElementsByTagName('table')[0] : null, - ie67 = $.browser.msie && $.browser.version <= 7; - - /* - * 1. Re-create the table inside the scrolling div - */ - - /* Remove the old minimised thead and tfoot elements in the inner table */ - var nTheadSize = o.nTable.getElementsByTagName('thead'); - if ( nTheadSize.length > 0 ) - { - o.nTable.removeChild( nTheadSize[0] ); - } - - var nTfootSize; - if ( o.nTFoot !== null ) - { - /* Remove the old minimised footer element in the cloned header */ - nTfootSize = o.nTable.getElementsByTagName('tfoot'); - if ( nTfootSize.length > 0 ) - { - o.nTable.removeChild( nTfootSize[0] ); - } - } - - /* Clone the current header and footer elements and then place it into the inner table */ - nTheadSize = o.nTHead.cloneNode(true); - o.nTable.insertBefore( nTheadSize, o.nTable.childNodes[0] ); - - if ( o.nTFoot !== null ) - { - nTfootSize = o.nTFoot.cloneNode(true); - o.nTable.insertBefore( nTfootSize, o.nTable.childNodes[1] ); - } - - /* - * 2. Take live measurements from the DOM - do not alter the DOM itself! - */ - - /* Remove old sizing and apply the calculated column widths - * Get the unique column headers in the newly created (cloned) header. We want to apply the - * calclated sizes to this header - */ - if ( o.oScroll.sX === "" ) - { - nScrollBody.style.width = '100%'; - nScrollHeadInner.parentNode.style.width = '100%'; - } - - var nThs = _fnGetUniqueThs( o, nTheadSize ); - for ( i=0, iLen=nThs.length ; i nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( $(o.nTable).outerWidth()-o.oScroll.iBarWidth ); - } - } - else - { - if ( o.oScroll.sXInner !== "" ) - { - /* x scroll inner has been given - use it */ - o.nTable.style.width = _fnStringToCss(o.oScroll.sXInner); - } - else if ( iSanityWidth == $(nScrollBody).width() && - $(nScrollBody).height() < $(o.nTable).height() ) - { - /* There is y-scrolling - try to take account of the y scroll bar */ - o.nTable.style.width = _fnStringToCss( iSanityWidth-o.oScroll.iBarWidth ); - if ( $(o.nTable).outerWidth() > iSanityWidth-o.oScroll.iBarWidth ) - { - /* Not possible to take account of it */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - else - { - /* All else fails */ - o.nTable.style.width = _fnStringToCss( iSanityWidth ); - } - } - - /* Recalculate the sanity width - now that we've applied the required width, before it was - * a temporary variable. This is required because the column width calculation is done - * before this table DOM is created. - */ - iSanityWidth = $(o.nTable).outerWidth(); - - /* We want the hidden header to have zero height, so remove padding and borders. Then - * set the width based on the real headers - */ - anHeadToSize = o.nTHead.getElementsByTagName('tr'); - anHeadSizers = nTheadSize.getElementsByTagName('tr'); - - _fnApplyToChildren( function(nSizer, nToSize) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - - iWidth = $(nSizer).width(); - nToSize.style.width = _fnStringToCss( iWidth ); - aApplied.push( iWidth ); - }, anHeadSizers, anHeadToSize ); - $(anHeadSizers).height(0); - - if ( o.nTFoot !== null ) - { - /* Clone the current footer and then place it into the body table as a "hidden header" */ - anFootSizers = nTfootSize.getElementsByTagName('tr'); - anFootToSize = o.nTFoot.getElementsByTagName('tr'); - - _fnApplyToChildren( function(nSizer, nToSize) { - oStyle = nSizer.style; - oStyle.paddingTop = "0"; - oStyle.paddingBottom = "0"; - oStyle.borderTopWidth = "0"; - oStyle.borderBottomWidth = "0"; - oStyle.height = 0; - - iWidth = $(nSizer).width(); - nToSize.style.width = _fnStringToCss( iWidth ); - aApplied.push( iWidth ); - }, anFootSizers, anFootToSize ); - $(anFootSizers).height(0); - } - - /* - * 3. Apply the measurements - */ - - /* "Hide" the header and footer that we used for the sizing. We want to also fix their width - * to what they currently are - */ - _fnApplyToChildren( function(nSizer) { - nSizer.innerHTML = ""; - nSizer.style.width = _fnStringToCss( aApplied.shift() ); - }, anHeadSizers ); - - if ( o.nTFoot !== null ) - { - _fnApplyToChildren( function(nSizer) { - nSizer.innerHTML = ""; - nSizer.style.width = _fnStringToCss( aApplied.shift() ); - }, anFootSizers ); - } - - /* Sanity check that the table is of a sensible width. If not then we are going to get - * misalignment - try to prevent this by not allowing the table to shrink below its min width - */ - if ( $(o.nTable).outerWidth() < iSanityWidth ) - { - /* The min width depends upon if we have a vertical scrollbar visible or not */ - var iCorrection = ((nScrollBody.scrollHeight > nScrollBody.offsetHeight || - $(nScrollBody).css('overflow-y') == "scroll")) ? - iSanityWidth+o.oScroll.iBarWidth : iSanityWidth; - - /* IE6/7 are a law unto themselves... */ - if ( ie67 && (nScrollBody.scrollHeight > - nScrollBody.offsetHeight || $(nScrollBody).css('overflow-y') == "scroll") ) - { - o.nTable.style.width = _fnStringToCss( iCorrection-o.oScroll.iBarWidth ); - } - - /* Apply the calculated minimum width to the table wrappers */ - nScrollBody.style.width = _fnStringToCss( iCorrection ); - nScrollHeadInner.parentNode.style.width = _fnStringToCss( iCorrection ); - - if ( o.nTFoot !== null ) - { - nScrollFootInner.parentNode.style.width = _fnStringToCss( iCorrection ); - } - - /* And give the user a warning that we've stopped the table getting too small */ - if ( o.oScroll.sX === "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. The table has been drawn at its minimum possible width." ); - } - else if ( o.oScroll.sXInner !== "" ) - { - _fnLog( o, 1, "The table cannot fit into the current element which will cause column"+ - " misalignment. Increase the sScrollXInner value or remove it to allow automatic"+ - " calculation" ); - } - } - else - { - nScrollBody.style.width = _fnStringToCss( '100%' ); - nScrollHeadInner.parentNode.style.width = _fnStringToCss( '100%' ); - - if ( o.nTFoot !== null ) - { - nScrollFootInner.parentNode.style.width = _fnStringToCss( '100%' ); - } - } - - - /* - * 4. Clean up - */ - if ( o.oScroll.sY === "" ) - { - /* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting - * the scrollbar height from the visible display, rather than adding it on. We need to - * set the height in order to sort this. Don't want to do it in any other browsers. - */ - if ( ie67 ) - { - nScrollBody.style.height = _fnStringToCss( o.nTable.offsetHeight+o.oScroll.iBarWidth ); - } - } - - if ( o.oScroll.sY !== "" && o.oScroll.bCollapse ) - { - nScrollBody.style.height = _fnStringToCss( o.oScroll.sY ); - - var iExtra = (o.oScroll.sX !== "" && o.nTable.offsetWidth > nScrollBody.offsetWidth) ? - o.oScroll.iBarWidth : 0; - if ( o.nTable.offsetHeight < nScrollBody.offsetHeight ) - { - nScrollBody.style.height = _fnStringToCss( $(o.nTable).height()+iExtra ); - } - } - - /* Finally set the width's of the header and footer tables */ - var iOuterWidth = $(o.nTable).outerWidth(); - nScrollHeadTable.style.width = _fnStringToCss( iOuterWidth ); - nScrollHeadInner.style.width = _fnStringToCss( iOuterWidth ); - - if ( o.nTFoot !== null ) - { - nScrollFootInner.style.width = _fnStringToCss( o.nTable.offsetWidth ); - nScrollFootTable.style.width = _fnStringToCss( o.nTable.offsetWidth ); - } - - /* If sorting or filtering has occurred, jump the scrolling back to the top */ - if ( o.bSorted || o.bFiltered ) - { - nScrollBody.scrollTop = 0; - } - } - - - /** - * Apply a given function to the display child nodes of an element array (typically - * TD children of TR rows - * @param {function} fn Method to apply to the objects - * @param array {nodes} an1 List of elements to look through for display children - * @param array {nodes} an2 Another list (identical structure to the first) - optional - * @memberof DataTable#oApi - */ - function _fnApplyToChildren( fn, an1, an2 ) - { - for ( var i=0, iLen=an1.length ; itd', nCalcTmp); - } - - /* Apply custom sizing to the cloned header */ - var nThs = _fnGetUniqueThs( oSettings, nTheadClone ); - iCorrector = 0; - for ( i=0 ; i 0 ) - { - oSettings.aoColumns[i].sWidth = _fnStringToCss( iWidth ); - } - iCorrector++; - } - } - - var cssWidth = $(nCalcTmp).css('width'); - oSettings.nTable.style.width = (cssWidth.indexOf('%') !== -1) ? - cssWidth : _fnStringToCss( $(nCalcTmp).outerWidth() ); - nCalcTmp.parentNode.removeChild( nCalcTmp ); - } - - if ( widthAttr ) - { - oSettings.nTable.style.width = _fnStringToCss( widthAttr ); - } - } - - - /** - * Adjust a table's width to take account of scrolling - * @param {object} oSettings dataTables settings object - * @param {node} n table node - * @memberof DataTable#oApi - */ - function _fnScrollingWidthAdjust ( oSettings, n ) - { - if ( oSettings.oScroll.sX === "" && oSettings.oScroll.sY !== "" ) - { - /* When y-scrolling only, we want to remove the width of the scroll bar so the table - * + scroll bar will fit into the area avaialble. - */ - var iOrigWidth = $(n).width(); - n.style.width = _fnStringToCss( $(n).outerWidth()-oSettings.oScroll.iBarWidth ); - } - else if ( oSettings.oScroll.sX !== "" ) - { - /* When x-scrolling both ways, fix the table at it's current size, without adjusting */ - n.style.width = _fnStringToCss( $(n).outerWidth() ); - } - } - - - /** - * Get the widest node - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {string} max strlens for each column - * @memberof DataTable#oApi - */ - function _fnGetWidestNode( oSettings, iCol ) - { - var iMaxIndex = _fnGetMaxLenString( oSettings, iCol ); - if ( iMaxIndex < 0 ) - { - return null; - } - - if ( oSettings.aoData[iMaxIndex].nTr === null ) - { - var n = document.createElement('td'); - n.innerHTML = _fnGetCellData( oSettings, iMaxIndex, iCol, '' ); - return n; - } - return _fnGetTdNodes(oSettings, iMaxIndex)[iCol]; - } - - - /** - * Get the maximum strlen for each data column - * @param {object} oSettings dataTables settings object - * @param {int} iCol column of interest - * @returns {string} max strlens for each column - * @memberof DataTable#oApi - */ - function _fnGetMaxLenString( oSettings, iCol ) - { - var iMax = -1; - var iMaxIndex = -1; - - for ( var i=0 ; i/g, "" ); - if ( s.length > iMax ) - { - iMax = s.length; - iMaxIndex = i; - } - } - - return iMaxIndex; - } - - - /** - * Append a CSS unit (only if required) to a string - * @param {array} aArray1 first array - * @param {array} aArray2 second array - * @returns {int} 0 if match, 1 if length is different, 2 if no match - * @memberof DataTable#oApi - */ - function _fnStringToCss( s ) - { - if ( s === null ) - { - return "0px"; - } - - if ( typeof s == 'number' ) - { - if ( s < 0 ) - { - return "0px"; - } - return s+"px"; - } - - /* Check if the last character is not 0-9 */ - var c = s.charCodeAt( s.length-1 ); - if (c < 0x30 || c > 0x39) - { - return s; - } - return s+"px"; - } - - - /** - * Get the width of a scroll bar in this browser being used - * @returns {int} width in pixels - * @memberof DataTable#oApi - */ - function _fnScrollBarWidth () - { - var inner = document.createElement('p'); - var style = inner.style; - style.width = "100%"; - style.height = "200px"; - style.padding = "0px"; - - var outer = document.createElement('div'); - style = outer.style; - style.position = "absolute"; - style.top = "0px"; - style.left = "0px"; - style.visibility = "hidden"; - style.width = "200px"; - style.height = "150px"; - style.padding = "0px"; - style.overflow = "hidden"; - outer.appendChild(inner); - - document.body.appendChild(outer); - var w1 = inner.offsetWidth; - outer.style.overflow = 'scroll'; - var w2 = inner.offsetWidth; - if ( w1 == w2 ) - { - w2 = outer.clientWidth; - } - - document.body.removeChild(outer); - return (w1 - w2); - } - - - - /** - * Change the order of the table - * @param {object} oSettings dataTables settings object - * @param {bool} bApplyClasses optional - should we apply classes or not - * @memberof DataTable#oApi - */ - function _fnSort ( oSettings, bApplyClasses ) - { - var - i, iLen, j, jLen, k, kLen, - sDataType, nTh, - aaSort = [], - aiOrig = [], - oSort = DataTable.ext.oSort, - aoData = oSettings.aoData, - aoColumns = oSettings.aoColumns, - oAria = oSettings.oLanguage.oAria; - - /* No sorting required if server-side or no sorting array */ - if ( !oSettings.oFeatures.bServerSide && - (oSettings.aaSorting.length !== 0 || oSettings.aaSortingFixed !== null) ) - { - if ( oSettings.aaSortingFixed !== null ) - { - aaSort = oSettings.aaSortingFixed.concat( oSettings.aaSorting ); - } - else - { - aaSort = oSettings.aaSorting.slice(); - } - - /* If there is a sorting data type, and a fuction belonging to it, then we need to - * get the data from the developer's function and apply it for this column - */ - for ( i=0 ; i 0 && aaSort[0][0] == i ) - { - nTh.setAttribute('aria-sort', aaSort[0][1]=="asc" ? "ascending" : "descending" ); - - var nextSort = (aoColumns[i].asSorting[ aaSort[0][2]+1 ]) ? - aoColumns[i].asSorting[ aaSort[0][2]+1 ] : aoColumns[i].asSorting[0]; - nTh.setAttribute('aria-label', aoColumns[i].sTitle+ - (nextSort=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - else - { - nTh.setAttribute('aria-label', aoColumns[i].sTitle+ - (aoColumns[i].asSorting[0]=="asc" ? oAria.sSortAscending : oAria.sSortDescending) ); - } - } - else - { - nTh.setAttribute('aria-label', aoColumns[i].sTitle); - } - } - - /* Tell the draw function that we have sorted the data */ - oSettings.bSorted = true; - $(oSettings.oInstance).trigger('sort', oSettings); - - /* Copy the master data into the draw array and re-draw */ - if ( oSettings.oFeatures.bFilter ) - { - /* _fnFilter() will redraw the table for us */ - _fnFilterComplete( oSettings, oSettings.oPreviousSearch, 1 ); - } - else - { - oSettings.aiDisplay = oSettings.aiDisplayMaster.slice(); - oSettings._iDisplayStart = 0; /* reset display back to page 0 */ - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - } - - - /** - * Attach a sort handler (click) to a node - * @param {object} oSettings dataTables settings object - * @param {node} nNode node to attach the handler to - * @param {int} iDataIndex column sorting index - * @param {function} [fnCallback] callback function - * @memberof DataTable#oApi - */ - function _fnSortAttachListener ( oSettings, nNode, iDataIndex, fnCallback ) - { - _fnBindAction( nNode, {}, function (e) { - /* If the column is not sortable - don't to anything */ - if ( oSettings.aoColumns[iDataIndex].bSortable === false ) - { - return; - } - - /* - * This is a little bit odd I admit... I declare a temporary function inside the scope of - * _fnBuildHead and the click handler in order that the code presented here can be used - * twice - once for when bProcessing is enabled, and another time for when it is - * disabled, as we need to perform slightly different actions. - * Basically the issue here is that the Javascript engine in modern browsers don't - * appear to allow the rendering engine to update the display while it is still excuting - * it's thread (well - it does but only after long intervals). This means that the - * 'processing' display doesn't appear for a table sort. To break the js thread up a bit - * I force an execution break by using setTimeout - but this breaks the expected - * thread continuation for the end-developer's point of view (their code would execute - * too early), so we on;y do it when we absolutely have to. - */ - var fnInnerSorting = function () { - var iColumn, iNextSort; - - /* If the shift key is pressed then we are multipe column sorting */ - if ( e.shiftKey ) - { - /* Are we already doing some kind of sort on this column? */ - var bFound = false; - for ( var i=0 ; i= iColumns ) - { - for ( i=0 ; i 4096 ) /* Magic 10 for padding */ - { - var aCookies =document.cookie.split(';'); - for ( var i=0, iLen=aCookies.length ; i=0 ; i-- ) - { - aRet.push( aoStore[i].fn.apply( oSettings.oInstance, aArgs ) ); - } - - if ( sTrigger !== null ) - { - $(oSettings.oInstance).trigger(sTrigger, aArgs); - } - - return aRet; - } - - - /** - * JSON stringify. If JSON.stringify it provided by the browser, json2.js or any other - * library, then we use that as it is fast, safe and accurate. If the function isn't - * available then we need to built it ourselves - the insperation for this function comes - * from Craig Buckler ( http://www.sitepoint.com/javascript-json-serialization/ ). It is - * not perfect and absolutely should not be used as a replacement to json2.js - but it does - * do what we need, without requiring a dependency for DataTables. - * @param {object} o JSON object to be converted - * @returns {string} JSON string - * @memberof DataTable#oApi - */ - var _fnJsonString = (window.JSON) ? JSON.stringify : function( o ) - { - /* Not an object or array */ - var sType = typeof o; - if (sType !== "object" || o === null) - { - // simple data type - if (sType === "string") - { - o = '"'+o+'"'; - } - return o+""; - } - - /* If object or array, need to recurse over it */ - var - sProp, mValue, - json = [], - bArr = $.isArray(o); - - for (sProp in o) - { - mValue = o[sProp]; - sType = typeof mValue; - - if (sType === "string") - { - mValue = '"'+mValue+'"'; - } - else if (sType === "object" && mValue !== null) - { - mValue = _fnJsonString(mValue); - } - - json.push((bArr ? "" : '"'+sProp+'":') + mValue); - } - - return (bArr ? "[" : "{") + json + (bArr ? "]" : "}"); - }; - - - - - /** - * Perform a jQuery selector action on the table's TR elements (from the tbody) and - * return the resulting jQuery object. - * @param {string|node|jQuery} sSelector jQuery selector or node collection to act on - * @param {object} [oOpts] Optional parameters for modifying the rows to be included - * @param {string} [oOpts.filter=none] Select TR elements that meet the current filter - * criterion ("applied") or all TR elements (i.e. no filter). - * @param {string} [oOpts.order=current] Order of the TR elements in the processed array. - * Can be either 'current', whereby the current sorting of the table is used, or - * 'original' whereby the original order the data was read into the table is used. - * @param {string} [oOpts.page=all] Limit the selection to the currently displayed page - * ("current") or not ("all"). If 'current' is given, then order is assumed to be - * 'current' and filter is 'applied', regardless of what they might be given as. - * @returns {object} jQuery object, filtered by the given selector. - * @dtopt API - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Highlight every second row - * oTable.$('tr:odd').css('backgroundColor', 'blue'); - * } ); - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable(); - * - * // Filter to rows with 'Webkit' in them, add a background colour and then - * // remove the filter, thus highlighting the 'Webkit' rows only. - * oTable.fnFilter('Webkit'); - * oTable.$('tr', {"filter": "applied"}).css('backgroundColor', 'blue'); - * oTable.fnFilter(''); - * } ); - */ - this.$ = function ( sSelector, oOpts ) - { - var i, iLen, a = []; - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - - if ( !oOpts ) - { - oOpts = {}; - } - - oOpts = $.extend( {}, { - "filter": "none", // applied - "order": "current", // "original" - "page": "all" // current - }, oOpts ); - - // Current page implies that order=current and fitler=applied, since it is fairly - // senseless otherwise - if ( oOpts.page == 'current' ) - { - for ( i=oSettings._iDisplayStart, iLen=oSettings.fnDisplayEnd() ; i - *
            • 1D array of data - add a single row with the data provided
            • - *
            • 2D array of arrays - add multiple rows in a single call
            • - *
            • object - data object when using mDataProp
            • - *
            • array of objects - multiple data objects when using mDataProp
            • - *
            - * @param {bool} [bRedraw=true] redraw the table or not - * @returns {array} An array of integers, representing the list of indexes in - * aoData ({@link DataTable.models.oSettings}) that have been added to - * the table. - * @dtopt API - * - * @example - * // Global var for counter - * var giCount = 2; - * - * $(document).ready(function() { - * $('#example').dataTable(); - * } ); - * - * function fnClickAddRow() { - * $('#example').dataTable().fnAddData( [ - * giCount+".1", - * giCount+".2", - * giCount+".3", - * giCount+".4" ] - * ); - * - * giCount++; - * } - */ - this.fnAddData = function( mData, bRedraw ) - { - if ( mData.length === 0 ) - { - return []; - } - - var aiReturn = []; - var iTest; - - /* Find settings from table node */ - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - - /* Check if we want to add multiple rows or not */ - if ( typeof mData[0] === "object" && mData[0] !== null ) - { - for ( var i=0 ; i= oSettings.aiDisplay.length ) - { - oSettings._iDisplayStart -= oSettings._iDisplayLength; - if ( oSettings._iDisplayStart < 0 ) - { - oSettings._iDisplayStart = 0; - } - } - - if ( bRedraw === undefined || bRedraw ) - { - _fnCalculateEnd( oSettings ); - _fnDraw( oSettings ); - } - - return oData; - }; - - - /** - * Restore the table to it's original state in the DOM by removing all of DataTables - * enhancements, alterations to the DOM structure of the table and event listeners. - * @param {boolean} [bRemove=false] Completely remove the table from the DOM - * @dtopt API - * - * @example - * $(document).ready(function() { - * // This example is fairly pointless in reality, but shows how fnDestroy can be used - * var oTable = $('#example').dataTable(); - * oTable.fnDestroy(); - * } ); - */ - this.fnDestroy = function ( bRemove ) - { - var oSettings = _fnSettingsFromNode( this[DataTable.ext.iApiIndex] ); - var nOrig = oSettings.nTableWrapper.parentNode; - var nBody = oSettings.nTBody; - var i, iLen; - - bRemove = (bRemove===undefined) ? false : true; - - /* Flag to note that the table is currently being destroyed - no action should be taken */ - oSettings.bDestroying = true; - - /* Restore hidden columns */ - for ( i=0, iLen=oSettings.aoDestroyCallback.length ; i
          - * @type object - * @default {} - * - * @example - * // Case-sensitive string sorting, with no pre-formatting method - * $.extend( $.fn.dataTableExt.oSort, { - * "string-case-asc": function(x,y) { - * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - * }, - * "string-case-desc": function(x,y) { - * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - * } - * } ); - * - * @example - * // Case-insensitive string sorting, with pre-formatting - * $.extend( $.fn.dataTableExt.oSort, { - * "string-pre": function(x) { - * return x.toLowerCase(); - * }, - * "string-asc": function(x,y) { - * return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - * }, - * "string-desc": function(x,y) { - * return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - * } - * } ); - */ - "oSort": {}, - - - /** - * Version string for plug-ins to check compatibility. Allowed format is - * a.b.c.d.e where: a:int, b:int, c:int, d:string(dev|beta), e:int. d and - * e are optional - * @type string - * @default Version number - */ - "sVersion": DataTable.version, - - - /** - * How should DataTables report an error. Can take the value 'alert' or 'throw' - * @type string - * @default alert - */ - "sErrMode": "alert", - - - /** - * Store information for DataTables to access globally about other instances - * @namespace - * @private - */ - "_oExternConfig": { - /* int:iNextUnique - next unique number for an instance */ - "iNextUnique": 0 - } - }; - - - - - /** - * Template object for the way in which DataTables holds information about - * search information for the global filter and individual column filters. - * @namespace - */ - DataTable.models.oSearch = { - /** - * Flag to indicate if the filtering should be case insensitive or not - * @type boolean - * @default true - */ - "bCaseInsensitive": true, - - /** - * Applied search term - * @type string - * @default Empty string - */ - "sSearch": "", - - /** - * Flag to indicate if the search term should be interpreted as a - * regular expression (true) or not (false) and therefore and special - * regex characters escaped. - * @type boolean - * @default false - */ - "bRegex": false, - - /** - * Flag to indicate if DataTables is to use its smart filtering or not. - * @type boolean - * @default true - */ - "bSmart": true - }; - - - - - /** - * Template object for the way in which DataTables holds information about - * each individual row. This is the object format used for the settings - * aoData array. - * @namespace - */ - DataTable.models.oRow = { - /** - * TR element for the row - * @type node - * @default null - */ - "nTr": null, - - /** - * Data object from the original data source for the row. This is either - * an array if using the traditional form of DataTables, or an object if - * using mDataProp options. The exact type will depend on the passed in - * data from the data source, or will be an array if using DOM a data - * source. - * @type array|object - * @default [] - */ - "_aData": [], - - /** - * Sorting data cache - this array is ostensibly the same length as the - * number of columns (although each index is generated only as it is - * needed), and holds the data that is used for sorting each column in the - * row. We do this cache generation at the start of the sort in order that - * the formatting of the sort data need be done only once for each cell - * per sort. This array should not be read from or written to by anything - * other than the master sorting methods. - * @type array - * @default [] - * @private - */ - "_aSortData": [], - - /** - * Array of TD elements that are cached for hidden rows, so they can be - * reinserted into the table if a column is made visible again (or to act - * as a store if a column is made hidden). Only hidden columns have a - * reference in the array. For non-hidden columns the value is either - * undefined or null. - * @type array nodes - * @default [] - * @private - */ - "_anHidden": [], - - /** - * Cache of the class name that DataTables has applied to the row, so we - * can quickly look at this variable rather than needing to do a DOM check - * on className for the nTr property. - * @type string - * @default Empty string - * @private - */ - "_sRowStripe": "" - }; - - - - /** - * Template object for the column information object in DataTables. This object - * is held in the settings aoColumns array and contains all the information that - * DataTables needs about each individual column. - * - * Note that this object is related to {@link DataTable.defaults.columns} - * but this one is the internal data store for DataTables's cache of columns. - * It should NOT be manipulated outside of DataTables. Any configuration should - * be done through the initialisation options. - * @namespace - */ - DataTable.models.oColumn = { - /** - * A list of the columns that sorting should occur on when this column - * is sorted. That this property is an array allows multi-column sorting - * to be defined for a column (for example first name / last name columns - * would benefit from this). The values are integers pointing to the - * columns to be sorted on (typically it will be a single integer pointing - * at itself, but that doesn't need to be the case). - * @type array - */ - "aDataSort": null, - - /** - * Define the sorting directions that are applied to the column, in sequence - * as the column is repeatedly sorted upon - i.e. the first value is used - * as the sorting direction when the column if first sorted (clicked on). - * Sort it again (click again) and it will move on to the next index. - * Repeat until loop. - * @type array - */ - "asSorting": null, - - /** - * Flag to indicate if the column is searchable, and thus should be included - * in the filtering or not. - * @type boolean - */ - "bSearchable": null, - - /** - * Flag to indicate if the column is sortable or not. - * @type boolean - */ - "bSortable": null, - - /** - * When using fnRender, you have two options for what to do with the data, - * and this property serves as the switch. Firstly, you can have the sorting - * and filtering use the rendered value (true - default), or you can have - * the sorting and filtering us the original value (false). - * - * *NOTE* It is it is advisable now to use mDataProp as a function and make - * use of the 'type' that it gives, allowing (potentially) different data to - * be used for sorting, filtering, display and type detection. - * @type boolean - * @deprecated - */ - "bUseRendered": null, - - /** - * Flag to indicate if the column is currently visible in the table or not - * @type boolean - */ - "bVisible": null, - - /** - * Flag to indicate to the type detection method if the automatic type - * detection should be used, or if a column type (sType) has been specified - * @type boolean - * @default true - * @private - */ - "_bAutoType": true, - - /** - * Developer definable function that is called whenever a cell is created (Ajax source, - * etc) or processed for input (DOM source). This can be used as a compliment to fnRender - * allowing you to modify the DOM element (add background colour for example) when the - * element is available (since it is not when fnRender is called). - * @type function - * @param {element} nTd The TD node that has been created - * @param {*} sData The Data for the cell - * @param {array|object} oData The data for the whole row - * @param {int} iRow The row index for the aoData data store - * @default null - */ - "fnCreatedCell": null, - - /** - * Function to get data from a cell in a column. You should never - * access data directly through _aData internally in DataTables - always use - * the method attached to this property. It allows mDataProp to function as - * required. This function is automatically assigned by the column - * initialisation method - * @type function - * @param {array|object} oData The data array/object for the array - * (i.e. aoData[]._aData) - * @param {string} sSpecific The specific data type you want to get - - * 'display', 'type' 'filter' 'sort' - * @returns {*} The data for the cell from the given row's data - * @default null - */ - "fnGetData": null, - - /** - * Custom display function that will be called for the display of each cell - * in this column. - * @type function - * @param {object} o Object with the following parameters: - * @param {int} o.iDataRow The row in aoData - * @param {int} o.iDataColumn The column in question - * @param {array o.aData The data for the row in question - * @param {object} o.oSettings The settings object for this DataTables instance - * @returns {string} The string you which to use in the display - * @default null - */ - "fnRender": null, - - /** - * Function to set data for a cell in the column. You should never - * set the data directly to _aData internally in DataTables - always use - * this method. It allows mDataProp to function as required. This function - * is automatically assigned by the column initialisation method - * @type function - * @param {array|object} oData The data array/object for the array - * (i.e. aoData[]._aData) - * @param {*} sValue Value to set - * @default null - */ - "fnSetData": null, - - /** - * Property to read the value for the cells in the column from the data - * source array / object. If null, then the default content is used, if a - * function is given then the return from the function is used. - * @type function|int|string|null - * @default null - */ - "mDataProp": null, - - /** - * Unique header TH/TD element for this column - this is what the sorting - * listener is attached to (if sorting is enabled.) - * @type node - * @default null - */ - "nTh": null, - - /** - * Unique footer TH/TD element for this column (if there is one). Not used - * in DataTables as such, but can be used for plug-ins to reference the - * footer for each column. - * @type node - * @default null - */ - "nTf": null, - - /** - * The class to apply to all TD elements in the table's TBODY for the column - * @type string - * @default null - */ - "sClass": null, - - /** - * When DataTables calculates the column widths to assign to each column, - * it finds the longest string in each column and then constructs a - * temporary table and reads the widths from that. The problem with this - * is that "mmm" is much wider then "iiii", but the latter is a longer - * string - thus the calculation can go wrong (doing it properly and putting - * it into an DOM object and measuring that is horribly(!) slow). Thus as - * a "work around" we provide this option. It will append its value to the - * text that is found to be the longest string for the column - i.e. padding. - * @type string - */ - "sContentPadding": null, - - /** - * Allows a default value to be given for a column's data, and will be used - * whenever a null data source is encountered (this can be because mDataProp - * is set to null, or because the data source itself is null). - * @type string - * @default null - */ - "sDefaultContent": null, - - /** - * Name for the column, allowing reference to the column by name as well as - * by index (needs a lookup to work by name). - * @type string - */ - "sName": null, - - /** - * Custom sorting data type - defines which of the available plug-ins in - * afnSortData the custom sorting will use - if any is defined. - * @type string - * @default std - */ - "sSortDataType": 'std', - - /** - * Class to be applied to the header element when sorting on this column - * @type string - * @default null - */ - "sSortingClass": null, - - /** - * Class to be applied to the header element when sorting on this column - - * when jQuery UI theming is used. - * @type string - * @default null - */ - "sSortingClassJUI": null, - - /** - * Title of the column - what is seen in the TH element (nTh). - * @type string - */ - "sTitle": null, - - /** - * Column sorting and filtering type - * @type string - * @default null - */ - "sType": null, - - /** - * Width of the column - * @type string - * @default null - */ - "sWidth": null, - - /** - * Width of the column when it was first "encountered" - * @type string - * @default null - */ - "sWidthOrig": null - }; - - - - /** - * Initialisation options that can be given to DataTables at initialisation - * time. - * @namespace - */ - DataTable.defaults = { - /** - * An array of data to use for the table, passed in at initialisation which - * will be used in preference to any data which is already in the DOM. This is - * particularly useful for constructing tables purely in Javascript, for - * example with a custom Ajax call. - * @type array - * @default null - * @dtopt Option - * - * @example - * // Using a 2D array data source - * $(document).ready( function () { - * $('#example').dataTable( { - * "aaData": [ - * ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'], - * ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'], - * ], - * "aoColumns": [ - * { "sTitle": "Engine" }, - * { "sTitle": "Browser" }, - * { "sTitle": "Platform" }, - * { "sTitle": "Version" }, - * { "sTitle": "Grade" } - * ] - * } ); - * } ); - * - * @example - * // Using an array of objects as a data source (mDataProp) - * $(document).ready( function () { - * $('#example').dataTable( { - * "aaData": [ - * { - * "engine": "Trident", - * "browser": "Internet Explorer 4.0", - * "platform": "Win 95+", - * "version": 4, - * "grade": "X" - * }, - * { - * "engine": "Trident", - * "browser": "Internet Explorer 5.0", - * "platform": "Win 95+", - * "version": 5, - * "grade": "C" - * } - * ], - * "aoColumns": [ - * { "sTitle": "Engine", "mDataProp": "engine" }, - * { "sTitle": "Browser", "mDataProp": "browser" }, - * { "sTitle": "Platform", "mDataProp": "platform" }, - * { "sTitle": "Version", "mDataProp": "version" }, - * { "sTitle": "Grade", "mDataProp": "grade" } - * ] - * } ); - * } ); - */ - "aaData": null, - - - /** - * If sorting is enabled, then DataTables will perform a first pass sort on - * initialisation. You can define which column(s) the sort is performed upon, - * and the sorting direction, with this variable. The aaSorting array should - * contain an array for each column to be sorted initially containing the - * column's index and a direction string ('asc' or 'desc'). - * @type array - * @default [[0,'asc']] - * @dtopt Option - * - * @example - * // Sort by 3rd column first, and then 4th column - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSorting": [[2,'asc'], [3,'desc']] - * } ); - * } ); - * - * // No initial sorting - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSorting": [] - * } ); - * } ); - */ - "aaSorting": [[0,'asc']], - - - /** - * This parameter is basically identical to the aaSorting parameter, but - * cannot be overridden by user interaction with the table. What this means - * is that you could have a column (visible or hidden) which the sorting will - * always be forced on first - any sorting after that (from the user) will - * then be performed as required. This can be useful for grouping rows - * together. - * @type array - * @default null - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aaSortingFixed": [[0,'asc']] - * } ); - * } ) - */ - "aaSortingFixed": null, - - - /** - * This parameter allows you to readily specify the entries in the length drop - * down menu that DataTables shows when pagination is enabled. It can be - * either a 1D array of options which will be used for both the displayed - * option and the value, or a 2D array which will use the array in the first - * position as the value, and the array in the second position as the - * displayed options (useful for language strings such as 'All'). - * @type array - * @default [ 10, 25, 50, 100 ] - * @dtopt Option - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "aLengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]] - * } ); - * } ); - * - * @example - * // Setting the default display length as well as length menu - * // This is likely to be wanted if you remove the '10' option which - * // is the iDisplayLength default. - * $(document).ready(function() { - * $('#example').dataTable( { - * "iDisplayLength": 25, - * "aLengthMenu": [[25, 50, 100, -1], [25, 50, 100, "All"]] - * } ); - * } ); - */ - "aLengthMenu": [ 10, 25, 50, 100 ], - - - /** - * The aoColumns option in the initialisation parameter allows you to define - * details about the way individual columns behave. For a full list of - * column options that can be set, please see - * {@link DataTable.defaults.columns}. Note that if you use aoColumns to - * define your columns, you must have an entry in the array for every single - * column that you have in your table (these can be null if you don't which - * to specify any options). - * @member - */ - "aoColumns": null, - - /** - * Very similar to aoColumns, aoColumnDefs allows you to target a specific - * column, multiple columns, or all columns, using the aTargets property of - * each object in the array. This allows great flexibility when creating - * tables, as the aoColumnDefs arrays can be of any length, targeting the - * columns you specifically want. aoColumnDefs may use any of the column - * options available: {@link DataTable.defaults.columns}, but it _must_ - * have aTargets defined in each object in the array. Values in the aTargets - * array may be: - *
            - *
          • a string - class name will be matched on the TH for the column
          • - *
          • 0 or a positive integer - column index counting from the left
          • - *
          • a negative integer - column index counting from the right
          • - *
          • the string "_all" - all columns (i.e. assign a default)
          • - *
          - * @member - */ - "aoColumnDefs": null, - - - /** - * Basically the same as oSearch, this parameter defines the individual column - * filtering state at initialisation time. The array must be of the same size - * as the number of columns, and each element be an object with the parameters - * "sSearch" and "bEscapeRegex" (the latter is optional). 'null' is also - * accepted and the default will be used. - * @type array - * @default [] - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "aoSearchCols": [ - * null, - * { "sSearch": "My filter" }, - * null, - * { "sSearch": "^[0-9]", "bEscapeRegex": false } - * ] - * } ); - * } ) - */ - "aoSearchCols": [], - - - /** - * An array of CSS classes that should be applied to displayed rows. This - * array may be of any length, and DataTables will apply each class - * sequentially, looping when required. - * @type array - * @default [ 'odd', 'even' ] - * @dtopt Option - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "asStripeClasses": [ 'strip1', 'strip2', 'strip3' ] - * } ); - * } ) - */ - "asStripeClasses": [ 'odd', 'even' ], - - - /** - * Enable or disable automatic column width calculation. This can be disabled - * as an optimisation (it takes some time to calculate the widths) if the - * tables widths are passed in using aoColumns. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bAutoWidth": false - * } ); - * } ); - */ - "bAutoWidth": true, - - - /** - * Deferred rendering can provide DataTables with a huge speed boost when you - * are using an Ajax or JS data source for the table. This option, when set to - * true, will cause DataTables to defer the creation of the table elements for - * each row until they are needed for a draw - saving a significant amount of - * time. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/arrays.txt", - * "bDeferRender": true - * } ); - * } ); - */ - "bDeferRender": false, - - - /** - * Replace a DataTable which matches the given selector and replace it with - * one which has the properties of the new initialisation object passed. If no - * table matches the selector, then the new DataTable will be constructed as - * per normal. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false - * } ); - * - * // Some time later.... - * $('#example').dataTable( { - * "bFilter": false, - * "bDestroy": true - * } ); - * } ); - */ - "bDestroy": false, - - - /** - * Enable or disable filtering of data. Filtering in DataTables is "smart" in - * that it allows the end user to input multiple words (space separated) and - * will match a row containing those words, even if not in the order that was - * specified (this allow matching across multiple columns). Note that if you - * wish to use filtering in DataTables this must remain 'true' - to remove the - * default filtering input box and retain filtering abilities, please use - * @ref{sDom}. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bFilter": false - * } ); - * } ); - */ - "bFilter": true, - - - /** - * Enable or disable the table information display. This shows information - * about the data that is currently visible on the page, including information - * about filtered data if that action is being performed. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bInfo": false - * } ); - * } ); - */ - "bInfo": true, - - - /** - * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some - * slightly different and additional mark-up from what DataTables has - * traditionally used). - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "bJQueryUI": true - * } ); - * } ); - */ - "bJQueryUI": false, - - - /** - * Allows the end user to select the size of a formatted page from a select - * menu (sizes are 10, 25, 50 and 100). Requires pagination (bPaginate). - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bLengthChange": false - * } ); - * } ); - */ - "bLengthChange": true, - - - /** - * Enable or disable pagination. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bPaginate": false - * } ); - * } ); - */ - "bPaginate": true, - - - /** - * Enable or disable the display of a 'processing' indicator when the table is - * being processed (e.g. a sort). This is particularly useful for tables with - * large amounts of data where it can take a noticeable amount of time to sort - * the entries. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bProcessing": true - * } ); - * } ); - */ - "bProcessing": false, - - - /** - * Retrieve the DataTables object for the given selector. Note that if the - * table has already been initialised, this parameter will cause DataTables - * to simply return the object that has already been set up - it will not take - * account of any changes you might have made to the initialisation object - * passed to DataTables (setting this parameter to true is an acknowledgement - * that you understand this). bDestroy can be used to reinitialise a table if - * you need. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready(function() { - * initTable(); - * tableActions(); - * } ); - * - * function initTable () - * { - * return $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false, - * "bRetrieve": true - * } ); - * } - * - * function tableActions () - * { - * var oTable = initTable(); - * // perform API operations with oTable - * } - */ - "bRetrieve": false, - - - /** - * Indicate if DataTables should be allowed to set the padding / margin - * etc for the scrolling header elements or not. Typically you will want - * this. - * @type boolean - * @default true - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bScrollAutoCss": false, - * "sScrollY": "200px" - * } ); - * } ); - */ - "bScrollAutoCss": true, - - - /** - * When vertical (y) scrolling is enabled, DataTables will force the height of - * the table's viewport to the given height at all times (useful for layout). - * However, this can look odd when filtering data down to a small data set, - * and the footer is left "floating" further down. This parameter (when - * enabled) will cause DataTables to collapse the table's viewport down when - * the result set will fit within the given Y height. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollY": "200", - * "bScrollCollapse": true - * } ); - * } ); - */ - "bScrollCollapse": false, - - - /** - * Enable infinite scrolling for DataTables (to be used in combination with - * sScrollY). Infinite scrolling means that DataTables will continually load - * data as a user scrolls through a table, which is very useful for large - * dataset. This cannot be used with pagination, which is automatically - * disabled. Note - the Scroller extra for DataTables is recommended in - * in preference to this option. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bScrollInfinite": true, - * "bScrollCollapse": true, - * "sScrollY": "200px" - * } ); - * } ); - */ - "bScrollInfinite": false, - - - /** - * Configure DataTables to use server-side processing. Note that the - * sAjaxSource parameter must also be given in order to give DataTables a - * source to obtain the required data for each draw. - * @type boolean - * @default false - * @dtopt Features - * @dtopt Server-side - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "xhr.php" - * } ); - * } ); - */ - "bServerSide": false, - - - /** - * Enable or disable sorting of columns. Sorting of individual columns can be - * disabled by the "bSortable" option for each column. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bSort": false - * } ); - * } ); - */ - "bSort": true, - - - /** - * Allows control over whether DataTables should use the top (true) unique - * cell that is found for a single column, or the bottom (false - default). - * This is useful when using complex headers. - * @type boolean - * @default false - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bSortCellsTop": true - * } ); - * } ); - */ - "bSortCellsTop": false, - - - /** - * Enable or disable the addition of the classes 'sorting_1', 'sorting_2' and - * 'sorting_3' to the columns which are currently being sorted on. This is - * presented as a feature switch as it can increase processing time (while - * classes are removed and added) so for large data sets you might want to - * turn this off. - * @type boolean - * @default true - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bSortClasses": false - * } ); - * } ); - */ - "bSortClasses": true, - - - /** - * Enable or disable state saving. When enabled a cookie will be used to save - * table display information such as pagination information, display length, - * filtering and sorting. As such when the end user reloads the page the - * display display will match what thy had previously set up. - * @type boolean - * @default false - * @dtopt Features - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "bStateSave": true - * } ); - * } ); - */ - "bStateSave": false, - - - /** - * Customise the cookie and / or the parameters being stored when using - * DataTables with state saving enabled. This function is called whenever - * the cookie is modified, and it expects a fully formed cookie string to be - * returned. Note that the data object passed in is a Javascript object which - * must be converted to a string (JSON.stringify for example). - * @type function - * @param {string} sName Name of the cookie defined by DataTables - * @param {object} oData Data to be stored in the cookie - * @param {string} sExpires Cookie expires string - * @param {string} sPath Path of the cookie to set - * @returns {string} Cookie formatted string (which should be encoded by - * using encodeURIComponent()) - * @dtopt Callbacks - * - * @example - * $(document).ready( function () { - * $('#example').dataTable( { - * "fnCookieCallback": function (sName, oData, sExpires, sPath) { - * // Customise oData or sName or whatever else here - * return sName + "="+JSON.stringify(oData)+"; expires=" + sExpires +"; path=" + sPath; - * } - * } ); - * } ); - */ - "fnCookieCallback": null, - - - /** - * This function is called when a TR element is created (and all TD child - * elements have been inserted), or registered if using a DOM source, allowing - * manipulation of the TR element (adding classes etc). - * @type function - * @param {node} nRow "TR" element for the current row - * @param {array} aData Raw data array for this row - * @param {int} iDataIndex The index of this row in aoData - * @dtopt Callbacks - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "fnCreatedRow": function( nRow, aData, iDataIndex ) { - * // Bold the grade for all 'A' grade browsers - * if ( aData[4] == "A" ) - * { - * $('td:eq(4)', nRow).html( 'A' ); - * } - * } - * } ); - * } ); - */ - "fnCreatedRow": null, - - - /** - * This function is called on every 'draw' event, and allows you to - * dynamically modify any aspect you want about the created DOM. - * @type function - * @param {object} oSettings DataTables settings object - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnDrawCallback": function() { - * alert( 'DataTables has redrawn the table' ); - * } - * } ); - * } ); - */ - "fnDrawCallback": null, - - - /** - * Identical to fnHeaderCallback() but for the table footer this function - * allows you to modify the table footer on every 'draw' even. - * @type function - * @param {node} nFoot "TR" element for the footer - * @param {array} aData Full table data (as derived from the original HTML) - * @param {int} iStart Index for the current display starting point in the - * display array - * @param {int} iEnd Index for the current display ending point in the - * display array - * @param {array int} aiDisplay Index array to translate the visual position - * to the full data array - * @dtopt Callbacks - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "fnFooterCallback": function( nFoot, aData, iStart, iEnd, aiDisplay ) { - * nFoot.getElementsByTagName('th')[0].innerHTML = "Starting index is "+iStart; - * } - * } ); - * } ) - */ - "fnFooterCallback": null, - - - /** - * When rendering large numbers in the information element for the table - * (i.e. "Showing 1 to 10 of 57 entries") DataTables will render large numbers - * to have a comma separator for the 'thousands' units (e.g. 1 million is - * rendered as "1,000,000") to help readability for the end user. This - * function will override the default method DataTables uses. - * @type function - * @member - * @param {int} iIn number to be formatted - * @returns {string} formatted string for DataTables to show the number - * @dtopt Callbacks - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "fnFormatNumber": function ( iIn ) { - * if ( iIn < 1000 ) { - * return iIn; - * } else { - * var - * s=(iIn+""), - * a=s.split(""), out="", - * iLen=s.length; - * - * for ( var i=0 ; i<iLen ; i++ ) { - * if ( i%3 === 0 && i !== 0 ) { - * out = "'"+out; - * } - * out = a[iLen-i-1]+out; - * } - * } - * return out; - * }; - * } ); - * } ); - */ - "fnFormatNumber": function ( iIn ) { - if ( iIn < 1000 ) - { - // A small optimisation for what is likely to be the majority of use cases - return iIn; - } - - var s=(iIn+""), a=s.split(""), out="", iLen=s.length; - - for ( var i=0 ; iA' ); - * } - * } - * } ); - * } ); - */ - "fnRowCallback": null, - - - /** - * This parameter allows you to override the default function which obtains - * the data from the server ($.getJSON) so something more suitable for your - * application. For example you could use POST data, or pull information from - * a Gears or AIR database. - * @type function - * @member - * @param {string} sSource HTTP source to obtain the data from (sAjaxSource) - * @param {array} aoData A key/value pair object containing the data to send - * to the server - * @param {function} fnCallback to be called on completion of the data get - * process that will draw the data on the page. - * @param {object} oSettings DataTables settings object - * @dtopt Callbacks - * @dtopt Server-side - * - * @example - * // POST data to server - * $(document).ready(function() { - * $('#example').dataTable( { - * "bProcessing": true, - * "bServerSide": true, - * "sAjaxSource": "xhr.php", - * "fnServerData": function ( sSource, aoData, fnCallback ) { - * $.ajax( { - * "dataType": 'json', - * "type": "POST", - * "url": sSource, - * "data": aoData, - * "success": fnCallback - * } ); - * } - * } ); - * } ); - */ - "fnServerData": function ( sUrl, aoData, fnCallback, oSettings ) { - oSettings.jqXHR = $.ajax( { - "url": sUrl, - "data": aoData, - "success": function (json) { - $(oSettings.oInstance).trigger('xhr', oSettings); - fnCallback( json ); - }, - "dataType": "json", - "cache": false, - "type": oSettings.sServerMethod, - "error": function (xhr, error, thrown) { - if ( error == "parsererror" ) { - alert( "DataTables warning: JSON data from server could not be parsed. "+ - "This is caused by a JSON formatting error." ); - } - } - } ); - }, - - - /** - * It is often useful to send extra data to the server when making an Ajax - * request - for example custom filtering information, and this callback - * function makes it trivial to send extra information to the server. The - * passed in parameter is the data set that has been constructed by - * DataTables, and you can add to this or modify it as you require. - * @type function - * @param {array} aoData Data array (array of objects which are name/value - * pairs) that has been constructed by DataTables and will be sent to the - * server. In the case of Ajax sourced data with server-side processing - * this will be an empty array, for server-side processing there will be a - * significant number of parameters! - * @returns {undefined} Ensure that you modify the aoData array passed in, - * as this is passed by reference. - * @dtopt Callbacks - * @dtopt Server-side - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bProcessing": true, - * "bServerSide": true, - * "sAjaxSource": "scripts/server_processing.php", - * "fnServerParams": function ( aoData ) { - * aoData.push( { "name": "more_data", "value": "my_value" } ); - * } - * } ); - * } ); - */ - "fnServerParams": null, - - - /** - * Load the table state. With this function you can define from where, and how, the - * state of a table is loaded. By default DataTables will load from its state saving - * cookie, but you might wish to use local storage (HTML5) or a server-side database. - * @type function - * @member - * @param {object} oSettings DataTables settings object - * @return {object} The DataTables state object to be loaded - * @dtopt Callbacks - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateSave": function (oSettings, oData) { - * var o; - * - * // Send an Ajax request to the server to get the data. Note that - * // this is a synchronous request. - * $.ajax( { - * "url": "/state_load", - * "async": false, - * "dataType": "json", - * "success": function (json) { - * o = json; - * } - * } ); - * - * return o; - * } - * } ); - * } ); - */ - "fnStateLoad": function ( oSettings ) { - var sData = this.oApi._fnReadCookie( oSettings.sCookiePrefix+oSettings.sInstance ); - var oData; - - try { - oData = (typeof $.parseJSON === 'function') ? - $.parseJSON(sData) : eval( '('+sData+')' ); - } catch (e) { - oData = null; - } - - return oData; - }, - - - /** - * Callback which allows modification of the saved state prior to loading that state. - * This callback is called when the table is loading state from the stored data, but - * prior to the settings object being modified by the saved state. Note that for - * plug-in authors, you should use the 'stateLoadParams' event to load parameters for - * a plug-in. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object that is to be loaded - * @dtopt Callbacks - * - * @example - * // Remove a saved filter, so filtering is never loaded - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoadParams": function (oSettings, oData) { - * oData.oFilter.sSearch = ""; - * } ); - * } ); - * - * @example - * // Disallow state loading by returning false - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoadParams": function (oSettings, oData) { - * return false; - * } ); - * } ); - */ - "fnStateLoadParams": null, - - - /** - * Callback that is called when the state has been loaded from the state saving method - * and the DataTables settings object has been modified as a result of the loaded state. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object that was loaded - * @dtopt Callbacks - * - * @example - * // Show an alert with the filtering value that was saved - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoaded": function (oSettings, oData) { - * alert( 'Saved filter was: '+oData.oFilter.sSearch ); - * } ); - * } ); - */ - "fnStateLoaded": null, - - - /** - * Save the table state. This function allows you to define where and how the state - * information for the table is stored - by default it will use a cookie, but you - * might want to use local storage (HTML5) or a server-side database. - * @type function - * @member - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object to be saved - * @dtopt Callbacks - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateSave": function (oSettings, oData) { - * // Send an Ajax request to the server with the state object - * $.ajax( { - * "url": "/state_save", - * "data": oData, - * "dataType": "json", - * "method": "POST" - * "success": function () {} - * } ); - * } - * } ); - * } ); - */ - "fnStateSave": function ( oSettings, oData ) { - this.oApi._fnCreateCookie( - oSettings.sCookiePrefix+oSettings.sInstance, - this.oApi._fnJsonString(oData), - oSettings.iCookieDuration, - oSettings.sCookiePrefix, - oSettings.fnCookieCallback - ); - }, - - - /** - * Callback which allows modification of the state to be saved. Called when the table - * has changed state a new state save is required. This method allows modification of - * the state saving object prior to actually doing the save, including addition or - * other state properties or modification. Note that for plug-in authors, you should - * use the 'stateSaveParams' event to save parameters for a plug-in. - * @type function - * @param {object} oSettings DataTables settings object - * @param {object} oData The state object to be saved - * @dtopt Callbacks - * - * @example - * // Remove a saved filter, so filtering is never saved - * $(document).ready(function() { - * $('#example').dataTable( { - * "bStateSave": true, - * "fnStateLoadParams": function (oSettings, oData) { - * oData.oFilter.sSearch = ""; - * } ); - * } ); - */ - "fnStateSaveParams": null, - - - /** - * Duration of the cookie which is used for storing session information. This - * value is given in seconds. - * @type int - * @default 7200 (2 hours) - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iCookieDuration": 60*60*24 // 1 day - * } ); - * } ) - */ - "iCookieDuration": 7200, - - - /** - * When enabled DataTables will not make a request to the server for the first - * page draw - rather it will use the data already on the page (no sorting etc - * will be applied to it), thus saving on an XHR at load time. iDeferLoading - * is used to indicate that deferred loading is required, but it is also used - * to tell DataTables how many records there are in the full table (allowing - * the information element and pagination to be displayed correctly). - * @type int - * @default null - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "scripts/server_processing.php", - * "iDeferLoading": 57 - * } ); - * } ); - */ - "iDeferLoading": null, - - - /** - * Number of rows to display on a single page when using pagination. If - * feature enabled (bLengthChange) then the end user will be able to override - * this to a custom setting using a pop-up menu. - * @type int - * @default 10 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iDisplayLength": 50 - * } ); - * } ) - */ - "iDisplayLength": 10, - - - /** - * Define the starting point for data display when using DataTables with - * pagination. Note that this parameter is the number of records, rather than - * the page number, so if you have 10 records per page and want to start on - * the third page, it should be "20". - * @type int - * @default 0 - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "iDisplayStart": 20 - * } ); - * } ) - */ - "iDisplayStart": 0, - - - /** - * The scroll gap is the amount of scrolling that is left to go before - * DataTables will load the next 'page' of data automatically. You typically - * want a gap which is big enough that the scrolling will be smooth for the - * user, while not so large that it will load more data than need. - * @type int - * @default 100 - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bScrollInfinite": true, - * "bScrollCollapse": true, - * "sScrollY": "200px", - * "iScrollLoadGap": 50 - * } ); - * } ); - */ - "iScrollLoadGap": 100, - - - /** - * By default DataTables allows keyboard navigation of the table (sorting, paging, - * and filtering) by adding a tabindex attribute to the required elements. This - * allows you to tab through the controls and press the enter key to activate them. - * The tabindex is default 0, meaning that the tab follows the flow of the document. - * You can overrule this using this parameter if you wish. Use a value of -1 to - * disable built-in keyboard navigation. - * @type int - * @default 0 - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "iTabIndex": 1 - * } ); - * } ); - */ - "iTabIndex": 0, - - - /** - * All strings that DataTables uses in the user interface that it creates - * are defined in this object, allowing you to modified them individually or - * completely replace them all as required. - * @namespace - */ - "oLanguage": { - /** - * Strings that are used for WAI-ARIA labels and controls only (these are not - * actually visible on the page, but will be read by screenreaders, and thus - * must be internationalised as well). - * @namespace - */ - "oAria": { - /** - * ARIA label that is added to the table headers when the column may be - * sorted ascending by activing the column (click or return when focused). - * Note that the column header is prefixed to this string. - * @type string - * @default : activate to sort column ascending - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oAria": { - * "sSortAscending": " - click/return to sort ascending" - * } - * } - * } ); - * } ); - */ - "sSortAscending": ": activate to sort column ascending", - - /** - * ARIA label that is added to the table headers when the column may be - * sorted descending by activing the column (click or return when focused). - * Note that the column header is prefixed to this string. - * @type string - * @default : activate to sort column ascending - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oAria": { - * "sSortDescending": " - click/return to sort descending" - * } - * } - * } ); - * } ); - */ - "sSortDescending": ": activate to sort column descending" - }, - - /** - * Pagination string used by DataTables for the two built-in pagination - * control types ("two_button" and "full_numbers") - * @namespace - */ - "oPaginate": { - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the first page. - * @type string - * @default First - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sFirst": "First page" - * } - * } - * } ); - * } ); - */ - "sFirst": "First", - - - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the last page. - * @type string - * @default Last - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sLast": "Last page" - * } - * } - * } ); - * } ); - */ - "sLast": "Last", - - - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the next page. - * @type string - * @default Next - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sNext": "Next page" - * } - * } - * } ); - * } ); - */ - "sNext": "Next", - - - /** - * Text to use when using the 'full_numbers' type of pagination for the - * button to take the user to the previous page. - * @type string - * @default Previous - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "oPaginate": { - * "sPrevious": "Previous page" - * } - * } - * } ); - * } ); - */ - "sPrevious": "Previous" - }, - - /** - * This string is shown in preference to sZeroRecords when the table is - * empty of data (regardless of filtering). Note that this is an optional - * parameter - if it is not given, the value of sZeroRecords will be used - * instead (either the default or given value). - * @type string - * @default No data available in table - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sEmptyTable": "No data available in table" - * } - * } ); - * } ); - */ - "sEmptyTable": "No data available in table", - - - /** - * This string gives information to the end user about the information that - * is current on display on the page. The _START_, _END_ and _TOTAL_ - * variables are all dynamically replaced as the table display updates, and - * can be freely moved or removed as the language requirements change. - * @type string - * @default Showing _START_ to _END_ of _TOTAL_ entries - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfo": "Got a total of _TOTAL_ entries to show (_START_ to _END_)" - * } - * } ); - * } ); - */ - "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", - - - /** - * Display information string for when the table is empty. Typically the - * format of this string should match sInfo. - * @type string - * @default Showing 0 to 0 of 0 entries - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoEmpty": "No entries to show" - * } - * } ); - * } ); - */ - "sInfoEmpty": "Showing 0 to 0 of 0 entries", - - - /** - * When a user filters the information in a table, this string is appended - * to the information (sInfo) to give an idea of how strong the filtering - * is. The variable _MAX_ is dynamically updated. - * @type string - * @default (filtered from _MAX_ total entries) - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoFiltered": " - filtering from _MAX_ records" - * } - * } ); - * } ); - */ - "sInfoFiltered": "(filtered from _MAX_ total entries)", - - - /** - * If can be useful to append extra information to the info string at times, - * and this variable does exactly that. This information will be appended to - * the sInfo (sInfoEmpty and sInfoFiltered in whatever combination they are - * being used) at all times. - * @type string - * @default Empty string - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoPostFix": "All records shown are derived from real information." - * } - * } ); - * } ); - */ - "sInfoPostFix": "", - - - /** - * DataTables has a build in number formatter (fnFormatNumber) which is used - * to format large numbers that are used in the table information. By - * default a comma is used, but this can be trivially changed to any - * character you wish with this parameter. - * @type string - * @default , - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sInfoThousands": "'" - * } - * } ); - * } ); - */ - "sInfoThousands": ",", - - - /** - * Detail the action that will be taken when the drop down menu for the - * pagination length option is changed. The '_MENU_' variable is replaced - * with a default select list of 10, 25, 50 and 100, and can be replaced - * with a custom select box if required. - * @type string - * @default Show _MENU_ entries - * @dtopt Language - * - * @example - * // Language change only - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLengthMenu": "Display _MENU_ records" - * } - * } ); - * } ); - * - * @example - * // Language and options change - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLengthMenu": 'Display records' - * } - * } ); - * } ); - */ - "sLengthMenu": "Show _MENU_ entries", - - - /** - * When using Ajax sourced data and during the first draw when DataTables is - * gathering the data, this message is shown in an empty row in the table to - * indicate to the end user the the data is being loaded. Note that this - * parameter is not used when loading data by server-side processing, just - * Ajax sourced data with client-side processing. - * @type string - * @default Loading... - * @dtopt Language - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sLoadingRecords": "Please wait - loading..." - * } - * } ); - * } ); - */ - "sLoadingRecords": "Loading...", - - - /** - * Text which is displayed when the table is processing a user action - * (usually a sort command or similar). - * @type string - * @default Processing... - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sProcessing": "DataTables is currently busy" - * } - * } ); - * } ); - */ - "sProcessing": "Processing...", - - - /** - * Details the actions that will be taken when the user types into the - * filtering input text box. The variable "_INPUT_", if used in the string, - * is replaced with the HTML text box for the filtering input allowing - * control over where it appears in the string. If "_INPUT_" is not given - * then the input box is appended to the string automatically. - * @type string - * @default Search: - * @dtopt Language - * - * @example - * // Input text box will be appended at the end automatically - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sSearch": "Filter records:" - * } - * } ); - * } ); - * - * @example - * // Specify where the filter should appear - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sSearch": "Apply filter _INPUT_ to table" - * } - * } ); - * } ); - */ - "sSearch": "Search:", - - - /** - * All of the language information can be stored in a file on the - * server-side, which DataTables will look up if this parameter is passed. - * It must store the URL of the language file, which is in a JSON format, - * and the object has the same properties as the oLanguage object in the - * initialiser object (i.e. the above parameters). Please refer to one of - * the example language files to see how this works in action. - * @type string - * @default Empty string - i.e. disabled - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sUrl": "http://www.sprymedia.co.uk/dataTables/lang.txt" - * } - * } ); - * } ); - */ - "sUrl": "", - - - /** - * Text shown inside the table records when the is no information to be - * displayed after filtering. sEmptyTable is shown when there is simply no - * information in the table at all (regardless of filtering). - * @type string - * @default No matching records found - * @dtopt Language - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "oLanguage": { - * "sZeroRecords": "No records to display" - * } - * } ); - * } ); - */ - "sZeroRecords": "No matching records found" - }, - - - /** - * This parameter allows you to have define the global filtering state at - * initialisation time. As an object the "sSearch" parameter must be - * defined, but all other parameters are optional. When "bRegex" is true, - * the search string will be treated as a regular expression, when false - * (default) it will be treated as a straight string. When "bSmart" - * DataTables will use it's smart filtering methods (to word match at - * any point in the data), when false this will not be done. - * @namespace - * @extends DataTable.models.oSearch - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "oSearch": {"sSearch": "Initial search"} - * } ); - * } ) - */ - "oSearch": $.extend( {}, DataTable.models.oSearch ), - - - /** - * By default DataTables will look for the property 'aaData' when obtaining - * data from an Ajax source or for server-side processing - this parameter - * allows that property to be changed. You can use Javascript dotted object - * notation to get a data source for multiple levels of nesting. - * @type string - * @default aaData - * @dtopt Options - * @dtopt Server-side - * - * @example - * // Get data from { "data": [...] } - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/data.txt", - * "sAjaxDataProp": "data" - * } ); - * } ); - * - * @example - * // Get data from { "data": { "inner": [...] } } - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/data.txt", - * "sAjaxDataProp": "data.inner" - * } ); - * } ); - */ - "sAjaxDataProp": "aaData", - - - /** - * You can instruct DataTables to load data from an external source using this - * parameter (use aData if you want to pass data in you already have). Simply - * provide a url a JSON object can be obtained from. This object must include - * the parameter 'aaData' which is the data source for the table. - * @type string - * @default null - * @dtopt Options - * @dtopt Server-side - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sAjaxSource": "http://www.sprymedia.co.uk/dataTables/json.php" - * } ); - * } ) - */ - "sAjaxSource": null, - - - /** - * This parameter can be used to override the default prefix that DataTables - * assigns to a cookie when state saving is enabled. - * @type string - * @default SpryMedia_DataTables_ - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sCookiePrefix": "my_datatable_", - * } ); - * } ); - */ - "sCookiePrefix": "SpryMedia_DataTables_", - - - /** - * This initialisation variable allows you to specify exactly where in the - * DOM you want DataTables to inject the various controls it adds to the page - * (for example you might want the pagination controls at the top of the - * table). DIV elements (with or without a custom class) can also be added to - * aid styling. The follow syntax is used: - *
            - *
          • The following options are allowed: - *
              - *
            • 'l' - Length changing
            • 'f' - Filtering input - *
            • 't' - The table!
            • - *
            • 'i' - Information
            • - *
            • 'p' - Pagination
            • - *
            • 'r' - pRocessing
            • - *
            - *
          • - *
          • The following constants are allowed: - *
              - *
            • 'H' - jQueryUI theme "header" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')
            • - *
            • 'F' - jQueryUI theme "footer" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')
            • - *
            - *
          • - *
          • The following syntax is expected: - *
              - *
            • '<' and '>' - div elements
            • - *
            • '<"class" and '>' - div with a class
            • - *
            • '<"#id" and '>' - div with an ID
            • - *
            - *
          • - *
          • Examples: - *
              - *
            • '<"wrapper"flipt>'
            • - *
            • '<lf<t>ip>'
            • - *
            - *
          • - *
          - * @type string - * @default lfrtip (when bJQueryUI is false) or - * <"H"lfr>t<"F"ip> (when bJQueryUI is true) - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sDom": '<"top"i>rt<"bottom"flp><"clear"&lgt;' - * } ); - * } ); - */ - "sDom": "lfrtip", - - - /** - * DataTables features two different built-in pagination interaction methods - * ('two_button' or 'full_numbers') which present different page controls to - * the end user. Further methods can be added using the API (see below). - * @type string - * @default two_button - * @dtopt Options - * - * @example - * $(document).ready( function() { - * $('#example').dataTable( { - * "sPaginationType": "full_numbers" - * } ); - * } ) - */ - "sPaginationType": "two_button", - - - /** - * Enable horizontal scrolling. When a table is too wide to fit into a certain - * layout, or you have a large number of columns in the table, you can enable - * x-scrolling to show the table in a viewport, which can be scrolled. This - * property can by any CSS unit, or a number (in which case it will be treated - * as a pixel measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Features - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollX": "100%", - * "bScrollCollapse": true - * } ); - * } ); - */ - "sScrollX": "", - - - /** - * This property can be used to force a DataTable to use more width than it - * might otherwise do when x-scrolling is enabled. For example if you have a - * table which requires to be well spaced, this parameter is useful for - * "over-sizing" the table, and thus forcing scrolling. This property can by - * any CSS unit, or a number (in which case it will be treated as a pixel - * measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Options - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollX": "100%", - * "sScrollXInner": "110%" - * } ); - * } ); - */ - "sScrollXInner": "", - - - /** - * Enable vertical scrolling. Vertical scrolling will constrain the DataTable - * to the given height, an enable scrolling for any data which overflows the - * current viewport. This can be used as an alternative to paging to display - * a lot of data in a small area (although paging and scrolling can both be - * enabled at the same time). This property can by any CSS unit, or a number - * (in which case it will be treated as a pixel measurement). - * @type string - * @default blank string - i.e. disabled - * @dtopt Features - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "sScrollY": "200px", - * "bPaginate": false - * } ); - * } ); - */ - "sScrollY": "", - - - /** - * Set the HTTP method that is used to make the Ajax call for server-side - * processing or Ajax sourced data. - * @type string - * @default GET - * @dtopt Options - * @dtopt Server-side - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "bServerSide": true, - * "sAjaxSource": "scripts/post.php", - * "sServerMethod": "POST" - * } ); - * } ); - */ - "sServerMethod": "GET" - }; - - - - /** - * Column options that can be given to DataTables at initialisation time. - * @namespace - */ - DataTable.defaults.columns = { - /** - * Allows a column's sorting to take multiple columns into account when - * doing a sort. For example first name / last name columns make sense to - * do a multi-column sort over the two columns. - * @type array - * @default null Takes the value of the column index automatically - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "aDataSort": [ 0, 1 ], "aTargets": [ 0 ] }, - * { "aDataSort": [ 1, 0 ], "aTargets": [ 1 ] }, - * { "aDataSort": [ 2, 3, 4 ], "aTargets": [ 2 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "aDataSort": [ 0, 1 ] }, - * { "aDataSort": [ 1, 0 ] }, - * { "aDataSort": [ 2, 3, 4 ] }, - * null, - * null - * ] - * } ); - * } ); - */ - "aDataSort": null, - - - /** - * You can control the default sorting direction, and even alter the behaviour - * of the sort handler (i.e. only allow ascending sorting etc) using this - * parameter. - * @type array - * @default [ 'asc', 'desc' ] - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "asSorting": [ "asc" ], "aTargets": [ 1 ] }, - * { "asSorting": [ "desc", "asc", "asc" ], "aTargets": [ 2 ] }, - * { "asSorting": [ "desc" ], "aTargets": [ 3 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * { "asSorting": [ "asc" ] }, - * { "asSorting": [ "desc", "asc", "asc" ] }, - * { "asSorting": [ "desc" ] }, - * null - * ] - * } ); - * } ); - */ - "asSorting": [ 'asc', 'desc' ], - - - /** - * Enable or disable filtering on the data in this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bSearchable": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bSearchable": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bSearchable": true, - - - /** - * Enable or disable sorting on this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bSortable": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bSortable": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bSortable": true, - - - /** - * When using fnRender() for a column, you may wish to use the original data - * (before rendering) for sorting and filtering (the default is to used the - * rendered data that the user can see). This may be useful for dates etc. - * - * *NOTE* It is it is advisable now to use mDataProp as a function and make - * use of the 'type' that it gives, allowing (potentially) different data to - * be used for sorting, filtering, display and type detection. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "fnRender": function ( oObj ) { - * return oObj.aData[0] +' '+ oObj.aData[3]; - * }, - * "bUseRendered": false, - * "aTargets": [ 0 ] - * } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { - * "fnRender": function ( oObj ) { - * return oObj.aData[0] +' '+ oObj.aData[3]; - * }, - * "bUseRendered": false - * }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "bUseRendered": true, - - - /** - * Enable or disable the display of this column. - * @type boolean - * @default true - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "bVisible": false, "aTargets": [ 0 ] } - * ] } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "bVisible": false }, - * null, - * null, - * null, - * null - * ] } ); - * } ); - */ - "bVisible": true, - - - /** - * Developer definable function that is called whenever a cell is created (Ajax source, - * etc) or processed for input (DOM source). This can be used as a compliment to fnRender - * allowing you to modify the DOM element (add background colour for example) when the - * element is available (since it is not when fnRender is called). - * @type function - * @param {element} nTd The TD node that has been created - * @param {*} sData The Data for the cell - * @param {array|object} oData The data for the whole row - * @param {int} iRow The row index for the aoData data store - * @param {int} iCol The column index for aoColumns - * @dtopt Columns - * - * @example - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ { - * "aTargets": [3], - * "fnCreatedCell": function (nTd, sData, oData, iRow, iCol) { - * if ( sData == "1.7" ) { - * $(nTd).css('color', 'blue') - * } - * } - * } ] - * }); - * } ); - */ - "fnCreatedCell": null, - - - /** - * Custom display function that will be called for the display of each cell in - * this column. - * @type function - * @param {object} o Object with the following parameters: - * @param {int} o.iDataRow The row in aoData - * @param {int} o.iDataColumn The column in question - * @param {array} o.aData The data for the row in question - * @param {object} o.oSettings The settings object for this DataTables instance - * @param {object} o.mDataProp The data property used for this column - * @param {*} val The current cell value - * @returns {string} The string you which to use in the display - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "fnRender": function ( o, val ) { - * return o.aData[0] +' '+ o.aData[3]; - * }, - * "aTargets": [ 0 ] - * } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "fnRender": function ( o, val ) { - * return o.aData[0] +' '+ o.aData[3]; - * } }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "fnRender": null, - - - /** - * The column index (starting from 0!) that you wish a sort to be performed - * upon when this column is selected for sorting. This can be used for sorting - * on hidden columns for example. - * @type int - * @default -1 Use automatically calculated column index - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "iDataSort": 1, "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "iDataSort": 1 }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "iDataSort": -1, - - - /** - * This property can be used to read data from any JSON data source property, - * including deeply nested objects / properties. mDataProp can be given in a - * number of different ways which effect its behaviour: - *
            - *
          • integer - treated as an array index for the data source. This is the - * default that DataTables uses (incrementally increased for each column).
          • - *
          • string - read an object property from the data source. Note that you can - * use Javascript dotted notation to read deep properties/arrays from the - * data source.
          • - *
          • null - the sDafaultContent option will use used for the cell (empty - * string by default. This can be useful on generated columns such as - * edit / delete action columns.
          • - *
          • function - the function given will be executed whenever DataTables - * needs to set or get the data for a cell in the column. The function - * takes three parameters: - *
              - *
            • {array|object} The data source for the row
            • - *
            • {string} The type call data requested - this will be 'set' when - * setting data or 'filter', 'display', 'type' or 'sort' when gathering - * data.
            • - *
            • {*} Data to set when the second parameter is 'set'.
            • - *
            - * The return value from the function is not required when 'set' is the type - * of call, but otherwise the return is what will be used for the data - * requested.
          • - *
          - * @type string|int|function|null - * @default null Use automatically calculated column index - * @dtopt Columns - * - * @example - * // Read table data from objects - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "sAjaxSource": "sources/deep.txt", - * "aoColumns": [ - * { "mDataProp": "engine" }, - * { "mDataProp": "browser" }, - * { "mDataProp": "platform.inner" }, - * { "mDataProp": "platform.details.0" }, - * { "mDataProp": "platform.details.1" } - * ] - * } ); - * } ); - * - * @example - * // Using mDataProp as a function to provide different information for - * // sorting, filtering and display. In this case, currency (price) - * $(document).ready(function() { - * var oTable = $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "aTargets": [ 0 ], - * "mDataProp": function ( source, type, val ) { - * if (type === 'set') { - * source.price = val; - * // Store the computed dislay and filter values for efficiency - * source.price_display = val=="" ? "" : "$"+numberFormat(val); - * source.price_filter = val=="" ? "" : "$"+numberFormat(val)+" "+val; - * return; - * } - * else if (type === 'display') { - * return source.price_display; - * } - * else if (type === 'filter') { - * return source.price_filter; - * } - * // 'sort' and 'type' both just use the integer - * return source.price; - * } - * ] - * } ); - * } ); - */ - "mDataProp": null, - - - /** - * Class to give to each cell in this column. - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sClass": "my_class", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sClass": "my_class" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sClass": "", - - /** - * When DataTables calculates the column widths to assign to each column, - * it finds the longest string in each column and then constructs a - * temporary table and reads the widths from that. The problem with this - * is that "mmm" is much wider then "iiii", but the latter is a longer - * string - thus the calculation can go wrong (doing it properly and putting - * it into an DOM object and measuring that is horribly(!) slow). Thus as - * a "work around" we provide this option. It will append its value to the - * text that is found to be the longest string for the column - i.e. padding. - * Generally you shouldn't need this, and it is not documented on the - * general DataTables.net documentation - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * null, - * { - * "sContentPadding": "mmm" - * } - * ] - * } ); - * } ); - */ - "sContentPadding": "", - - - /** - * Allows a default value to be given for a column's data, and will be used - * whenever a null data source is encountered (this can be because mDataProp - * is set to null, or because the data source itself is null). - * @type string - * @default null - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { - * "mDataProp": null, - * "sDefaultContent": "Edit", - * "aTargets": [ -1 ] - * } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * null, - * { - * "mDataProp": null, - * "sDefaultContent": "Edit" - * } - * ] - * } ); - * } ); - */ - "sDefaultContent": null, - - - /** - * This parameter is only used in DataTables' server-side processing. It can - * be exceptionally useful to know what columns are being displayed on the - * client side, and to map these to database fields. When defined, the names - * also allow DataTables to reorder information from the server if it comes - * back in an unexpected order (i.e. if you switch your columns around on the - * client-side, your server-side code does not also need updating). - * @type string - * @default Empty string - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sName": "engine", "aTargets": [ 0 ] }, - * { "sName": "browser", "aTargets": [ 1 ] }, - * { "sName": "platform", "aTargets": [ 2 ] }, - * { "sName": "version", "aTargets": [ 3 ] }, - * { "sName": "grade", "aTargets": [ 4 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sName": "engine" }, - * { "sName": "browser" }, - * { "sName": "platform" }, - * { "sName": "version" }, - * { "sName": "grade" } - * ] - * } ); - * } ); - */ - "sName": "", - - - /** - * Defines a data source type for the sorting which can be used to read - * realtime information from the table (updating the internally cached - * version) prior to sorting. This allows sorting to occur on user editable - * elements such as form inputs. - * @type string - * @default std - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sSortDataType": "dom-text", "aTargets": [ 2, 3 ] }, - * { "sType": "numeric", "aTargets": [ 3 ] }, - * { "sSortDataType": "dom-select", "aTargets": [ 4 ] }, - * { "sSortDataType": "dom-checkbox", "aTargets": [ 5 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * null, - * null, - * { "sSortDataType": "dom-text" }, - * { "sSortDataType": "dom-text", "sType": "numeric" }, - * { "sSortDataType": "dom-select" }, - * { "sSortDataType": "dom-checkbox" } - * ] - * } ); - * } ); - */ - "sSortDataType": "std", - - - /** - * The title of this column. - * @type string - * @default null Derived from the 'TH' value for this column in the - * original HTML table. - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sTitle": "My column title", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sTitle": "My column title" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sTitle": null, - - - /** - * The type allows you to specify how the data for this column will be sorted. - * Four types (string, numeric, date and html (which will strip HTML tags - * before sorting)) are currently available. Note that only date formats - * understood by Javascript's Date() object will be accepted as type date. For - * example: "Mar 26, 2008 5:03 PM". May take the values: 'string', 'numeric', - * 'date' or 'html' (by default). Further types can be adding through - * plug-ins. - * @type string - * @default null Auto-detected from raw data - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sType": "html", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sType": "html" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sType": null, - - - /** - * Defining the width of the column, this parameter may take any CSS value - * (3em, 20px etc). DataTables applys 'smart' widths to columns which have not - * been given a specific width through this interface ensuring that the table - * remains readable. - * @type string - * @default null Automatic - * @dtopt Columns - * - * @example - * // Using aoColumnDefs - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumnDefs": [ - * { "sWidth": "20%", "aTargets": [ 0 ] } - * ] - * } ); - * } ); - * - * @example - * // Using aoColumns - * $(document).ready(function() { - * $('#example').dataTable( { - * "aoColumns": [ - * { "sWidth": "20%" }, - * null, - * null, - * null, - * null - * ] - * } ); - * } ); - */ - "sWidth": null - }; - - - - /** - * DataTables settings object - this holds all the information needed for a - * given table, including configuration, data and current application of the - * table options. DataTables does not have a single instance for each DataTable - * with the settings attached to that instance, but rather instances of the - * DataTable "class" are created on-the-fly as needed (typically by a - * $().dataTable() call) and the settings object is then applied to that - * instance. - * - * Note that this object is related to {@link DataTable.defaults} but this - * one is the internal data store for DataTables's cache of columns. It should - * NOT be manipulated outside of DataTables. Any configuration should be done - * through the initialisation options. - * @namespace - * @todo Really should attach the settings object to individual instances so we - * don't need to create new instances on each $().dataTable() call (if the - * table already exists). It would also save passing oSettings around and - * into every single function. However, this is a very significant - * architecture change for DataTables and will almost certainly break - * backwards compatibility with older installations. This is something that - * will be done in 2.0. - */ - DataTable.models.oSettings = { - /** - * Primary features of DataTables and their enablement state. - * @namespace - */ - "oFeatures": { - - /** - * Flag to say if DataTables should automatically try to calculate the - * optimum table and columns widths (true) or not (false). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bAutoWidth": null, - - /** - * Delay the creation of TR and TD elements until they are actually - * needed by a driven page draw. This can give a significant speed - * increase for Ajax source and Javascript source data, but makes no - * difference at all fro DOM and server-side processing tables. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bDeferRender": null, - - /** - * Enable filtering on the table or not. Note that if this is disabled - * then there is no filtering at all on the table, including fnFilter. - * To just remove the filtering input use sDom and remove the 'f' option. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bFilter": null, - - /** - * Table information element (the 'Showing x of y records' div) enable - * flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bInfo": null, - - /** - * Present a user control allowing the end user to change the page size - * when pagination is enabled. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bLengthChange": null, - - /** - * Pagination enabled or not. Note that if this is disabled then length - * changing must also be disabled. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bPaginate": null, - - /** - * Processing indicator enable flag whenever DataTables is enacting a - * user request - typically an Ajax request for server-side processing. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bProcessing": null, - - /** - * Server-side processing enabled flag - when enabled DataTables will - * get all data from the server for every draw - there is no filtering, - * sorting or paging done on the client-side. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bServerSide": null, - - /** - * Sorting enablement flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSort": null, - - /** - * Apply a class to the columns which are being sorted to provide a - * visual highlight or not. This can slow things down when enabled since - * there is a lot of DOM interaction. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSortClasses": null, - - /** - * State saving enablement flag. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bStateSave": null - }, - - - /** - * Scrolling settings for a table. - * @namespace - */ - "oScroll": { - /** - * Indicate if DataTables should be allowed to set the padding / margin - * etc for the scrolling header elements or not. Typically you will want - * this. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bAutoCss": null, - - /** - * When the table is shorter in height than sScrollY, collapse the - * table container down to the height of the table (when true). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bCollapse": null, - - /** - * Infinite scrolling enablement flag. Now deprecated in favour of - * using the Scroller plug-in. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bInfinite": null, - - /** - * Width of the scrollbar for the web-browser's platform. Calculated - * during table initialisation. - * @type int - * @default 0 - */ - "iBarWidth": 0, - - /** - * Space (in pixels) between the bottom of the scrolling container and - * the bottom of the scrolling viewport before the next page is loaded - * when using infinite scrolling. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type int - */ - "iLoadGap": null, - - /** - * Viewport width for horizontal scrolling. Horizontal scrolling is - * disabled if an empty string. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sX": null, - - /** - * Width to expand the table to when using x-scrolling. Typically you - * should not need to use this. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @deprecated - */ - "sXInner": null, - - /** - * Viewport height for vertical scrolling. Vertical scrolling is disabled - * if an empty string. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sY": null - }, - - /** - * Language information for the table. - * @namespace - * @extends DataTable.defaults.oLanguage - */ - "oLanguage": { - /** - * Information callback function. See - * {@link DataTable.defaults.fnInfoCallback} - * @type function - * @default - */ - "fnInfoCallback": null - }, - - /** - * Array referencing the nodes which are used for the features. The - * parameters of this object match what is allowed by sDom - i.e. - *
            - *
          • 'l' - Length changing
          • - *
          • 'f' - Filtering input
          • - *
          • 't' - The table!
          • - *
          • 'i' - Information
          • - *
          • 'p' - Pagination
          • - *
          • 'r' - pRocessing
          • - *
          - * @type array - * @default [] - */ - "aanFeatures": [], - - /** - * Store data information - see {@link DataTable.models.oRow} for detailed - * information. - * @type array - * @default [] - */ - "aoData": [], - - /** - * Array of indexes which are in the current display (after filtering etc) - * @type array - * @default [] - */ - "aiDisplay": [], - - /** - * Array of indexes for display - no filtering - * @type array - * @default [] - */ - "aiDisplayMaster": [], - - /** - * Store information about each column that is in use - * @type array - * @default [] - */ - "aoColumns": [], - - /** - * Store information about the table's header - * @type array - * @default [] - */ - "aoHeader": [], - - /** - * Store information about the table's footer - * @type array - * @default [] - */ - "aoFooter": [], - - /** - * Search data array for regular expression searching - * @type array - * @default [] - */ - "asDataSearch": [], - - /** - * Store the applied global search information in case we want to force a - * research or compare the old search to a new one. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @namespace - * @extends DataTable.models.oSearch - */ - "oPreviousSearch": {}, - - /** - * Store the applied search for each column - see - * {@link DataTable.models.oSearch} for the format that is used for the - * filtering information for each column. - * @type array - * @default [] - */ - "aoPreSearchCols": [], - - /** - * Sorting that is applied to the table. Note that the inner arrays are - * used in the following manner: - *
            - *
          • Index 0 - column number
          • - *
          • Index 1 - current sorting direction
          • - *
          • Index 2 - index of asSorting for this column
          • - *
          - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @todo These inner arrays should really be objects - */ - "aaSorting": null, - - /** - * Sorting that is always applied to the table (i.e. prefixed in front of - * aaSorting). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array|null - * @default null - */ - "aaSortingFixed": null, - - /** - * Classes to use for the striping of a table. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @default [] - */ - "asStripeClasses": null, - - /** - * If restoring a table - we should restore its striping classes as well - * @type array - * @default [] - */ - "asDestroyStripes": [], - - /** - * If restoring a table - we should restore its width - * @type int - * @default 0 - */ - "sDestroyWidth": 0, - - /** - * Callback functions array for every time a row is inserted (i.e. on a draw). - * @type array - * @default [] - */ - "aoRowCallback": [], - - /** - * Callback functions for the header on each draw. - * @type array - * @default [] - */ - "aoHeaderCallback": [], - - /** - * Callback function for the footer on each draw. - * @type array - * @default [] - */ - "aoFooterCallback": [], - - /** - * Array of callback functions for draw callback functions - * @type array - * @default [] - */ - "aoDrawCallback": [], - - /** - * Array of callback functions for row created function - * @type array - * @default [] - */ - "aoRowCreatedCallback": [], - - /** - * Callback functions for just before the table is redrawn. A return of - * false will be used to cancel the draw. - * @type array - * @default [] - */ - "aoPreDrawCallback": [], - - /** - * Callback functions for when the table has been initialised. - * @type array - * @default [] - */ - "aoInitComplete": [], - - - /** - * Callbacks for modifying the settings to be stored for state saving, prior to - * saving state. - * @type array - * @default [] - */ - "aoStateSaveParams": [], - - /** - * Callbacks for modifying the settings that have been stored for state saving - * prior to using the stored values to restore the state. - * @type array - * @default [] - */ - "aoStateLoadParams": [], - - /** - * Callbacks for operating on the settings object once the saved state has been - * loaded - * @type array - * @default [] - */ - "aoStateLoaded": [], - - /** - * Cache the table ID for quick access - * @type string - * @default Empty string - */ - "sTableId": "", - - /** - * The TABLE node for the main table - * @type node - * @default null - */ - "nTable": null, - - /** - * Permanent ref to the thead element - * @type node - * @default null - */ - "nTHead": null, - - /** - * Permanent ref to the tfoot element - if it exists - * @type node - * @default null - */ - "nTFoot": null, - - /** - * Permanent ref to the tbody element - * @type node - * @default null - */ - "nTBody": null, - - /** - * Cache the wrapper node (contains all DataTables controlled elements) - * @type node - * @default null - */ - "nTableWrapper": null, - - /** - * Indicate if when using server-side processing the loading of data - * should be deferred until the second draw. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - * @default false - */ - "bDeferLoading": false, - - /** - * Indicate if all required information has been read in - * @type boolean - * @default false - */ - "bInitialised": false, - - /** - * Information about open rows. Each object in the array has the parameters - * 'nTr' and 'nParent' - * @type array - * @default [] - */ - "aoOpenRows": [], - - /** - * Dictate the positioning of DataTables' control elements - see - * {@link DataTable.model.oInit.sDom}. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default null - */ - "sDom": null, - - /** - * Which type of pagination should be used. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default two_button - */ - "sPaginationType": "two_button", - - /** - * The cookie duration (for bStateSave) in seconds. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type int - * @default 0 - */ - "iCookieDuration": 0, - - /** - * The cookie name prefix. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default Empty string - */ - "sCookiePrefix": "", - - /** - * Callback function for cookie creation. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - * @default null - */ - "fnCookieCallback": null, - - /** - * Array of callback functions for state saving. Each array element is an - * object with the following parameters: - *
            - *
          • function:fn - function to call. Takes two parameters, oSettings - * and the JSON string to save that has been thus far created. Returns - * a JSON string to be inserted into a json object - * (i.e. '"param": [ 0, 1, 2]')
          • - *
          • string:sName - name of callback
          • - *
          - * @type array - * @default [] - */ - "aoStateSave": [], - - /** - * Array of callback functions for state loading. Each array element is an - * object with the following parameters: - *
            - *
          • function:fn - function to call. Takes two parameters, oSettings - * and the object stored. May return false to cancel state loading
          • - *
          • string:sName - name of callback
          • - *
          - * @type array - * @default [] - */ - "aoStateLoad": [], - - /** - * State that was loaded from the cookie. Useful for back reference - * @type object - * @default null - */ - "oLoadedState": null, - - /** - * Source url for AJAX data for the table. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - * @default null - */ - "sAjaxSource": null, - - /** - * Property from a given object from which to read the table data from. This - * can be an empty string (when not server-side processing), in which case - * it is assumed an an array is given directly. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sAjaxDataProp": null, - - /** - * Note if draw should be blocked while getting data - * @type boolean - * @default true - */ - "bAjaxDataGet": true, - - /** - * The last jQuery XHR object that was used for server-side data gathering. - * This can be used for working with the XHR information in one of the - * callbacks - * @type object - * @default null - */ - "jqXHR": null, - - /** - * Function to get the server-side data. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - */ - "fnServerData": null, - - /** - * Functions which are called prior to sending an Ajax request so extra - * parameters can easily be sent to the server - * @type array - * @default [] - */ - "aoServerParams": [], - - /** - * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if - * required). - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type string - */ - "sServerMethod": null, - - /** - * Format numbers for display. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type function - */ - "fnFormatNumber": null, - - /** - * List of options that can be used for the user selectable length menu. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type array - * @default [] - */ - "aLengthMenu": null, - - /** - * Counter for the draws that the table does. Also used as a tracker for - * server-side processing - * @type int - * @default 0 - */ - "iDraw": 0, - - /** - * Indicate if a redraw is being done - useful for Ajax - * @type boolean - * @default false - */ - "bDrawing": false, - - /** - * Draw index (iDraw) of the last error when parsing the returned data - * @type int - * @default -1 - */ - "iDrawError": -1, - - /** - * Paging display length - * @type int - * @default 10 - */ - "_iDisplayLength": 10, - - /** - * Paging start point - aiDisplay index - * @type int - * @default 0 - */ - "_iDisplayStart": 0, - - /** - * Paging end point - aiDisplay index. Use fnDisplayEnd rather than - * this property to get the end point - * @type int - * @default 10 - * @private - */ - "_iDisplayEnd": 10, - - /** - * Server-side processing - number of records in the result set - * (i.e. before filtering), Use fnRecordsTotal rather than - * this property to get the value of the number of records, regardless of - * the server-side processing setting. - * @type int - * @default 0 - * @private - */ - "_iRecordsTotal": 0, - - /** - * Server-side processing - number of records in the current display set - * (i.e. after filtering). Use fnRecordsDisplay rather than - * this property to get the value of the number of records, regardless of - * the server-side processing setting. - * @type boolean - * @default 0 - * @private - */ - "_iRecordsDisplay": 0, - - /** - * Flag to indicate if jQuery UI marking and classes should be used. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bJUI": null, - - /** - * The classes to use for the table - * @type object - * @default {} - */ - "oClasses": {}, - - /** - * Flag attached to the settings object so you can check in the draw - * callback if filtering has been done in the draw. Deprecated in favour of - * events. - * @type boolean - * @default false - * @deprecated - */ - "bFiltered": false, - - /** - * Flag attached to the settings object so you can check in the draw - * callback if sorting has been done in the draw. Deprecated in favour of - * events. - * @type boolean - * @default false - * @deprecated - */ - "bSorted": false, - - /** - * Indicate that if multiple rows are in the header and there is more than - * one unique cell per column, if the top one (true) or bottom one (false) - * should be used for sorting / title by DataTables. - * Note that this parameter will be set by the initialisation routine. To - * set a default use {@link DataTable.defaults}. - * @type boolean - */ - "bSortCellsTop": null, - - /** - * Initialisation object that is used for the table - * @type object - * @default null - */ - "oInit": null, - - /** - * Destroy callback functions - for plug-ins to attach themselves to the - * destroy so they can clean up markup and events. - * @type array - * @default [] - */ - "aoDestroyCallback": [], - - - /** - * Get the number of records in the current record set, before filtering - * @type function - */ - "fnRecordsTotal": function () - { - if ( this.oFeatures.bServerSide ) { - return parseInt(this._iRecordsTotal, 10); - } else { - return this.aiDisplayMaster.length; - } - }, - - /** - * Get the number of records in the current record set, after filtering - * @type function - */ - "fnRecordsDisplay": function () - { - if ( this.oFeatures.bServerSide ) { - return parseInt(this._iRecordsDisplay, 10); - } else { - return this.aiDisplay.length; - } - }, - - /** - * Set the display end point - aiDisplay index - * @type function - * @todo Should do away with _iDisplayEnd and calculate it on-the-fly here - */ - "fnDisplayEnd": function () - { - if ( this.oFeatures.bServerSide ) { - if ( this.oFeatures.bPaginate === false || this._iDisplayLength == -1 ) { - return this._iDisplayStart+this.aiDisplay.length; - } else { - return Math.min( this._iDisplayStart+this._iDisplayLength, - this._iRecordsDisplay ); - } - } else { - return this._iDisplayEnd; - } - }, - - /** - * The DataTables object for this table - * @type object - * @default null - */ - "oInstance": null, - - /** - * Unique identifier for each instance of the DataTables object. If there - * is an ID on the table node, then it takes that value, otherwise an - * incrementing internal counter is used. - * @type string - * @default null - */ - "sInstance": null, - - /** - * tabindex attribute value that is added to DataTables control elements, allowing - * keyboard navigation of the table and its controls. - */ - "iTabIndex": 0 - }; - - /** - * Extension object for DataTables that is used to provide all extension options. - * - * Note that the DataTable.ext object is available through - * jQuery.fn.dataTable.ext where it may be accessed and manipulated. It is - * also aliased to jQuery.fn.dataTableExt for historic reasons. - * @namespace - * @extends DataTable.models.ext - */ - DataTable.ext = $.extend( true, {}, DataTable.models.ext ); - - $.extend( DataTable.ext.oStdClasses, { - "sTable": "dataTable", - - /* Two buttons buttons */ - "sPagePrevEnabled": "paginate_enabled_previous", - "sPagePrevDisabled": "paginate_disabled_previous", - "sPageNextEnabled": "paginate_enabled_next", - "sPageNextDisabled": "paginate_disabled_next", - "sPageJUINext": "", - "sPageJUIPrev": "", - - /* Full numbers paging buttons */ - "sPageButton": "paginate_button", - "sPageButtonActive": "paginate_active", - "sPageButtonStaticDisabled": "paginate_button paginate_button_disabled", - "sPageFirst": "first", - "sPagePrevious": "previous", - "sPageNext": "next", - "sPageLast": "last", - - /* Striping classes */ - "sStripeOdd": "odd", - "sStripeEven": "even", - - /* Empty row */ - "sRowEmpty": "dataTables_empty", - - /* Features */ - "sWrapper": "dataTables_wrapper", - "sFilter": "dataTables_filter", - "sInfo": "dataTables_info", - "sPaging": "dataTables_paginate paging_", /* Note that the type is postfixed */ - "sLength": "dataTables_length", - "sProcessing": "dataTables_processing", - - /* Sorting */ - "sSortAsc": "sorting_asc", - "sSortDesc": "sorting_desc", - "sSortable": "sorting", /* Sortable in both directions */ - "sSortableAsc": "sorting_asc_disabled", - "sSortableDesc": "sorting_desc_disabled", - "sSortableNone": "sorting_disabled", - "sSortColumn": "sorting_", /* Note that an int is postfixed for the sorting order */ - "sSortJUIAsc": "", - "sSortJUIDesc": "", - "sSortJUI": "", - "sSortJUIAscAllowed": "", - "sSortJUIDescAllowed": "", - "sSortJUIWrapper": "", - "sSortIcon": "", - - /* Scrolling */ - "sScrollWrapper": "dataTables_scroll", - "sScrollHead": "dataTables_scrollHead", - "sScrollHeadInner": "dataTables_scrollHeadInner", - "sScrollBody": "dataTables_scrollBody", - "sScrollFoot": "dataTables_scrollFoot", - "sScrollFootInner": "dataTables_scrollFootInner", - - /* Misc */ - "sFooterTH": "" - } ); - - - $.extend( DataTable.ext.oJUIClasses, DataTable.ext.oStdClasses, { - /* Two buttons buttons */ - "sPagePrevEnabled": "fg-button ui-button ui-state-default ui-corner-left", - "sPagePrevDisabled": "fg-button ui-button ui-state-default ui-corner-left ui-state-disabled", - "sPageNextEnabled": "fg-button ui-button ui-state-default ui-corner-right", - "sPageNextDisabled": "fg-button ui-button ui-state-default ui-corner-right ui-state-disabled", - "sPageJUINext": "ui-icon ui-icon-circle-arrow-e", - "sPageJUIPrev": "ui-icon ui-icon-circle-arrow-w", - - /* Full numbers paging buttons */ - "sPageButton": "fg-button ui-button ui-state-default", - "sPageButtonActive": "fg-button ui-button ui-state-default ui-state-disabled", - "sPageButtonStaticDisabled": "fg-button ui-button ui-state-default ui-state-disabled", - "sPageFirst": "first ui-corner-tl ui-corner-bl", - "sPageLast": "last ui-corner-tr ui-corner-br", - - /* Features */ - "sPaging": "dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi "+ - "ui-buttonset-multi paging_", /* Note that the type is postfixed */ - - /* Sorting */ - "sSortAsc": "ui-state-default", - "sSortDesc": "ui-state-default", - "sSortable": "ui-state-default", - "sSortableAsc": "ui-state-default", - "sSortableDesc": "ui-state-default", - "sSortableNone": "ui-state-default", - "sSortJUIAsc": "css_right ui-icon ui-icon-triangle-1-n", - "sSortJUIDesc": "css_right ui-icon ui-icon-triangle-1-s", - "sSortJUI": "css_right ui-icon ui-icon-carat-2-n-s", - "sSortJUIAscAllowed": "css_right ui-icon ui-icon-carat-1-n", - "sSortJUIDescAllowed": "css_right ui-icon ui-icon-carat-1-s", - "sSortJUIWrapper": "DataTables_sort_wrapper", - "sSortIcon": "DataTables_sort_icon", - - /* Scrolling */ - "sScrollHead": "dataTables_scrollHead ui-state-default", - "sScrollFoot": "dataTables_scrollFoot ui-state-default", - - /* Misc */ - "sFooterTH": "ui-state-default" - } ); - - - /* - * Variable: oPagination - * Purpose: - * Scope: jQuery.fn.dataTableExt - */ - $.extend( DataTable.ext.oPagination, { - /* - * Variable: two_button - * Purpose: Standard two button (forward/back) pagination - * Scope: jQuery.fn.dataTableExt.oPagination - */ - "two_button": { - /* - * Function: oPagination.two_button.fnInit - * Purpose: Initialise dom elements required for pagination with forward/back buttons only - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * node:nPaging - the DIV which contains this pagination control - * function:fnCallbackDraw - draw function which must be called on update - */ - "fnInit": function ( oSettings, nPaging, fnCallbackDraw ) - { - var oLang = oSettings.oLanguage.oPaginate; - var oClasses = oSettings.oClasses; - var fnClickHandler = function ( e ) { - if ( oSettings.oApi._fnPageChange( oSettings, e.data.action ) ) - { - fnCallbackDraw( oSettings ); - } - }; - - var sAppend = (!oSettings.bJUI) ? - ''+oLang.sPrevious+''+ - ''+oLang.sNext+'' - : - ''+ - ''; - $(nPaging).append( sAppend ); - - var els = $('a', nPaging); - var nPrevious = els[0], - nNext = els[1]; - - oSettings.oApi._fnBindAction( nPrevious, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); - - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nPrevious.id = oSettings.sTableId+'_previous'; - nNext.id = oSettings.sTableId+'_next'; - - nPrevious.setAttribute('aria-controls', oSettings.sTableId); - nNext.setAttribute('aria-controls', oSettings.sTableId); - } - }, - - /* - * Function: oPagination.two_button.fnUpdate - * Purpose: Update the two button pagination at the end of the draw - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } - - var oClasses = oSettings.oClasses; - var an = oSettings.aanFeatures.p; - - /* Loop over each instance of the pager */ - for ( var i=0, iLen=an.length ; i'+oLang.sFirst+''+ - ''+oLang.sPrevious+''+ - ''+ - ''+oLang.sNext+''+ - ''+oLang.sLast+'' - ); - var els = $('a', nPaging); - var nFirst = els[0], - nPrev = els[1], - nNext = els[2], - nLast = els[3]; - - oSettings.oApi._fnBindAction( nFirst, {action: "first"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nPrev, {action: "previous"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nNext, {action: "next"}, fnClickHandler ); - oSettings.oApi._fnBindAction( nLast, {action: "last"}, fnClickHandler ); - - /* ID the first elements only */ - if ( !oSettings.aanFeatures.p ) - { - nPaging.id = oSettings.sTableId+'_paginate'; - nFirst.id =oSettings.sTableId+'_first'; - nPrev.id =oSettings.sTableId+'_previous'; - nNext.id =oSettings.sTableId+'_next'; - nLast.id =oSettings.sTableId+'_last'; - } - }, - - /* - * Function: oPagination.full_numbers.fnUpdate - * Purpose: Update the list of page buttons shows - * Returns: - - * Inputs: object:oSettings - dataTables settings object - * function:fnCallbackDraw - draw function to call on page change - */ - "fnUpdate": function ( oSettings, fnCallbackDraw ) - { - if ( !oSettings.aanFeatures.p ) - { - return; - } - - var iPageCount = DataTable.ext.oPagination.iFullNumbersShowPages; - var iPageCountHalf = Math.floor(iPageCount / 2); - var iPages = Math.ceil((oSettings.fnRecordsDisplay()) / oSettings._iDisplayLength); - var iCurrentPage = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1; - var sList = ""; - var iStartButton, iEndButton, i, iLen; - var oClasses = oSettings.oClasses; - var anButtons, anStatic, nPaginateList; - var an = oSettings.aanFeatures.p; - var fnBind = function (j) { - oSettings.oApi._fnBindAction( this, {"page": j+iStartButton-1}, function(e) { - /* Use the information in the element to jump to the required page */ - oSettings.oApi._fnPageChange( oSettings, e.data.page ); - fnCallbackDraw( oSettings ); - e.preventDefault(); - } ); - }; - - /* Pages calculation */ - if (iPages < iPageCount) - { - iStartButton = 1; - iEndButton = iPages; - } - else if (iCurrentPage <= iPageCountHalf) - { - iStartButton = 1; - iEndButton = iPageCount; - } - else if (iCurrentPage >= (iPages - iPageCountHalf)) - { - iStartButton = iPages - iPageCount + 1; - iEndButton = iPages; - } - else - { - iStartButton = iCurrentPage - Math.ceil(iPageCount / 2) + 1; - iEndButton = iStartButton + iPageCount - 1; - } - - /* Build the dynamic list */ - for ( i=iStartButton ; i<=iEndButton ; i++ ) - { - sList += (iCurrentPage !== i) ? - ''+oSettings.fnFormatNumber(i)+'' : - ''+oSettings.fnFormatNumber(i)+''; - } - - /* Loop over each instance of the pager */ - for ( i=0, iLen=an.length ; i y) ? 1 : 0)); - }, - - "string-desc": function ( x, y ) - { - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }, - - - /* - * html sorting (ignore html tags) - */ - "html-pre": function ( a ) - { - return a.replace( /<.*?>/g, "" ).toLowerCase(); - }, - - "html-asc": function ( x, y ) - { - return ((x < y) ? -1 : ((x > y) ? 1 : 0)); - }, - - "html-desc": function ( x, y ) - { - return ((x < y) ? 1 : ((x > y) ? -1 : 0)); - }, - - - /* - * date sorting - */ - "date-pre": function ( a ) - { - var x = Date.parse( a ); - - if ( isNaN(x) || x==="" ) - { - x = Date.parse( "01/01/1970 00:00:00" ); - } - return x; - }, - - "date-asc": function ( x, y ) - { - return x - y; - }, - - "date-desc": function ( x, y ) - { - return y - x; - }, - - - /* - * numerical sorting - */ - "numeric-pre": function ( a ) - { - return (a=="-" || a==="") ? 0 : a*1; - }, - - "numeric-asc": function ( x, y ) - { - return x - y; - }, - - "numeric-desc": function ( x, y ) - { - return y - x; - } - } ); - - - $.extend( DataTable.ext.aTypes, [ - /* - * Function: - - * Purpose: Check to see if a string is numeric - * Returns: string:'numeric' or null - * Inputs: mixed:sText - string to check - */ - function ( sData ) - { - /* Allow zero length strings as a number */ - if ( typeof sData === 'number' ) - { - return 'numeric'; - } - else if ( typeof sData !== 'string' ) - { - return null; - } - - var sValidFirstChars = "0123456789-"; - var sValidChars = "0123456789."; - var Char; - var bDecimal = false; - - /* Check for a valid first char (no period and allow negatives) */ - Char = sData.charAt(0); - if (sValidFirstChars.indexOf(Char) == -1) - { - return null; - } - - /* Check all the other characters are valid */ - for ( var i=1 ; i') != -1 ) - { - return 'html'; - } - return null; - } - ] ); - - - // jQuery aliases - $.fn.DataTable = DataTable; - $.fn.dataTable = DataTable; - $.fn.dataTableSettings = DataTable.settings; - $.fn.dataTableExt = DataTable.ext; - - - // Information about events fired by DataTables - for documentation. - /** - * Draw event, fired whenever the table is redrawn on the page, at the same point as - * fnDrawCallback. This may be useful for binding events or performing calculations when - * the table is altered at all. - * @name DataTable#draw - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Filter event, fired when the filtering applied to the table (using the build in global - * global filter, or column filters) is altered. - * @name DataTable#filter - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Page change event, fired when the paging of the table is altered. - * @name DataTable#page - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * Sort event, fired when the sorting applied to the table is altered. - * @name DataTable#sort - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ - - /** - * DataTables initialisation complete event, fired when the table is fully drawn, - * including Ajax data loaded, if Ajax data is required. - * @name DataTable#init - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The JSON object request from the server - only - * present if client-side Ajax sourced data is used - */ - - /** - * State save event, fired when the table has changed state a new state save is required. - * This method allows modification of the state saving object prior to actually doing the - * save, including addition or other state properties (for plug-ins) or modification - * of a DataTables core property. - * @name DataTable#stateSaveParams - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The state information to be saved - */ - - /** - * State load event, fired when the table is loading state from the stored data, but - * prior to the settings object being modified by the saved state - allowing modification - * of the saved state is required or loading of state for a plug-in. - * @name DataTable#stateLoadParams - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The saved state information - */ - - /** - * State loaded event, fired when state has been loaded from stored data and the settings - * object has been modified by the loaded data. - * @name DataTable#stateLoaded - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {object} json The saved state information - */ - - /** - * Processing event, fired when DataTables is doing some kind of processing (be it, - * sort, filter or anything else). Can be used to indicate to the end user that - * there is something happening, or that something has finished. - * @name DataTable#processing - * @event - * @param {event} e jQuery event object - * @param {object} oSettings DataTables settings object - * @param {boolean} bShow Flag for if DataTables is doing processing or not - */ - - /** - * Ajax (XHR) event, fired whenever an Ajax request is completed from a request to - * made to the server for new data (note that this trigger is called in fnServerData, - * if you override fnServerData and which to use this event, you need to trigger it in - * you success function). - * @name DataTable#xhr - * @event - * @param {event} e jQuery event object - * @param {object} o DataTables settings object {@link DataTable.models.oSettings} - */ -}(jQuery, window, document, undefined)); diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.min.js deleted file mode 100755 index bbbddb5b0c..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.dataTables.min.js +++ /dev/null @@ -1,153 +0,0 @@ -/* - * File: jquery.dataTables.min.js - * Version: 1.9.0 - * Author: Allan Jardine (www.sprymedia.co.uk) - * Info: www.datatables.net - * - * Copyright 2008-2012 Allan Jardine, all rights reserved. - * - * This source file is free software, under either the GPL v2 license or a - * BSD style license, available at: - * http://datatables.net/license_gpl2 - * http://datatables.net/license_bsd - * - * This source file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details. - */ -(function(i,aa,k,l){var j=function(e){function o(a,b){var c=j.defaults.columns,d=a.aoColumns.length,c=i.extend({},j.models.oColumn,c,{sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,nTh:b?b:k.createElement("th"),sTitle:c.sTitle?c.sTitle:b?b.innerHTML:"",aDataSort:c.aDataSort?c.aDataSort:[d],mDataProp:c.mDataProp?c.oDefaults:d});a.aoColumns.push(c);if(a.aoPreSearchCols[d]===l||null===a.aoPreSearchCols[d])a.aoPreSearchCols[d]=i.extend({},j.models.oSearch);else{c=a.aoPreSearchCols[d]; -if(c.bRegex===l)c.bRegex=!0;if(c.bSmart===l)c.bSmart=!0;if(c.bCaseInsensitive===l)c.bCaseInsensitive=!0}E(a,d,null)}function E(a,b,c){b=a.aoColumns[b];if(c!==l&&null!==c){if(c.sType!==l)b.sType=c.sType,b._bAutoType=!1;i.extend(b,c);n(b,c,"sWidth","sWidthOrig");if(c.iDataSort!==l)b.aDataSort=[c.iDataSort];n(b,c,"aDataSort")}b.fnGetData=V(b.mDataProp);b.fnSetData=sa(b.mDataProp);if(!a.oFeatures.bSort)b.bSortable=!1;if(!b.bSortable||-1==i.inArray("asc",b.asSorting)&&-1==i.inArray("desc",b.asSorting))b.sSortingClass= -a.oClasses.sSortableNone,b.sSortingClassJUI="";else if(b.bSortable||-1==i.inArray("asc",b.asSorting)&&-1==i.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortable,b.sSortingClassJUI=a.oClasses.sSortJUI;else if(-1!=i.inArray("asc",b.asSorting)&&-1==i.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortableAsc,b.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed;else if(-1==i.inArray("asc",b.asSorting)&&-1!=i.inArray("desc",b.asSorting))b.sSortingClass=a.oClasses.sSortableDesc,b.sSortingClassJUI= -a.oClasses.sSortJUIDescAllowed}function r(a){if(!1===a.oFeatures.bAutoWidth)return!1;ba(a);for(var b=0,c=a.aoColumns.length;bm[h])d(a.aoColumns.length+m[h],b[f]);else if("string"===typeof m[h])for(e=0,q=a.aoColumns.length;eb&&a[d]--; -1!=c&&a.splice(c, -1)}function R(a,b,c){var d=a.aoColumns[c];return d.fnRender({iDataRow:b,iDataColumn:c,oSettings:a,aData:a.aoData[b]._aData,mDataProp:d.mDataProp},w(a,b,c,"display"))}function ca(a,b){var c=a.aoData[b],d;if(null===c.nTr){c.nTr=k.createElement("tr");c.nTr._DT_RowIndex=b;if(c._aData.DT_RowId)c.nTr.id=c._aData.DT_RowId;c._aData.DT_RowClass&&i(c.nTr).addClass(c._aData.DT_RowClass);for(var f=0,h=a.aoColumns.length;f=a.fnRecordsDisplay()?0:a.iInitDisplayStart,a.iInitDisplayStart=-1,z(a);if(a.bDeferLoading)a.bDeferLoading=!1,a.iDraw++;else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!va(a))return}else a.iDraw++;if(0!==a.aiDisplay.length){var g=a._iDisplayStart;c=a._iDisplayEnd;if(a.oFeatures.bServerSide)g=0,c=a.aoData.length;for(;g
      ")[0];a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=i('
      ')[0];a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),f,h,g,e,q,m,o,l=0;l
      ")[0];q=d[l+1];if("'"==q||'"'==q){m="";for(o=2;d[l+o]!=q;)m+=d[l+o], -o++;"H"==m?m="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix":"F"==m&&(m="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix");-1!=m.indexOf(".")?(q=m.split("."),e.id=q[0].substr(1,q[0].length-1),e.className=q[1]):"#"==m.charAt(0)?e.id=m.substr(1,m.length-1):e.className=m;l+=o}c.appendChild(e);c=e}else if(">"==g)c=c.parentNode;else if("l"==g&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange)f=xa(a),h=1;else if("f"==g&&a.oFeatures.bFilter)f= -ya(a),h=1;else if("r"==g&&a.oFeatures.bProcessing)f=za(a),h=1;else if("t"==g)f=Aa(a),h=1;else if("i"==g&&a.oFeatures.bInfo)f=Ba(a),h=1;else if("p"==g&&a.oFeatures.bPaginate)f=Ca(a),h=1;else if(0!==j.ext.aoFeatures.length){e=j.ext.aoFeatures;o=0;for(q=e.length;o'):""===c?'':c+' ',d=k.createElement("div");d.className=a.oClasses.sFilter;d.innerHTML="";if(!a.aanFeatures.f)d.id=a.sTableId+"_filter";c=i("input", -d);c.val(b.sSearch.replace('"',"""));c.bind("keyup.DT",function(){for(var c=a.aanFeatures.f,d=0,g=c.length;d=b.length)a.aiDisplay.splice(0,a.aiDisplay.length),a.aiDisplay=a.aiDisplayMaster.slice();else if(a.aiDisplay.length==a.aiDisplayMaster.length|| -f.sSearch.length>b.length||1==c||0!==b.indexOf(f.sSearch)){a.aiDisplay.splice(0,a.aiDisplay.length);ia(a,1);for(b=0;b/g,""):"string"===typeof a?a.replace(/[\r\n]/g," "):null===a?"":a}function ma(a){return a.replace(RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)","g"),"\\$1")}function Ba(a){var b=k.createElement("div");b.className=a.oClasses.sInfo;if(!a.aanFeatures.i)a.aoDrawCallback.push({fn:Ia,sName:"information"}),b.id=a.sTableId+"_info";a.nTable.setAttribute("aria-describedby", -a.sTableId+"_info");return b}function Ia(a){if(a.oFeatures.bInfo&&0!==a.aanFeatures.i.length){var b=a._iDisplayStart+1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),h=a.fnFormatNumber(b),g=a.fnFormatNumber(c),e=a.fnFormatNumber(d),q=a.fnFormatNumber(f);a.oScroll.bInfinite&&(h=a.fnFormatNumber(1));h=0===a.fnRecordsDisplay()&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:0===a.fnRecordsDisplay()?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_", -e)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",h).replace("_END_",g).replace("_TOTAL_",q)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",h).replace("_END_",g).replace("_TOTAL_",q)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;null!==a.oLanguage.fnInfoCallback&&(h=a.oLanguage.fnInfoCallback.call(a.oInstance,a,b,c,d,f,h));a=a.aanFeatures.i;b=0;for(c=a.length;b",c,d,f=a.aLengthMenu;if(2==f.length&&"object"===typeof f[0]&&"object"===typeof f[1])for(c=0,d=f[0].length;c'+f[1][c]+"";else for(c=0,d=f.length;c'+f[c]+"";b+="";f=k.createElement("div");if(!a.aanFeatures.l)f.id=a.sTableId+"_length";f.className=a.oClasses.sLength;f.innerHTML=""; -i('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",!0);i("select",f).bind("change.DT",function(){var b=i(this).val(),f=a.aanFeatures.l;for(c=0,d=f.length;ca._iDisplayStart))a._iDisplayStart=0;if(-1==a._iDisplayLength)a._iDisplayStart=0;y(a)});i("select",f).attr("aria-controls",a.sTableId);return f} -function z(a){a._iDisplayEnd=!1===a.oFeatures.bPaginate?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||-1==a._iDisplayLength?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Ca(a){if(a.oScroll.bInfinite)return null;var b=k.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;j.ext.oPagination[a.sPaginationType].fnInit(a,b,function(a){z(a);y(a)});a.aanFeatures.p||a.aoDrawCallback.push({fn:function(a){j.ext.oPagination[a.sPaginationType].fnUpdate(a, -function(a){z(a);y(a)})},sName:"pagination"});return b}function oa(a,b){var c=a._iDisplayStart;if("number"===typeof b){if(a._iDisplayStart=b*a._iDisplayLength,a._iDisplayStart>a.fnRecordsDisplay())a._iDisplayStart=0}else if("first"==b)a._iDisplayStart=0;else if("previous"==b){if(a._iDisplayStart=0<=a._iDisplayLength?a._iDisplayStart-a._iDisplayLength:0,0>a._iDisplayStart)a._iDisplayStart=0}else if("next"==b)0<=a._iDisplayLength?a._iDisplayStart+a._iDisplayLengthi(a.nTable).height()-a.oScroll.iLoadGap&&a.fnDisplayEnd()=i.browser.version;g=a.nTable.getElementsByTagName("thead");0d.offsetHeight||"scroll"==i(d).css("overflow-y")))a.nTable.style.width= -p(i(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(""!==a.oScroll.sXInner)a.nTable.style.width=p(a.oScroll.sXInner);else if(f==i(d).width()&&i(d).height()f-a.oScroll.iBarWidth)a.nTable.style.width=p(f)}else a.nTable.style.width=p(f);f=i(a.nTable).outerWidth();h=a.nTHead.getElementsByTagName("tr");g=g.getElementsByTagName("tr");N(function(a,b){m=a.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth= -"0";m.borderBottomWidth="0";m.height=0;l=i(a).width();b.style.width=p(l);r.push(l)},g,h);i(g).height(0);null!==a.nTFoot&&(e=j.getElementsByTagName("tr"),j=a.nTFoot.getElementsByTagName("tr"),N(function(a,b){m=a.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;l=i(a).width();b.style.width=p(l);r.push(l)},e,j),i(e).height(0));N(function(a){a.innerHTML="";a.style.width=p(r.shift())},g);null!==a.nTFoot&&N(function(a){a.innerHTML="";a.style.width=p(r.shift())}, -e);if(i(a.nTable).outerWidth()d.offsetHeight||"scroll"==i(d).css("overflow-y")?f+a.oScroll.iBarWidth:f;if(k&&(d.scrollHeight>d.offsetHeight||"scroll"==i(d).css("overflow-y")))a.nTable.style.width=p(e-a.oScroll.iBarWidth);d.style.width=p(e);b.parentNode.style.width=p(e);if(null!==a.nTFoot)n.parentNode.style.width=p(e);""===a.oScroll.sX?F(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width."): -""!==a.oScroll.sXInner&&F(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else if(d.style.width=p("100%"),b.parentNode.style.width=p("100%"),null!==a.nTFoot)n.parentNode.style.width=p("100%");if(""===a.oScroll.sY&&k)d.style.height=p(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(""!==a.oScroll.sY&&a.oScroll.bCollapse&&(d.style.height=p(a.oScroll.sY),k=""!==a.oScroll.sX&&a.nTable.offsetWidth> -d.offsetWidth?a.oScroll.iBarWidth:0,a.nTable.offsetHeighttd",b));g=O(a, -h);for(h=d=0;hc)return null;if(null===a.aoData[c].nTr){var d=k.createElement("td");d.innerHTML=w(a,c,b,"");return d}return L(a,c)[b]}function Na(a,b){for(var c=-1,d=-1,f=0;f/g,"");if(h.length>c)c=h.length,d=f}return d}function p(a){if(null===a)return"0px";if("number"==typeof a)return 0>a?"0px":a+"px";var b=a.charCodeAt(a.length-1);return 48>b||57=g)for(b=0;be&&e++}}}function pa(a){if(a.oFeatures.bStateSave&&!a.bDestroying){var b,c;b=a.oScroll.bInfinite;var d={iCreate:(new Date).getTime(),iStart:b?0:a._iDisplayStart, -iEnd:b?a._iDisplayLength:a._iDisplayEnd,iLength:a._iDisplayLength,aaSorting:i.extend(!0,[],a.aaSorting),oSearch:i.extend(!0,{},a.oPreviousSearch),aoSearchCols:i.extend(!0,[],a.aoPreSearchCols),abVisCols:[]};for(b=0,c=a.aoColumns.length;b=d.aiDisplay.length&&(d._iDisplayStart-=d._iDisplayLength,0>d._iDisplayStart))d._iDisplayStart=0;if(c===l||c)z(d),y(d);return e};this.fnDestroy=function(a){var b=u(this[j.ext.iApiIndex]),c=b.nTableWrapper.parentNode,d=b.nTBody,f,e,a=a===l?!1:!0;b.bDestroying=!0;for(f=0,e=b.aoDestroyCallback.length;ftr>td."+b.oClasses.sRowEmpty,b.nTable).parent().remove();b.nTable!=b.nTHead.parentNode&&(i(b.nTable).children("thead").remove(),b.nTable.appendChild(b.nTHead));b.nTFoot&&b.nTable!=b.nTFoot.parentNode&&(i(b.nTable).children("tfoot").remove(),b.nTable.appendChild(b.nTFoot));b.nTable.parentNode.removeChild(b.nTable);i(b.nTableWrapper).remove();b.aaSorting= -[];b.aaSortingFixed=[];Q(b);i(S(b)).removeClass(b.asStripeClasses.join(" "));i("th, td",b.nTHead).removeClass([b.oClasses.sSortable,b.oClasses.sSortableAsc,b.oClasses.sSortableDesc,b.oClasses.sSortableNone].join(" "));b.bJUI&&(i("th span."+b.oClasses.sSortIcon+", td span."+b.oClasses.sSortIcon,b.nTHead).remove(),i("th, td",b.nTHead).each(function(){var a=i("div."+b.oClasses.sSortJUIWrapper,this),c=a.contents();i(this).append(c);a.remove()}));!a&&b.nTableReinsertBefore?c.insertBefore(b.nTable,b.nTableReinsertBefore): -a||c.appendChild(b.nTable);for(f=0,e=b.aoData.length;f=v(d);if(!m)for(f=a;ft<"F"ip>'}else i.extend(g.oClasses,j.ext.oStdClasses);i(this).addClass(g.oClasses.sTable);if(""!==g.oScroll.sX||""!==g.oScroll.sY)g.oScroll.iBarWidth=Oa();if(g.iInitDisplayStart===l)g.iInitDisplayStart=e.iDisplayStart,g._iDisplayStart=e.iDisplayStart;if(e.bStateSave)g.oFeatures.bStateSave=!0,Qa(g,e),A(g,"aoDrawCallback",pa,"state_save");if(null!==e.iDeferLoading)g.bDeferLoading=!0,g._iRecordsTotal=e.iDeferLoading, -g._iRecordsDisplay=e.iDeferLoading;null!==e.aaData&&(h=!0);""!==e.oLanguage.sUrl?(g.oLanguage.sUrl=e.oLanguage.sUrl,i.getJSON(g.oLanguage.sUrl,null,function(a){na(a);i.extend(!0,g.oLanguage,e.oLanguage,a);$(g)}),f=!0):i.extend(!0,g.oLanguage,e.oLanguage);c=!1;d=i(this).children("tbody").children("tr");for(a=0,b=g.asStripeClasses.length;a=g.aoColumns.length&&(g.aaSorting[a][0]=0);var r=g.aoColumns[g.aaSorting[a][0]];g.aaSorting[a][2]===l&&(g.aaSorting[a][2]=0);e.aaSorting===l&&g.saved_aaSorting===l&&(g.aaSorting[a][1]=r.asSorting[0]);for(c=0,d=r.asSorting.length;c< -d;c++)if(g.aaSorting[a][1]==r.asSorting[c]){g.aaSorting[a][2]=c;break}}Q(g);a=i(this).children("thead");0===a.length&&(a=[k.createElement("thead")],this.appendChild(a[0]));g.nTHead=a[0];a=i(this).children("tbody");0===a.length&&(a=[k.createElement("tbody")],this.appendChild(a[0]));g.nTBody=a[0];g.nTBody.setAttribute("role","alert");g.nTBody.setAttribute("aria-live","polite");g.nTBody.setAttribute("aria-relevant","all");a=i(this).children("tfoot");if(0=parseInt(k,10)},iApiIndex:0,ofnSearch:{},oApi:{}, -oStdClasses:{},oJUIClasses:{},oPagination:{},oSort:{},sVersion:j.version,sErrMode:"alert",_oExternConfig:{iNextUnique:0}};j.models.oSearch={bCaseInsensitive:!0,sSearch:"",bRegex:!1,bSmart:!0};j.models.oRow={nTr:null,_aData:[],_aSortData:[],_anHidden:[],_sRowStripe:""};j.models.oColumn={aDataSort:null,asSorting:null,bSearchable:null,bSortable:null,bUseRendered:null,bVisible:null,_bAutoType:!0,fnCreatedCell:null,fnGetData:null,fnRender:null,fnSetData:null,mDataProp:null,nTh:null,nTf:null,sClass:null, -sContentPadding:null,sDefaultContent:null,sName:null,sSortDataType:"std",sSortingClass:null,sSortingClassJUI:null,sTitle:null,sType:null,sWidth:null,sWidthOrig:null};j.defaults={aaData:null,aaSorting:[[0,"asc"]],aaSortingFixed:null,aLengthMenu:[10,25,50,100],aoColumns:null,aoColumnDefs:null,aoSearchCols:[],asStripeClasses:["odd","even"],bAutoWidth:!0,bDeferRender:!1,bDestroy:!1,bFilter:!0,bInfo:!0,bJQueryUI:!1,bLengthChange:!0,bPaginate:!0,bProcessing:!1,bRetrieve:!1,bScrollAutoCss:!0,bScrollCollapse:!1, -bScrollInfinite:!1,bServerSide:!1,bSort:!0,bSortCellsTop:!1,bSortClasses:!0,bStateSave:!1,fnCookieCallback:null,fnCreatedRow:null,fnDrawCallback:null,fnFooterCallback:null,fnFormatNumber:function(e){if(1E3>e)return e;for(var i=e+"",e=i.split(""),j="",i=i.length,l=0;l'+k.sPrevious+''+k.sNext+"":'';i(j).append(k);var t=i("a",j),k=t[0],t=t[1];e.oApi._fnBindAction(k,{action:"previous"},s);e.oApi._fnBindAction(t,{action:"next"},s);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_previous",t.id=e.sTableId+"_next",k.setAttribute("aria-controls",e.sTableId),t.setAttribute("aria-controls",e.sTableId)},fnUpdate:function(e){if(e.aanFeatures.p)for(var i=e.oClasses,j=e.aanFeatures.p,l=0, -k=j.length;l'+k.sFirst+ -''+k.sPrevious+''+k.sNext+''+k.sLast+"");var v=i("a",j),k=v[0],s=v[1],B=v[2],v=v[3];e.oApi._fnBindAction(k,{action:"first"},t);e.oApi._fnBindAction(s,{action:"previous"},t);e.oApi._fnBindAction(B,{action:"next"},t);e.oApi._fnBindAction(v,{action:"last"}, -t);if(!e.aanFeatures.p)j.id=e.sTableId+"_paginate",k.id=e.sTableId+"_first",s.id=e.sTableId+"_previous",B.id=e.sTableId+"_next",v.id=e.sTableId+"_last"},fnUpdate:function(e,l){if(e.aanFeatures.p){var k=j.ext.oPagination.iFullNumbersShowPages,r=Math.floor(k/2),s=Math.ceil(e.fnRecordsDisplay()/e._iDisplayLength),t=Math.ceil(e._iDisplayStart/e._iDisplayLength)+1,v="",B,D=e.oClasses,x,I=e.aanFeatures.p,G=function(i){e.oApi._fnBindAction(this,{page:i+B-1},function(i){e.oApi._fnPageChange(e,i.data.page); -l(e);i.preventDefault()})};s=s-r?(B=s-k+1,r=s):(B=t-Math.ceil(k/2)+1,r=B+k-1);for(k=B;k<=r;k++)v+=t!==k?''+e.fnFormatNumber(k)+"":''+e.fnFormatNumber(k)+"";for(k=0,r=I.length;ki?1:0},"string-desc":function(e,i){return ei?-1:0},"html-pre":function(e){return e.replace(/<.*?>/g,"").toLowerCase()}, -"html-asc":function(e,i){return ei?1:0},"html-desc":function(e,i){return ei?-1:0},"date-pre":function(e){e=Date.parse(e);if(isNaN(e)||""===e)e=Date.parse("01/01/1970 00:00:00");return e},"date-asc":function(e,i){return e-i},"date-desc":function(e,i){return i-e},"numeric-pre":function(e){return"-"==e||""===e?0:1*e},"numeric-asc":function(e,i){return e-i},"numeric-desc":function(e,i){return i-e}});i.extend(j.ext.aTypes,[function(e){if("number"===typeof e)return"numeric";if("string"!== -typeof e)return null;var i,j=!1;i=e.charAt(0);if(-1=="0123456789-".indexOf(i))return null;for(var k=1;k")?"html":null}]);i.fn.DataTable=j;i.fn.dataTable=j;i.fn.dataTableSettings=j.settings;i.fn.dataTableExt= -j.ext})(jQuery,window,document,void 0); diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.miniColors.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.miniColors.min.js deleted file mode 100755 index 25dcfa0e0b..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.miniColors.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/* - * jQuery miniColors: A small color selector - * - * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/) - * - * Dual licensed under the MIT or GPL Version 2 licenses - * -*/ -if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val());if(!color)color='ffffff';var hsb=hex2hsb(color);var trigger=$('');trigger.insertAfter(input);input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase','uppercase').data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase));if(o.readonly)input.prop('readonly',true);if(o.disabled)disable(input);trigger.bind('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#');show(input)});input.bind('focus.miniColors',function(event){if(input.val()==='')input.val('#');show(input)});input.bind('blur.miniColors',function(event){var hex=expandHex(input.val());input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'')});input.bind('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.bind('keyup.miniColors',function(event){setColorFromInput(input)});input.bind('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').unbind('.miniColors');$(document).unbind('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').css('opacity',1)};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').css('opacity',0.5)};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('
      ');selector.append('
      ').append('
      ').css({top:input.is(':visible')?input.offset().top+input.outerHeight():input.data('trigger').offset().top+input.data('trigger').outerHeight(),left:input.is(':visible')?input.offset().left:input.data('trigger').offset().left,display:'none'}).addClass(input.attr('class'));var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition.y+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);selector.fadeIn(100);selector.bind('selectstart',function(){return false});$(document).bind('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);if($(event.target).parents().andSelf().hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if($(event.target).parents().andSelf().hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if($(event.target).parents().andSelf().hasClass('miniColors-selector')){event.preventDefault();return}if($(event.target).parents().andSelf().hasClass('miniColors'))return;hide(input)});$(document).bind('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).bind('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event)}})};var hide=function(input){if(!input)input='.miniColors';$(input).each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){$(this).remove()})});$(document).unbind('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-5;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-5;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position={y:event.pageY};if(event.originalEvent.changedTouches){position.y=event.originalEvent.changedTouches[0].pageY}position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-1;if(position.y<=-1)position.y=-1;if(position.y>=149)position.y=149;input.data('huePosition',position);huePicker.css('top',position.y).show();var h=Math.round((150-position.y-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb);if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase')));input.data('trigger').css('backgroundColor','#'+hex);if(input.data('selector'))input.data('selector').find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));if(input.data('change')){if(hex===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,hsb2rgb(hsb));input.data('lastChange',hex)}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val()));var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var currentHSB=input.data('hsb');if(hsb.h===currentHSB.h&&hsb.s===currentHSB.s&&hsb.b===currentHSB.b)return true;var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition.y+'px');input.data('huePosition',huePosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='lowercase')return string.toLowerCase();if(letterCase==='uppercase')return string.toUpperCase();return string};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return{y:y-1}};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data);setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery); \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.multiselect.min.js b/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.multiselect.min.js deleted file mode 100755 index 7f5ab96615..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery.multiselect.min.js +++ /dev/null @@ -1,20 +0,0 @@ -/* - * jQuery MultiSelect UI Widget 1.12 - * Copyright (c) 2011 Eric Hynds - * - * http://www.erichynds.com/jquery/jquery-ui-multiselect-widget/ - * - * Depends: - * - jQuery 1.4.2+ - * - jQuery UI 1.8 widget factory - * - * Optional: - * - jQuery UI effects - * - jQuery UI position utility - * - * Dual licensed under the MIT and GPL licenses: - * http://www.opensource.org/licenses/mit-license.php - * http://www.gnu.org/licenses/gpl.html - * - */ -(function(d){var j=0;d.widget("ech.multiselect",{options:{header:!0,height:175,minWidth:225,classes:"",checkAllText:"Check all",uncheckAllText:"Uncheck all",noneSelectedText:"Select options",selectedText:"# selected",selectedList:0,show:"",hide:"",autoOpen:!1,multiple:!0,position:{}},_create:function(){var a=this.element.hide(),b=this.options;this.speed=d.fx.speeds._default;this._isOpen=!1;a=(this.button=d('')).addClass("ui-multiselect ui-widget ui-state-default ui-corner-all").addClass(b.classes).attr({title:a.attr("title"), "aria-haspopup":!0,tabIndex:a.attr("tabIndex")}).insertAfter(a);(this.buttonlabel=d("")).html(b.noneSelectedText).appendTo(a);var a=(this.menu=d("
      ")).addClass("ui-multiselect-menu ui-widget ui-widget-content ui-corner-all").addClass(b.classes).appendTo(document.body),c=(this.header=d("
      ")).addClass("ui-widget-header ui-corner-all ui-multiselect-header ui-helper-clearfix").appendTo(a);(this.headerLinkContainer=d("
      "+(i[0]>0&&G==i[1]-1?'
      ':""):"");O+=y}w+=O}w+=e+(d.browser.msie&&parseInt(d.browser.version,10)<7&&!a.inline?'': -"");a._keyEvent=false;return w},_generateMonthYearHeader:function(a,b,c,e,f,h,i,g){var j=this._get(a,"changeMonth"),l=this._get(a,"changeYear"),u=this._get(a,"showMonthAfterYear"),k='
      ',o="";if(h||!j)o+=''+i[b]+"";else{i=e&&e.getFullYear()==c;var m=f&&f.getFullYear()==c;o+='"}u||(k+=o+(h||!(j&&l)?" ":""));if(!a.yearshtml){a.yearshtml="";if(h||!l)k+=''+c+"";else{g=this._get(a,"yearRange").split(":");var s=(new Date).getFullYear();i=function(q){q=q.match(/c[+-].*/)?c+parseInt(q.substring(1),10):q.match(/[+-].*/)?s+parseInt(q,10):parseInt(q,10);return isNaN(q)?s:q};b=i(g[0]);g=Math.max(b,i(g[1]||""));b=e?Math.max(b, -e.getFullYear()):b;g=f?Math.min(g,f.getFullYear()):g;for(a.yearshtml+='";k+=a.yearshtml;a.yearshtml=null}}k+=this._get(a,"yearSuffix");if(u)k+=(h||!(j&&l)?" ":"")+o;k+="
      ";return k},_adjustInstDate:function(a,b,c){var e=a.drawYear+(c=="Y"?b:0),f=a.drawMonth+ -(c=="M"?b:0);b=Math.min(a.selectedDay,this._getDaysInMonth(e,f))+(c=="D"?b:0);e=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(e,f,b)));a.selectedDay=e.getDate();a.drawMonth=a.selectedMonth=e.getMonth();a.drawYear=a.selectedYear=e.getFullYear();if(c=="M"||c=="Y")this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");b=c&&ba?a:b},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");if(b)b.apply(a.input? -a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return a==null?[1,1]:typeof a=="number"?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a,b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,e){var f=this._getNumberOfMonths(a);c=this._daylightSavingAdjust(new Date(c, -e+(b<0?b:f[0]*f[1]),1));b<0&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min");a=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!a||b.getTime()<=a.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff");b=typeof b!="string"?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a, -"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,e){if(!b){a.currentDay=a.selectedDay;a.currentMonth=a.selectedMonth;a.currentYear=a.selectedYear}b=b?typeof b=="object"?b:this._daylightSavingAdjust(new Date(e,c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});d.fn.datepicker=function(a){if(!this.length)return this; -if(!d.datepicker.initialized){d(document).mousedown(d.datepicker._checkExternalClick).find("body").append(d.datepicker.dpDiv);d.datepicker.initialized=true}var b=Array.prototype.slice.call(arguments,1);if(typeof a=="string"&&(a=="isDisabled"||a=="getDate"||a=="widget"))return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));if(a=="option"&&arguments.length==2&&typeof arguments[1]=="string")return d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this[0]].concat(b));return this.each(function(){typeof a== -"string"?d.datepicker["_"+a+"Datepicker"].apply(d.datepicker,[this].concat(b)):d.datepicker._attachDatepicker(this,a)})};d.datepicker=new M;d.datepicker.initialized=false;d.datepicker.uuid=(new Date).getTime();d.datepicker.version="1.8.16";window["DP_jQuery_"+B]=d})(jQuery); -;/* - * jQuery UI Progressbar 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Progressbar - * - * Depends: - * jquery.ui.core.js - * jquery.ui.widget.js - */ -(function(b,d){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
      ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); -this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(a){if(a===d)return this._value();this._setOption("value",a);return this},_setOption:function(a,c){if(a==="value"){this.options.value=c;this._refreshValue();this._value()===this.options.max&&this._trigger("complete")}b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;if(typeof a!=="number")a=0;return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* -this._value()/this.options.max},_refreshValue:function(){var a=this.value(),c=this._percentage();if(this.oldValue!==a){this.oldValue=a;this._trigger("change")}this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(c.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.16"})})(jQuery); -;/* - * jQuery UI Effects 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/ - */ -jQuery.effects||function(f,j){function m(c){var a;if(c&&c.constructor==Array&&c.length==3)return c;if(a=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return[parseInt(a[1],10),parseInt(a[2],10),parseInt(a[3],10)];if(a=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return[parseFloat(a[1])*2.55,parseFloat(a[2])*2.55,parseFloat(a[3])*2.55];if(a=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return[parseInt(a[1], -16),parseInt(a[2],16),parseInt(a[3],16)];if(a=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return[parseInt(a[1]+a[1],16),parseInt(a[2]+a[2],16),parseInt(a[3]+a[3],16)];if(/rgba\(0, 0, 0, 0\)/.exec(c))return n.transparent;return n[f.trim(c).toLowerCase()]}function s(c,a){var b;do{b=f.curCSS(c,a);if(b!=""&&b!="transparent"||f.nodeName(c,"body"))break;a="backgroundColor"}while(c=c.parentNode);return m(b)}function o(){var c=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle, -a={},b,d;if(c&&c.length&&c[0]&&c[c[0]])for(var e=c.length;e--;){b=c[e];if(typeof c[b]=="string"){d=b.replace(/\-(\w)/g,function(g,h){return h.toUpperCase()});a[d]=c[b]}}else for(b in c)if(typeof c[b]==="string")a[b]=c[b];return a}function p(c){var a,b;for(a in c){b=c[a];if(b==null||f.isFunction(b)||a in t||/scrollbar/.test(a)||!/color/i.test(a)&&isNaN(parseFloat(b)))delete c[a]}return c}function u(c,a){var b={_:0},d;for(d in a)if(c[d]!=a[d])b[d]=a[d];return b}function k(c,a,b,d){if(typeof c=="object"){d= -a;b=null;a=c;c=a.effect}if(f.isFunction(a)){d=a;b=null;a={}}if(typeof a=="number"||f.fx.speeds[a]){d=b;b=a;a={}}if(f.isFunction(b)){d=b;b=null}a=a||{};b=b||a.duration;b=f.fx.off?0:typeof b=="number"?b:b in f.fx.speeds?f.fx.speeds[b]:f.fx.speeds._default;d=d||a.complete;return[c,a,b,d]}function l(c){if(!c||typeof c==="number"||f.fx.speeds[c])return true;if(typeof c==="string"&&!f.effects[c])return true;return false}f.effects={};f.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor", -"borderTopColor","borderColor","color","outlineColor"],function(c,a){f.fx.step[a]=function(b){if(!b.colorInit){b.start=s(b.elem,a);b.end=m(b.end);b.colorInit=true}b.elem.style[a]="rgb("+Math.max(Math.min(parseInt(b.pos*(b.end[0]-b.start[0])+b.start[0],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[1]-b.start[1])+b.start[1],10),255),0)+","+Math.max(Math.min(parseInt(b.pos*(b.end[2]-b.start[2])+b.start[2],10),255),0)+")"}});var n={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0, -0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211, -211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},q=["add","remove","toggle"],t={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};f.effects.animateClass=function(c,a,b, -d){if(f.isFunction(b)){d=b;b=null}return this.queue(function(){var e=f(this),g=e.attr("style")||" ",h=p(o.call(this)),r,v=e.attr("class");f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});r=p(o.call(this));e.attr("class",v);e.animate(u(h,r),{queue:false,duration:a,easing:b,complete:function(){f.each(q,function(w,i){c[i]&&e[i+"Class"](c[i])});if(typeof e.attr("style")=="object"){e.attr("style").cssText="";e.attr("style").cssText=g}else e.attr("style",g);d&&d.apply(this,arguments);f.dequeue(this)}})})}; -f.fn.extend({_addClass:f.fn.addClass,addClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{add:c},a,b,d]):this._addClass(c)},_removeClass:f.fn.removeClass,removeClass:function(c,a,b,d){return a?f.effects.animateClass.apply(this,[{remove:c},a,b,d]):this._removeClass(c)},_toggleClass:f.fn.toggleClass,toggleClass:function(c,a,b,d,e){return typeof a=="boolean"||a===j?b?f.effects.animateClass.apply(this,[a?{add:c}:{remove:c},b,d,e]):this._toggleClass(c,a):f.effects.animateClass.apply(this, -[{toggle:c},a,b,d])},switchClass:function(c,a,b,d,e){return f.effects.animateClass.apply(this,[{add:a,remove:c},b,d,e])}});f.extend(f.effects,{version:"1.8.16",save:function(c,a){for(var b=0;b
      ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}), -d=document.activeElement;c.wrap(b);if(c[0]===d||f.contains(c[0],d))f(d).focus();b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(e,g){a[g]=c.css(g);if(isNaN(parseInt(a[g],10)))a[g]="auto"});c.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})}return b.css(a).show()},removeWrapper:function(c){var a,b=document.activeElement; -if(c.parent().is(".ui-effects-wrapper")){a=c.parent().replaceWith(c);if(c[0]===b||f.contains(c[0],b))f(b).focus();return a}return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=k.apply(this,arguments),b={options:a[1],duration:a[2],callback:a[3]};a=b.options.mode;var d=f.effects[c];if(f.fx.off||!d)return a?this[a](b.duration,b.callback):this.each(function(){b.callback&&b.callback.call(this)}); -return d.call(this,b)},_show:f.fn.show,show:function(c){if(l(c))return this._show.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(l(c))return this._hide.apply(this,arguments);else{var a=k.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(l(c)||typeof c==="boolean"||f.isFunction(c))return this.__toggle.apply(this,arguments);else{var a=k.apply(this, -arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c,a,b,d,e){if((a/=e/2)<1)return d/ -2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+b},easeInQuint:function(c,a,b, -d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2,10*(a/e-1))+b},easeOutExpo:function(c, -a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)*a)+1)+b},easeInElastic:function(c,a,b, -d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h
      ").css({position:"absolute",visibility:"visible",left:-f*(h/d),top:-e*(i/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:h/d,height:i/c,left:g.left+f*(h/d)+(a.options.mode=="show"?(f-Math.floor(d/2))*(h/d):0),top:g.top+e*(i/c)+(a.options.mode=="show"?(e-Math.floor(c/2))*(i/c):0),opacity:a.options.mode=="show"?0:1}).animate({left:g.left+f*(h/d)+(a.options.mode=="show"?0:(f-Math.floor(d/2))*(h/d)),top:g.top+ -e*(i/c)+(a.options.mode=="show"?0:(e-Math.floor(c/2))*(i/c)),opacity:a.options.mode=="show"?1:0},a.duration||500);setTimeout(function(){a.options.mode=="show"?b.css({visibility:"visible"}):b.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(b[0]);b.dequeue();j("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); -;/* - * jQuery UI Effects Fade 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fade - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:false,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Fold 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Fold - * - * Depends: - * jquery.effects.core.js - */ -(function(c){c.effects.fold=function(a){return this.queue(function(){var b=c(this),j=["position","top","bottom","left","right"],d=c.effects.setMode(b,a.options.mode||"hide"),g=a.options.size||15,h=!!a.options.horizFirst,k=a.duration?a.duration/2:c.fx.speeds._default/2;c.effects.save(b,j);b.show();var e=c.effects.createWrapper(b).css({overflow:"hidden"}),f=d=="show"!=h,l=f?["width","height"]:["height","width"];f=f?[e.width(),e.height()]:[e.height(),e.width()];var i=/([0-9]+)%/.exec(g);if(i)g=parseInt(i[1], -10)/100*f[d=="hide"?0:1];if(d=="show")e.css(h?{height:0,width:g}:{height:g,width:0});h={};i={};h[l[0]]=d=="show"?f[0]:g;i[l[1]]=d=="show"?f[1]:0;e.animate(h,k,a.options.easing).animate(i,k,a.options.easing,function(){d=="hide"&&b.hide();c.effects.restore(b,j);c.effects.removeWrapper(b);a.callback&&a.callback.apply(b[0],arguments);b.dequeue()})})}})(jQuery); -;/* - * jQuery UI Effects Highlight 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Highlight - * - * Depends: - * jquery.effects.core.js - */ -(function(b){b.effects.highlight=function(c){return this.queue(function(){var a=b(this),e=["backgroundImage","backgroundColor","opacity"],d=b.effects.setMode(a,c.options.mode||"show"),f={backgroundColor:a.css("backgroundColor")};if(d=="hide")f.opacity=0;b.effects.save(a,e);a.show().css({backgroundImage:"none",backgroundColor:c.options.color||"#ffff99"}).animate(f,{queue:false,duration:c.duration,easing:c.options.easing,complete:function(){d=="hide"&&a.hide();b.effects.restore(a,e);d=="show"&&!b.support.opacity&& -this.style.removeAttribute("filter");c.callback&&c.callback.apply(this,arguments);a.dequeue()}})})}})(jQuery); -;/* - * jQuery UI Effects Pulsate 1.8.16 - * - * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) - * Dual licensed under the MIT or GPL Version 2 licenses. - * http://jquery.org/license - * - * http://docs.jquery.com/UI/Effects/Pulsate - * - * Depends: - * jquery.effects.core.js - */ -(function(d){d.effects.pulsate=function(a){return this.queue(function(){var b=d(this),c=d.effects.setMode(b,a.options.mode||"show");times=(a.options.times||5)*2-1;duration=a.duration?a.duration/2:d.fx.speeds._default/2;isVisible=b.is(":visible");animateTo=0;if(!isVisible){b.css("opacity",0).show();animateTo=1}if(c=="hide"&&isVisible||c=="show"&&!isVisible)times--;for(c=0;c
      ').appendTo(document.body).addClass(a.options.className).css({top:d.top,left:d.left,height:b.innerHeight(),width:b.innerWidth(),position:"absolute"}).animate(c,a.duration,a.options.easing,function(){f.remove();a.callback&&a.callback.apply(b[0],arguments); -b.dequeue()})})}})(jQuery); -; \ No newline at end of file diff --git a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery/jQRangeSlider-5.1/demo/sliderDemo.js b/src/lib/biojs-1.0/src/main/resources/dependencies/jquery/jQRangeSlider-5.1/demo/sliderDemo.js deleted file mode 100755 index f0e7df7037..0000000000 --- a/src/lib/biojs-1.0/src/main/resources/dependencies/jquery/jQRangeSlider-5.1/demo/sliderDemo.js +++ /dev/null @@ -1,347 +0,0 @@ - -(function($, undefined){ - "use strict"; - - $.widget("ui.sliderDemo", { - options:{ - }, - - _title: "Float values", - _name: "rangeSlider", - - _create: function(){ - this.element.addClass("ui-sliderDemo"); - - this._elements = {}; - this._createTitle(); - this._createZones(); - this._createOptions(); - this._createSlider(); - this._createLog(); - this._createCode(); - }, - - destroy: function(){ - this.element.empty(); - }, - - _setOption: function(name, value){ - this._elements.slider[this._name]("option", name, value); - }, - - _getOption: function(name){ - return this._elements.slider[this._name]("option", name); - }, - - _easyOptionChange: function(e){ - var target = $(e.target), - value = target.val(), - name = target.attr("name"); - - if (value === "false"){ - value = false - } else if (value === "null"){ - value = null - } else if (!isNaN(parseFloat(value)) && parseFloat(value).toString() == value){ - value = parseFloat(value) - } - - this._setOption(name, value); - }, - - _createZones: function(){ - var wrapper = $("
      ").appendTo(this.element), - inputZone = $("
      ").appendTo(wrapper), - optionsZone = $("
      ").appendTo(this.element); - - this._elements.sliderZone = $("
      ").appendTo(inputZone); - this._elements.optionsZone = $("").appendTo(optionsZone); - this._elements.logZone = $("
      ").appendTo(wrapper); - }, - - _createTitle: function(){ - var title = $("

      "); - title.text(this._title); - - this.element.append(title); - }, - - _createInputs: function(){ - var inputs = $("
      "), - minInputContainer = $("
      "), - maxInputContainer = $("
      "); - - this._elements.minInput = $("").appendTo(minInputContainer); - this._elements.maxInput = $("").appendTo(maxInputContainer); - - inputs.append("
      min
      ") - .append(minInputContainer) - .append("
      max
      ") - .append(maxInputContainer) - .appendTo(this._elements.sliderZone); - }, - - _createSlider: function(){ - var slider = $("
      ").appendTo(this._elements.sliderZone); - slider[this._name](); - - this._elements.slider = slider; - }, - - _format: function(value){ - return value; - }, - - _createOptions: function(){ - this._elements.options = $("
      ").appendTo(this._elements.optionsZone); - - this._createBoundsOptions(); - this._createRangeOptions(); - this._createStepOption(); - this._createWheelModeOption(); - this._createWheelSpeedOption(); - this._createArrowsOption(); - this._createLabelsOption(); - }, - - _createBoundsOptions: function(){ - this._createDT("Bounds"); - - var minSelect = this._createSelect("min", "Bound"), - maxSelect = this._createSelect("max", "Bound"); - - this._addOption(minSelect, 0); - this._addOption(minSelect, 10); - this._addOption(minSelect, 20); - - this._addOption(maxSelect, 100); - this._addOption(maxSelect, 90); - this._addOption(maxSelect, 80); - - minSelect.bind("change", "min", $.proxy(this._changeBound, this)); - maxSelect.bind("change", "max", $.proxy(this._changeBound, this)); - }, - - _changeBound: function(event, ui){ - var value = $(event.target).val(), - bounds = this._getOption("bounds"); - - bounds[event.data] = parseFloat(value); - this._setOption("bounds", bounds); - }, - - _createRangeOptions: function(){ - this._createDT("Range limit"); - - var minSelect = this._createSelect("min", "RangeLimit"), - maxSelect = this._createSelect("max", "RangeLimit"); - - this._fillMinSelect(minSelect); - this._fillMaxSelect(maxSelect); - - minSelect.bind("change", $.proxy(this._minSelectChange, this)); - maxSelect.bind("change", $.proxy(this._maxSelectChange, this)); - }, - - _createStepOption: function(){ - this._createDT("Step"); - - var select = $("").attr("name", name + suffix); - - this._elements.options.append($("
      ") - .append(name + ":") - .append(select)); - - return select; - }, - - _fillMinSelect: function(select){ - this._addOption(select, "false"); - this._addOption(select, 10); - this._addOption(select, 20); - this._addOption(select, 30); - this._addOption(select, 40); - }, - - _fillMaxSelect: function(select){ - this._addOption(select, "false"); - this._addOption(select, 50); - this._addOption(select, 60); - this._addOption(select, 70); - this._addOption(select, 80); - }, - - _addOption: function(select, text, value){ - var value, - option = $("