├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── css ├── images │ ├── animated-overlay.gif │ ├── ui-anim_basic_16x16.gif │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ ├── ui-bg_flat_75_ffffff_40x100.png │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ ├── ui-bg_glass_65_ffffff_1x400.png │ ├── ui-bg_glass_75_dadada_1x400.png │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ ├── ui-bg_glass_95_fef1ec_1x400.png │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ ├── ui-icons_222222_256x240.png │ ├── ui-icons_2e83ff_256x240.png │ ├── ui-icons_454545_256x240.png │ ├── ui-icons_888888_256x240.png │ └── ui-icons_cd0a0a_256x240.png ├── jquery-ui.css ├── jquery.fancybox │ ├── blank.gif │ ├── fancybox_loading.gif │ ├── fancybox_overlay.png │ ├── fancybox_sprite.png │ ├── helpers │ │ └── jquery.fancybox-thumbs.css │ └── jquery.fancybox.css └── screen.css ├── docker-compose.yml ├── document-properties-deactivated.png ├── help.html ├── img ├── SZTAKI_logo_2012_english_RG.png ├── SZTAKI_logo_2012_small_RGB.png ├── arrow-down.png ├── arrow-up-3.png ├── cross.png ├── default-rdf-type-group-32.png ├── default-rdf-type-noendpoint-32.png ├── default-rdf-type-person-32.png ├── default-rdf-type-thing-32.png ├── default-rdf-type-thing-empty-32.png ├── default-rdf-type-work-32.png ├── document-properties-deactivated.png ├── document-properties.png ├── edit-add.png ├── edit-delete.png ├── edit-delete2.png ├── edit-hide.png ├── favicon.png ├── help-about-2-deactivated.png ├── help-about-2-half.png ├── help-about-2.png ├── readme.txt ├── system-help-3.png ├── tileable-metal-texture-1.jpg ├── tileable-metal-texture-1_v2.png └── tileable-metal-texture-1mod.jpg ├── index.html └── js ├── 1.4.0 ├── jquery.jsPlumb-1.4.0-RC1.js ├── jsPlumb-1.4.0-RC1.js ├── jsPlumb-1.4.0-tests.js ├── jsPlumb-anchors-1.4.0-RC1.js ├── jsPlumb-apidoc-1.4.0-RC1.js ├── jsPlumb-connection-1.4.0-RC1.js ├── jsPlumb-connector-editors-1.4.0-RC1.js ├── jsPlumb-connectors-flowchart-1.4.0-RC1.js ├── jsPlumb-connectors-statemachine-1.4.0-RC1.js ├── jsPlumb-defaults-1.4.0-RC1.js ├── jsPlumb-dom-adapter-1.4.0-RC1.js ├── jsPlumb-drag-1.4.0-RC1.js ├── jsPlumb-endpoint-1.4.0-RC1.js ├── jsPlumb-overlays-guidelines-1.4.0-RC1.js ├── jsPlumb-renderers-canvas-1.4.0-RC1.js ├── jsPlumb-renderers-svg-1.4.0-RC1.js ├── jsPlumb-renderers-vml-1.4.0-RC1.js ├── jsPlumb-util-1.4.0-RC1.js ├── mootools.jsPlumb-1.4.0-RC1.js └── yui.jsPlumb-1.4.0-RC1.js ├── jquery-1.9.0-min.js ├── jquery-ui.min.js ├── jquery.fancybox-thumbs.js ├── jquery.fancybox.pack.js ├── jquery.getimagedata.min.js ├── jquery.json-2.4.min.js ├── jquery.jsonp.js ├── jquery.mousewheel.js ├── jquery.ui.touch-punch.min.js ├── jsBezier-0.6-min.js ├── jsPlumb ├── classList.js ├── jquery.jsPlumb-1.6.0-min.js ├── jquery.jsPlumb-1.6.2-min.js ├── jsBezier-0.6-min.js └── src │ ├── anchors.js │ ├── connection.js │ ├── connector-editors.js │ ├── connectors-bezier.js │ ├── connectors-flowchart.js │ ├── connectors-statemachine.js │ ├── defaults.js │ ├── dom-adapter.js │ ├── dom.jsPlumb.js │ ├── drag.js │ ├── endpoint.js │ ├── jquery.jsPlumb.js │ ├── jsPlumb.js │ ├── overlays-guidelines.js │ ├── renderers-canvas.js │ ├── renderers-svg.js │ ├── renderers-vml.js │ └── util.js ├── jstorage.js ├── lod ├── app.js ├── connection.class.js ├── export.js ├── graph.class.js ├── handlers.js ├── helper.class.js ├── jsplumb │ ├── connector.js │ └── helper.js ├── layout.js ├── layout │ ├── buffer.js │ ├── grid.js │ ├── radial.js │ ├── spring.js │ └── virtual.js ├── node.class.js ├── profile.class.js ├── server_connector.js ├── service.class.js ├── services.js └── sidemenu.class.js └── md5.js /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/.name 2 | /.idea/LODmilla-frontend.iml 3 | /.idea/encodings.xml 4 | /.idea/misc.xml 5 | /.idea/modules.xml 6 | /.idea/scopes/scope_settings.xml 7 | /.idea/vcs.xml 8 | /.idea/workspace.xml 9 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM httpd:latest 2 | ADD . /usr/local/apache2/htdocs/lodmilla 3 | 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LODmilla-frontend 2 | ================= 3 | 4 | LODmilla - a graph-based Linked Open Data browser 5 | 6 | Demo: http://munkapad.sztaki.hu/lodmilla/ 7 | Presentation: http://lcpd2013.research-infrastructures.eu/slides/lodmilla.pdf 8 | 9 | Intended as a prototype tool for generic LOD browsing. 10 | This frontend of LODmilla is written in "plain" jQuery, no js frameworks used (yet). 11 | Graph visualization is done by jsPlumb. 12 | 13 | Licensed as free software under the terms of the Apache v2.0 License: http://www.apache.org/licenses/LICENSE-2.0.html 14 | 15 | We are searching contributors for writing plug-ins or improve the code. 16 | 17 | Please refer/cite the authors when re-using this code: 18 | 19 | http://eprints.sztaki.hu/8054/ 20 | Micsik, András and Turbucz, Sándor and Tóth, Zoltán (2015) Exploring publication metadata graphs with the LODmilla browser and editor. 21 | International Journal on Digital Libraries, 16 (x1). pp. 15-24. DOI:10.1007/s00799-014-0130-2 22 | 23 | http://eprints.sztaki.hu/8012/ 24 | Micsik, András and Turbucz, Sándor and Györök, Attila (2014) LODmilla: a Linked Data Browser for All. 25 | In: Posters&Demos@SEMANTiCS 2014, 2014.09.04-2014.09.05, Leipzig, Germany. 26 | 27 | How to configure LODmilla for a new SPARQL endpoint? 28 | ---------------------------------------------------- 29 | 30 | LODmilla can use any LOD server with JSONP support, however with SPARQL endpoint configured, you will get better functionality. 31 | 32 | 1. In js/lod/services.js add description for your SPARQL endpoint. You can copy and edit an existing endpoint which seems similar to yours. At this point, you will be able to open a URI by entering it in the box "Or enter a node URI". 33 | 2. If you want autocomplete queries as well, you need to edit js/lod/profile.class.js as well, and your search URL to this.searchURLs. Again, use existing examples. After this, you will see your endpoint in the top dropdown list showing 'dbpedia'. 34 | -------------------------------------------------------------------------------- /css/images/animated-overlay.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/animated-overlay.gif -------------------------------------------------------------------------------- /css/images/ui-anim_basic_16x16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-anim_basic_16x16.gif -------------------------------------------------------------------------------- /css/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_flat_75_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_flat_75_ffffff_40x100.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_glass_95_fef1ec_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_glass_95_fef1ec_1x400.png -------------------------------------------------------------------------------- /css/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /css/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /css/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /css/jquery.fancybox/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/jquery.fancybox/blank.gif -------------------------------------------------------------------------------- /css/jquery.fancybox/fancybox_loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/jquery.fancybox/fancybox_loading.gif -------------------------------------------------------------------------------- /css/jquery.fancybox/fancybox_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/jquery.fancybox/fancybox_overlay.png -------------------------------------------------------------------------------- /css/jquery.fancybox/fancybox_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/css/jquery.fancybox/fancybox_sprite.png -------------------------------------------------------------------------------- /css/jquery.fancybox/helpers/jquery.fancybox-thumbs.css: -------------------------------------------------------------------------------- 1 | #fancybox-thumbs { 2 | position: fixed; 3 | left: 0; 4 | width: 100%; 5 | overflow: hidden; 6 | z-index: 8050; 7 | } 8 | 9 | #fancybox-thumbs.bottom { 10 | bottom: 2px; 11 | } 12 | 13 | #fancybox-thumbs.top { 14 | top: 2px; 15 | } 16 | 17 | #fancybox-thumbs ul { 18 | position: relative; 19 | list-style: none; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | #fancybox-thumbs ul li { 25 | float: left; 26 | padding: 1px; 27 | opacity: 0.5; 28 | } 29 | 30 | #fancybox-thumbs ul li.active { 31 | opacity: 0.75; 32 | padding: 0; 33 | border: 1px solid #fff; 34 | } 35 | 36 | #fancybox-thumbs ul li:hover { 37 | opacity: 1; 38 | } 39 | 40 | #fancybox-thumbs ul li a { 41 | display: block; 42 | position: relative; 43 | overflow: hidden; 44 | border: 1px solid #222; 45 | background: #111; 46 | outline: none; 47 | } 48 | 49 | #fancybox-thumbs ul li img { 50 | display: block; 51 | position: relative; 52 | border: 0; 53 | padding: 0; 54 | } -------------------------------------------------------------------------------- /css/jquery.fancybox/jquery.fancybox.css: -------------------------------------------------------------------------------- 1 | /*! fancyBox v2.1.4 fancyapps.com | fancyapps.com/fancybox/#license */ 2 | .fancybox-wrap, 3 | .fancybox-skin, 4 | .fancybox-outer, 5 | .fancybox-inner, 6 | .fancybox-image, 7 | .fancybox-wrap iframe, 8 | .fancybox-wrap object, 9 | .fancybox-nav, 10 | .fancybox-nav span, 11 | .fancybox-tmp 12 | { 13 | padding: 0; 14 | margin: 0; 15 | border: 0; 16 | outline: none; 17 | vertical-align: top; 18 | } 19 | 20 | .fancybox-wrap { 21 | position: absolute; 22 | top: 0; 23 | left: 0; 24 | z-index: 8020; 25 | } 26 | 27 | .fancybox-skin { 28 | position: relative; 29 | background: #f9f9f9; 30 | color: #444; 31 | text-shadow: none; 32 | -webkit-border-radius: 4px; 33 | -moz-border-radius: 4px; 34 | border-radius: 4px; 35 | } 36 | 37 | .fancybox-opened { 38 | z-index: 8030; 39 | } 40 | 41 | .fancybox-opened .fancybox-skin { 42 | -webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 43 | -moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 44 | box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5); 45 | } 46 | 47 | .fancybox-outer, .fancybox-inner { 48 | position: relative; 49 | } 50 | 51 | .fancybox-inner { 52 | overflow: hidden; 53 | } 54 | 55 | .fancybox-type-iframe .fancybox-inner { 56 | -webkit-overflow-scrolling: touch; 57 | } 58 | 59 | .fancybox-error { 60 | color: #444; 61 | font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 62 | margin: 0; 63 | padding: 15px; 64 | white-space: nowrap; 65 | } 66 | 67 | .fancybox-image, .fancybox-iframe { 68 | display: block; 69 | width: 100%; 70 | height: 100%; 71 | } 72 | 73 | .fancybox-image { 74 | max-width: 100%; 75 | max-height: 100%; 76 | } 77 | 78 | #fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span { 79 | background-image: url('fancybox_sprite.png'); 80 | } 81 | 82 | #fancybox-loading { 83 | position: fixed; 84 | top: 50%; 85 | left: 50%; 86 | margin-top: -22px; 87 | margin-left: -22px; 88 | background-position: 0 -108px; 89 | opacity: 0.8; 90 | cursor: pointer; 91 | z-index: 8060; 92 | } 93 | 94 | #fancybox-loading div { 95 | width: 44px; 96 | height: 44px; 97 | background: url('fancybox_loading.gif') center center no-repeat; 98 | } 99 | 100 | .fancybox-close { 101 | position: absolute; 102 | top: -18px; 103 | right: -18px; 104 | width: 36px; 105 | height: 36px; 106 | cursor: pointer; 107 | z-index: 8040; 108 | } 109 | 110 | .fancybox-nav { 111 | position: absolute; 112 | top: 0; 113 | width: 40%; 114 | height: 100%; 115 | cursor: pointer; 116 | text-decoration: none; 117 | background: transparent url('blank.gif'); /* helps IE */ 118 | -webkit-tap-highlight-color: rgba(0,0,0,0); 119 | z-index: 8040; 120 | } 121 | 122 | .fancybox-prev { 123 | left: 0; 124 | } 125 | 126 | .fancybox-next { 127 | right: 0; 128 | } 129 | 130 | .fancybox-nav span { 131 | position: absolute; 132 | top: 50%; 133 | width: 36px; 134 | height: 34px; 135 | margin-top: -18px; 136 | cursor: pointer; 137 | z-index: 8040; 138 | visibility: hidden; 139 | } 140 | 141 | .fancybox-prev span { 142 | left: 10px; 143 | background-position: 0 -36px; 144 | } 145 | 146 | .fancybox-next span { 147 | right: 10px; 148 | background-position: 0 -72px; 149 | } 150 | 151 | .fancybox-nav:hover span { 152 | visibility: visible; 153 | } 154 | 155 | .fancybox-tmp { 156 | position: absolute; 157 | top: -99999px; 158 | left: -99999px; 159 | visibility: hidden; 160 | max-width: 99999px; 161 | max-height: 99999px; 162 | overflow: visible !important; 163 | } 164 | 165 | /* Overlay helper */ 166 | 167 | .fancybox-lock { 168 | overflow: hidden; 169 | } 170 | 171 | .fancybox-overlay { 172 | position: absolute; 173 | top: 0; 174 | left: 0; 175 | overflow: hidden; 176 | display: none; 177 | z-index: 8010; 178 | background: url('fancybox_overlay.png'); 179 | } 180 | 181 | .fancybox-overlay-fixed { 182 | position: fixed; 183 | bottom: 0; 184 | right: 0; 185 | } 186 | 187 | .fancybox-lock .fancybox-overlay { 188 | overflow: auto; 189 | overflow-y: scroll; 190 | } 191 | 192 | /* Title helper */ 193 | 194 | .fancybox-title { 195 | visibility: hidden; 196 | font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif; 197 | position: relative; 198 | text-shadow: none; 199 | z-index: 8050; 200 | } 201 | 202 | .fancybox-opened .fancybox-title { 203 | visibility: visible; 204 | } 205 | 206 | .fancybox-title-float-wrap { 207 | position: absolute; 208 | bottom: 0; 209 | right: 50%; 210 | margin-bottom: -35px; 211 | z-index: 8050; 212 | text-align: center; 213 | } 214 | 215 | .fancybox-title-float-wrap .child { 216 | display: inline-block; 217 | margin-right: -100%; 218 | padding: 2px 20px; 219 | background: transparent; /* Fallback for web browsers that doesn't support RGBa */ 220 | background: rgba(0, 0, 0, 0.8); 221 | -webkit-border-radius: 15px; 222 | -moz-border-radius: 15px; 223 | border-radius: 15px; 224 | text-shadow: 0 1px 2px #222; 225 | color: #FFF; 226 | font-weight: bold; 227 | line-height: 24px; 228 | white-space: nowrap; 229 | } 230 | 231 | .fancybox-title-outside-wrap { 232 | position: relative; 233 | margin-top: 10px; 234 | color: #fff; 235 | } 236 | 237 | .fancybox-title-inside-wrap { 238 | padding-top: 10px; 239 | } 240 | 241 | .fancybox-title-over-wrap { 242 | position: absolute; 243 | bottom: 0; 244 | left: 0; 245 | color: #fff; 246 | padding: 10px; 247 | background: #000; 248 | background: rgba(0, 0, 0, .8); 249 | } -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | lodmilla: 4 | image: httpd:latest 5 | ports: 6 | - "9999:80" 7 | volumes: 8 | - .:/usr/local/apache2/htdocs/lodmilla 9 | restart: always 10 | -------------------------------------------------------------------------------- /document-properties-deactivated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/document-properties-deactivated.png -------------------------------------------------------------------------------- /help.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SZTAKI LodMilla - Help 5 | 6 | 7 | 8 | 9 | 10 |

SZTAKI LODmilla - Help

11 |

The SZTAKI LODmilla is a JS application to navigate through different LOD and RDF datasets. It visualizes the resources as graph nodes and their connections as graph vertices.

12 |

We hope that most of the functions are self-explanatory :)

13 |

Use CTRL and ALT key for group selection and deselection with rectangle selection tool.

14 |

Both CTRL and ALT key can be used to select or deselect a node while clicking on it.

15 | 16 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /img/SZTAKI_logo_2012_english_RG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/SZTAKI_logo_2012_english_RG.png -------------------------------------------------------------------------------- /img/SZTAKI_logo_2012_small_RGB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/SZTAKI_logo_2012_small_RGB.png -------------------------------------------------------------------------------- /img/arrow-down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/arrow-down.png -------------------------------------------------------------------------------- /img/arrow-up-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/arrow-up-3.png -------------------------------------------------------------------------------- /img/cross.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/cross.png -------------------------------------------------------------------------------- /img/default-rdf-type-group-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-group-32.png -------------------------------------------------------------------------------- /img/default-rdf-type-noendpoint-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-noendpoint-32.png -------------------------------------------------------------------------------- /img/default-rdf-type-person-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-person-32.png -------------------------------------------------------------------------------- /img/default-rdf-type-thing-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-thing-32.png -------------------------------------------------------------------------------- /img/default-rdf-type-thing-empty-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-thing-empty-32.png -------------------------------------------------------------------------------- /img/default-rdf-type-work-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/default-rdf-type-work-32.png -------------------------------------------------------------------------------- /img/document-properties-deactivated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/document-properties-deactivated.png -------------------------------------------------------------------------------- /img/document-properties.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/document-properties.png -------------------------------------------------------------------------------- /img/edit-add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/edit-add.png -------------------------------------------------------------------------------- /img/edit-delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/edit-delete.png -------------------------------------------------------------------------------- /img/edit-delete2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/edit-delete2.png -------------------------------------------------------------------------------- /img/edit-hide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/edit-hide.png -------------------------------------------------------------------------------- /img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/favicon.png -------------------------------------------------------------------------------- /img/help-about-2-deactivated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/help-about-2-deactivated.png -------------------------------------------------------------------------------- /img/help-about-2-half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/help-about-2-half.png -------------------------------------------------------------------------------- /img/help-about-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/help-about-2.png -------------------------------------------------------------------------------- /img/readme.txt: -------------------------------------------------------------------------------- 1 | http://seamless-pixels.blogspot.co.uk/2012/10/tileable-metal-texture-1.html - tileable-metal-texture-1.jpg -------------------------------------------------------------------------------- /img/system-help-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/system-help-3.png -------------------------------------------------------------------------------- /img/tileable-metal-texture-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/tileable-metal-texture-1.jpg -------------------------------------------------------------------------------- /img/tileable-metal-texture-1_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/tileable-metal-texture-1_v2.png -------------------------------------------------------------------------------- /img/tileable-metal-texture-1mod.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/img/tileable-metal-texture-1mod.jpg -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | SZTAKI LODmilla 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 27 | 28 | 29 | 30 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 |
65 |
67 |
68 |

69 | 70 |
71 | Created by: DSD
72 | Powerd by: jsPlumb
73 | Graphic elements from: Free Seamless Textures, Open Icon Library 74 |

75 |
76 |
77 |
78 | 79 | 80 |
81 |
82 |
83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /js/1.4.0/jsPlumb-connectors-statemachine-1.4.0-RC1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jsPlumb 3 | * 4 | * Title:jsPlumb 1.4.0 5 | * 6 | * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas 7 | * elements, or VML. 8 | * 9 | * This file contains the state machine connectors. 10 | * 11 | * Thanks to Brainstorm Mobile Solutions for supporting the development of these. 12 | * 13 | * Copyright (c) 2010 - 2013 Simon Porritt (simon.porritt@gmail.com) 14 | * 15 | * http://jsplumb.org 16 | * http://github.com/sporritt/jsplumb 17 | * http://code.google.com/p/jsplumb 18 | * 19 | * Dual licensed under the MIT and GPL2 licenses. 20 | */ 21 | 22 | ;(function() { 23 | 24 | var Line = function(x1, y1, x2, y2) { 25 | 26 | this.m = (y2 - y1) / (x2 - x1); 27 | this.b = -1 * ((this.m * x1) - y1); 28 | 29 | this.rectIntersect = function(x,y,w,h) { 30 | var results = []; 31 | 32 | // try top face 33 | // the equation of the top face is y = (0 * x) + b; y = b. 34 | var xInt = (y - this.b) / this.m; 35 | // test that the X value is in the line's range. 36 | if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]); 37 | 38 | // try right face 39 | var yInt = (this.m * (x + w)) + this.b; 40 | if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]); 41 | 42 | // bottom face 43 | var xInt = ((y + h) - this.b) / this.m; 44 | // test that the X value is in the line's range. 45 | if (xInt >= x && xInt <= (x + w)) results.push([ xInt, (this.m * xInt) + this.b ]); 46 | 47 | // try left face 48 | var yInt = (this.m * x) + this.b; 49 | if (yInt >= y && yInt <= (y + h)) results.push([ (yInt - this.b) / this.m, yInt ]); 50 | 51 | if (results.length == 2) { 52 | var midx = (results[0][0] + results[1][0]) / 2, midy = (results[0][1] + results[1][1]) / 2; 53 | results.push([ midx,midy ]); 54 | // now calculate the segment inside the rectangle where the midpoint lies. 55 | var xseg = midx <= x + (w / 2) ? -1 : 1, 56 | yseg = midy <= y + (h / 2) ? -1 : 1; 57 | results.push([xseg, yseg]); 58 | return results; 59 | } 60 | 61 | return null; 62 | 63 | }; 64 | }, 65 | _segment = function(x1, y1, x2, y2) { 66 | if (x1 <= x2 && y2 <= y1) return 1; 67 | else if (x1 <= x2 && y1 <= y2) return 2; 68 | else if (x2 <= x1 && y2 >= y1) return 3; 69 | return 4; 70 | }, 71 | 72 | // the control point we will use depends on the faces to which each end of the connection is assigned, specifically whether or not the 73 | // two faces are parallel or perpendicular. if they are parallel then the control point lies on the midpoint of the axis in which they 74 | // are parellel and varies only in the other axis; this variation is proportional to the distance that the anchor points lie from the 75 | // center of that face. if the two faces are perpendicular then the control point is at some distance from both the midpoints; the amount and 76 | // direction are dependent on the orientation of the two elements. 'seg', passed in to this method, tells you which segment the target element 77 | // lies in with respect to the source: 1 is top right, 2 is bottom right, 3 is bottom left, 4 is top left. 78 | // 79 | // sourcePos and targetPos are arrays of info about where on the source and target each anchor is located. their contents are: 80 | // 81 | // 0 - absolute x 82 | // 1 - absolute y 83 | // 2 - proportional x in element (0 is left edge, 1 is right edge) 84 | // 3 - proportional y in element (0 is top edge, 1 is bottom edge) 85 | // 86 | _findControlPoint = function(midx, midy, segment, sourceEdge, targetEdge, dx, dy, distance, proximityLimit) { 87 | // TODO (maybe) 88 | // - if anchor pos is 0.5, make the control point take into account the relative position of the elements. 89 | if (distance <= proximityLimit) return [midx, midy]; 90 | 91 | if (segment === 1) { 92 | if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ]; 93 | else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ]; 94 | else return [ midx + (-1 * dx) , midy + (-1 * dy) ]; 95 | } 96 | else if (segment === 2) { 97 | if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ]; 98 | else if (sourceEdge[2] >= 1 && targetEdge[2] <= 0) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ]; 99 | else return [ midx + (1 * dx) , midy + (-1 * dy) ]; 100 | } 101 | else if (segment === 3) { 102 | if (sourceEdge[3] >= 1 && targetEdge[3] <= 0) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ]; 103 | else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ]; 104 | else return [ midx + (-1 * dx) , midy + (-1 * dy) ]; 105 | } 106 | else if (segment === 4) { 107 | if (sourceEdge[3] <= 0 && targetEdge[3] >= 1) return [ midx + (sourceEdge[2] < 0.5 ? -1 * dx : dx), midy ]; 108 | else if (sourceEdge[2] <= 0 && targetEdge[2] >= 1) return [ midx, midy + (sourceEdge[3] < 0.5 ? -1 * dy : dy) ]; 109 | else return [ midx + (1 * dx) , midy + (-1 * dy) ]; 110 | } 111 | 112 | }; 113 | 114 | /** 115 | * Class: Connectors.StateMachine 116 | * Provides 'state machine' connectors. 117 | */ 118 | /* 119 | * Function: Constructor 120 | * 121 | * Parameters: 122 | * curviness - measure of how "curvy" the connectors will be. this is translated as the distance that the 123 | * Bezier curve's control point is from the midpoint of the straight line connecting the two 124 | * endpoints, and does not mean that the connector is this wide. The Bezier curve never reaches 125 | * its control points; they act as gravitational masses. defaults to 10. 126 | * margin - distance from element to start and end connectors, in pixels. defaults to 5. 127 | * proximityLimit - sets the distance beneath which the elements are consider too close together to bother 128 | * with fancy curves. by default this is 80 pixels. 129 | * loopbackRadius - the radius of a loopback connector. optional; defaults to 25. 130 | * showLoopback - If set to false this tells the connector that it is ok to paint connections whose source and target is the same element with a connector running through the element. The default value for this is true; the connector always makes a loopback connection loop around the element rather than passing through it. 131 | */ 132 | jsPlumb.Connectors.StateMachine = function(params) { 133 | params = params || {}; 134 | this.type = "StateMachine"; 135 | 136 | var self = this, 137 | _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments), 138 | curviness = params.curviness || 10, 139 | margin = params.margin || 5, 140 | proximityLimit = params.proximityLimit || 80, 141 | clockwise = params.orientation && params.orientation === "clockwise", 142 | loopbackRadius = params.loopbackRadius || 25, 143 | showLoopback = params.showLoopback !== false; 144 | 145 | this._compute = function(paintInfo, params) { 146 | var w = Math.abs(params.sourcePos[0] - params.targetPos[0]), 147 | h = Math.abs(params.sourcePos[1] - params.targetPos[1]), 148 | x = Math.min(params.sourcePos[0], params.targetPos[0]), 149 | y = Math.min(params.sourcePos[1], params.targetPos[1]); 150 | 151 | if (!showLoopback || (params.sourceEndpoint.elementId !== params.targetEndpoint.elementId)) { 152 | var _sx = params.sourcePos[0] < params.targetPos[0] ? 0 : w, 153 | _sy = params.sourcePos[1] < params.targetPos[1] ? 0:h, 154 | _tx = params.sourcePos[0] < params.targetPos[0] ? w : 0, 155 | _ty = params.sourcePos[1] < params.targetPos[1] ? h : 0; 156 | 157 | // now adjust for the margin 158 | if (params.sourcePos[2] === 0) _sx -= margin; 159 | if (params.sourcePos[2] === 1) _sx += margin; 160 | if (params.sourcePos[3] === 0) _sy -= margin; 161 | if (params.sourcePos[3] === 1) _sy += margin; 162 | if (params.targetPos[2] === 0) _tx -= margin; 163 | if (params.targetPos[2] === 1) _tx += margin; 164 | if (params.targetPos[3] === 0) _ty -= margin; 165 | if (params.targetPos[3] === 1) _ty += margin; 166 | 167 | // 168 | // these connectors are quadratic bezier curves, having a single control point. if both anchors 169 | // are located at 0.5 on their respective faces, the control point is set to the midpoint and you 170 | // get a straight line. this is also the case if the two anchors are within 'proximityLimit', since 171 | // it seems to make good aesthetic sense to do that. outside of that, the control point is positioned 172 | // at 'curviness' pixels away along the normal to the straight line connecting the two anchors. 173 | // 174 | // there may be two improvements to this. firstly, we might actually support the notion of avoiding nodes 175 | // in the UI, or at least making a good effort at doing so. if a connection would pass underneath some node, 176 | // for example, we might increase the distance the control point is away from the midpoint in a bid to 177 | // steer it around that node. this will work within limits, but i think those limits would also be the likely 178 | // limits for, once again, aesthetic good sense in the layout of a chart using these connectors. 179 | // 180 | // the second possible change is actually two possible changes: firstly, it is possible we should gradually 181 | // decrease the 'curviness' as the distance between the anchors decreases; start tailing it off to 0 at some 182 | // point (which should be configurable). secondly, we might slightly increase the 'curviness' for connectors 183 | // with respect to how far their anchor is from the center of its respective face. this could either look cool, 184 | // or stupid, and may indeed work only in a way that is so subtle as to have been a waste of time. 185 | // 186 | 187 | var _midx = (_sx + _tx) / 2, _midy = (_sy + _ty) / 2, 188 | m2 = (-1 * _midx) / _midy, theta2 = Math.atan(m2), 189 | dy = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.sin(theta2)), 190 | dx = (m2 == Infinity || m2 == -Infinity) ? 0 : Math.abs(curviness / 2 * Math.cos(theta2)), 191 | segment = _segment(_sx, _sy, _tx, _ty), 192 | distance = Math.sqrt(Math.pow(_tx - _sx, 2) + Math.pow(_ty - _sy, 2)), 193 | // calculate the control point. this code will be where we'll put in a rudimentary element avoidance scheme; it 194 | // will work by extending the control point to force the curve to be, um, curvier. 195 | _controlPoint = _findControlPoint(_midx, 196 | _midy, 197 | segment, 198 | params.sourcePos, 199 | params.targetPos, 200 | curviness, curviness, 201 | distance, 202 | proximityLimit); 203 | 204 | _super.addSegment("Bezier", { 205 | x1:_tx, y1:_ty, x2:_sx, y2:_sy, 206 | cp1x:_controlPoint[0], cp1y:_controlPoint[1], 207 | cp2x:_controlPoint[0], cp2y:_controlPoint[1] 208 | }); 209 | } 210 | else { 211 | // a loopback connector. draw an arc from one anchor to the other. 212 | var x1 = params.sourcePos[0], x2 = params.sourcePos[0], y1 = params.sourcePos[1] - margin, y2 = params.sourcePos[1] - margin, 213 | cx = x1, cy = y1 - loopbackRadius; 214 | 215 | // canvas sizing stuff, to ensure the whole painted area is visible. 216 | w = 2 * loopbackRadius, 217 | h = 2 * loopbackRadius, 218 | x = cx - loopbackRadius, 219 | y = cy - loopbackRadius; 220 | 221 | paintInfo.points[0] = x; 222 | paintInfo.points[1] = y; 223 | paintInfo.points[2] = w; 224 | paintInfo.points[3] = h; 225 | 226 | // ADD AN ARC SEGMENT. 227 | _super.addSegment("Arc", { 228 | x1:(x1-x) + 4, 229 | y1:y1-y, 230 | startAngle:0, 231 | endAngle: 2 * Math.PI, 232 | r:loopbackRadius, 233 | ac:!clockwise, 234 | x2:(x1-x) - 4, 235 | y2:y1-y, 236 | cx:cx-x, 237 | cy:cy-y 238 | }); 239 | } 240 | }; 241 | }; 242 | })(); 243 | 244 | /* 245 | // a possible rudimentary avoidance scheme, old now, perhaps not useful. 246 | // if (avoidSelector) { 247 | // var testLine = new Line(sourcePos[0] + _sx,sourcePos[1] + _sy,sourcePos[0] + _tx,sourcePos[1] + _ty); 248 | // var sel = jsPlumb.getSelector(avoidSelector); 249 | // for (var i = 0; i < sel.length; i++) { 250 | // var id = jsPlumb.getId(sel[i]); 251 | // if (id != sourceEndpoint.elementId && id != targetEndpoint.elementId) { 252 | // o = jsPlumb.getOffset(id), s = jsPlumb.getSize(id); 253 | // 254 | // if (o && s) { 255 | // var collision = testLine.rectIntersect(o.left,o.top,s[0],s[1]); 256 | // if (collision) { 257 | // set the control point to be a certain distance from the midpoint of the two points that 258 | // the line crosses on the rectangle. 259 | // TODO where will this 75 number come from? 260 | // _controlX = collision[2][0] + (75 * collision[3][0]); 261 | // / _controlY = collision[2][1] + (75 * collision[3][1]); 262 | // } 263 | // } 264 | // } 265 | // } 266 | //} 267 | */ -------------------------------------------------------------------------------- /js/1.4.0/jsPlumb-dom-adapter-1.4.0-RC1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jsPlumb 3 | * 4 | * Title:jsPlumb 1.4.0 5 | * 6 | * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas 7 | * elements, or VML. 8 | * 9 | * This file contains the base functionality for DOM type adapters. 10 | * 11 | * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org) 12 | * 13 | * http://jsplumb.org 14 | * http://github.com/sporritt/jsplumb 15 | * http://code.google.com/p/jsplumb 16 | * 17 | * Dual licensed under the MIT and GPL2 licenses. 18 | */ 19 | ;(function() { 20 | 21 | var canvasAvailable = !!document.createElement('canvas').getContext, 22 | svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"), 23 | // http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml-or-svg-in-a-browser 24 | vmlAvailable = function() { 25 | if (vmlAvailable.vml == undefined) { 26 | var a = document.body.appendChild(document.createElement('div')); 27 | a.innerHTML = ''; 28 | var b = a.firstChild; 29 | b.style.behavior = "url(#default#VML)"; 30 | vmlAvailable.vml = b ? typeof b.adj == "object": true; 31 | a.parentNode.removeChild(a); 32 | } 33 | return vmlAvailable.vml; 34 | }; 35 | 36 | /** 37 | Manages dragging for some instance of jsPlumb. 38 | */ 39 | var DragManager = function(_currentInstance) { 40 | var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {}, 41 | // elementids mapped to the draggable to which they belong. 42 | _draggablesForElements = {}; 43 | 44 | /** 45 | register some element as draggable. right now the drag init stuff is done elsewhere, and it is 46 | possible that will continue to be the case. 47 | */ 48 | this.register = function(el) { 49 | var jpcl = jsPlumb.CurrentLibrary; 50 | el = jpcl.getElementObject(el); 51 | var id = _currentInstance.getId(el), 52 | domEl = jpcl.getDOMElement(el), 53 | parentOffset = jpcl.getOffset(el); 54 | 55 | if (!_draggables[id]) { 56 | _draggables[id] = el; 57 | _dlist.push(el); 58 | _delements[id] = {}; 59 | } 60 | 61 | // look for child elements that have endpoints and register them against this draggable. 62 | var _oneLevel = function(p, startOffset) { 63 | if (p) { 64 | for (var i = 0; i < p.childNodes.length; i++) { 65 | if (p.childNodes[i].nodeType != 3 && p.childNodes[i].nodeType != 8) { 66 | var cEl = jpcl.getElementObject(p.childNodes[i]), 67 | cid = _currentInstance.getId(cEl, null, true); 68 | if (cid && _elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) { 69 | var cOff = jpcl.getOffset(cEl); 70 | _delements[id][cid] = { 71 | id:cid, 72 | offset:{ 73 | left:cOff.left - parentOffset.left, 74 | top:cOff.top - parentOffset.top 75 | } 76 | }; 77 | _draggablesForElements[cid] = id; 78 | } 79 | _oneLevel(p.childNodes[i]); 80 | } 81 | } 82 | } 83 | }; 84 | 85 | _oneLevel(domEl); 86 | }; 87 | 88 | // refresh the offsets for child elements of this element. 89 | this.updateOffsets = function(elId) { 90 | var jpcl = jsPlumb.CurrentLibrary, 91 | el = jpcl.getElementObject(elId), 92 | id = _currentInstance.getId(el), 93 | children = _delements[id], 94 | parentOffset = jpcl.getOffset(el); 95 | 96 | if (children) { 97 | for (var i in children) { 98 | var cel = jpcl.getElementObject(i), 99 | cOff = jpcl.getOffset(cel); 100 | 101 | _delements[id][i] = { 102 | id:i, 103 | offset:{ 104 | left:cOff.left - parentOffset.left, 105 | top:cOff.top - parentOffset.top 106 | } 107 | }; 108 | _draggablesForElements[i] = id; 109 | } 110 | } 111 | }; 112 | 113 | /** 114 | notification that an endpoint was added to the given el. we go up from that el's parent 115 | node, looking for a parent that has been registered as a draggable. if we find one, we add this 116 | el to that parent's list of elements to update on drag (if it is not there already) 117 | */ 118 | this.endpointAdded = function(el) { 119 | var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el), c = jpcl.getDOMElement(el), 120 | p = c.parentNode, done = p == b; 121 | 122 | _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1; 123 | 124 | while (p != null && p != b) { 125 | var pid = _currentInstance.getId(p, null, true); 126 | if (pid && _draggables[pid]) { 127 | var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jpcl.getOffset(pEl); 128 | 129 | if (_delements[pid][id] == null) { 130 | var cLoc = jsPlumb.CurrentLibrary.getOffset(el); 131 | _delements[pid][id] = { 132 | id:id, 133 | offset:{ 134 | left:cLoc.left - pLoc.left, 135 | top:cLoc.top - pLoc.top 136 | } 137 | }; 138 | _draggablesForElements[id] = pid; 139 | } 140 | break; 141 | } 142 | p = p.parentNode; 143 | } 144 | }; 145 | 146 | this.endpointDeleted = function(endpoint) { 147 | if (_elementsWithEndpoints[endpoint.elementId]) { 148 | _elementsWithEndpoints[endpoint.elementId]--; 149 | if (_elementsWithEndpoints[endpoint.elementId] <= 0) { 150 | for (var i in _delements) { 151 | if (_delements[i]) { 152 | delete _delements[i][endpoint.elementId]; 153 | delete _draggablesForElements[endpoint.elementId]; 154 | } 155 | } 156 | } 157 | } 158 | }; 159 | 160 | this.changeId = function(oldId, newId) { 161 | _delements[newId] = _delements[oldId]; 162 | _delements[oldId] = {}; 163 | _draggablesForElements[newId] = _draggablesForElements[oldId]; 164 | _draggablesForElements[oldId] = null; 165 | }; 166 | 167 | this.getElementsForDraggable = function(id) { 168 | return _delements[id]; 169 | }; 170 | 171 | this.elementRemoved = function(elementId) { 172 | var elId = _draggablesForElements[elementId]; 173 | if (elId) { 174 | delete _delements[elId][elementId]; 175 | delete _draggablesForElements[elementId]; 176 | } 177 | }; 178 | 179 | this.reset = function() { 180 | _draggables = {}; 181 | _dlist = []; 182 | _delements = {}; 183 | _elementsWithEndpoints = {}; 184 | }; 185 | 186 | }; 187 | 188 | // for those browsers that dont have it. they still don't have it! but at least they won't crash. 189 | if (!window.console) 190 | window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} }; 191 | 192 | window.jsPlumbAdapter = { 193 | 194 | headless:false, 195 | 196 | appendToRoot : function(node) { 197 | document.body.appendChild(node); 198 | }, 199 | getRenderModes : function() { 200 | return [ "canvas", "svg", "vml" ] 201 | }, 202 | isRenderModeAvailable : function(m) { 203 | return { 204 | "canvas":canvasAvailable, 205 | "svg":svgAvailable, 206 | "vml":vmlAvailable() 207 | }[m]; 208 | }, 209 | getDragManager : function(_jsPlumb) { 210 | return new DragManager(_jsPlumb); 211 | }, 212 | setRenderMode : function(mode) { 213 | var renderMode; 214 | 215 | if (mode) { 216 | mode = mode.toLowerCase(); 217 | 218 | var canvasAvailable = this.isRenderModeAvailable("canvas"), 219 | svgAvailable = this.isRenderModeAvailable("svg"), 220 | vmlAvailable = this.isRenderModeAvailable("vml"); 221 | 222 | // now test we actually have the capability to do this. 223 | if (mode === "svg") { 224 | if (svgAvailable) renderMode = "svg" 225 | else if (canvasAvailable) renderMode = "canvas" 226 | else if (vmlAvailable) renderMode = "vml" 227 | } 228 | else if (mode === "canvas" && canvasAvailable) renderMode = "canvas"; 229 | else if (vmlAvailable) renderMode = "vml"; 230 | } 231 | 232 | return renderMode; 233 | } 234 | }; 235 | 236 | })(); -------------------------------------------------------------------------------- /js/1.4.0/jsPlumb-drag-1.4.0-RC1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * this is experimental and probably will not be used. solutions exist for most libraries. but of course if 3 | * i want to support multiple scopes at some stage then i will have to do dragging inside jsPlumb. 4 | */ 5 | ;(function() { 6 | 7 | window.jsPlumbDrag = function(_jsPlumb) { 8 | 9 | var ta = new TouchAdapter(); 10 | 11 | this.draggable = function(selector) { 12 | var el, elId, da = [], elo, d = false, 13 | isInSelector = function(el) { 14 | if (typeof selector == "string") 15 | return selector === _jsPlumb.getId(el); 16 | 17 | for (var i = 0; i < selector.length; i++) { 18 | var _sel = jsPlumb.CurrentLibrary.getDOMElement(selector[i]); 19 | if (_sel == el) return true; 20 | } 21 | return false; 22 | }; 23 | 24 | ta.bind(document, "mousedown", function(e) { 25 | var target = e.target || e.srcElement; 26 | if (isInSelector(target)) { 27 | el = jsPlumb.CurrentLibrary.getElementObject(target); 28 | elId = _jsPlumb.getId(el); 29 | elo = jsPlumb.CurrentLibrary.getOffset(el); 30 | da = [e.pageX, e.pageY]; 31 | d = true; 32 | } 33 | }); 34 | 35 | ta.bind(document, "mousemove", function(e) { 36 | if (d) { 37 | var dx = e.pageX - da[0], 38 | dy = e.pageY - da[1]; 39 | 40 | jsPlumb.CurrentLibrary.setOffset(el, { 41 | left:elo.left + dx, 42 | top:elo.top + dy 43 | }); 44 | _jsPlumb.repaint(elId); 45 | e.preventDefault(); 46 | e.stopPropagation(); 47 | } 48 | }); 49 | ta.bind(document, "mouseup", function(e) { 50 | el = null; 51 | d = false; 52 | }); 53 | }; 54 | 55 | var isIOS = ((/iphone|ipad/gi).test(navigator.appVersion)); 56 | if (isIOS) 57 | _jsPlumb.draggable = this.draggable; 58 | 59 | }; 60 | 61 | })(); -------------------------------------------------------------------------------- /js/1.4.0/jsPlumb-overlays-guidelines-1.4.0-RC1.js: -------------------------------------------------------------------------------- 1 | // this is really just a test overlay, so its undocumented and doesnt take any parameters. but i was loth to delete it. 2 | jsPlumb.Overlays.GuideLines = function() { 3 | var self = this; 4 | self.length = 50; 5 | self.lineWidth = 5; 6 | this.type = "GuideLines"; 7 | AbstractOverlay.apply(this, arguments); 8 | jsPlumb.jsPlumbUIComponent.apply(this, arguments); 9 | this.draw = function(connector, currentConnectionPaintStyle, connectorDimensions) { 10 | 11 | var head = connector.pointAlongPathFrom(self.loc, self.length / 2), 12 | mid = connector.pointOnPath(self.loc), 13 | tail = jsPlumbUtil.pointOnLine(head, mid, self.length), 14 | tailLine = jsPlumbUtil.perpendicularLineTo(head, tail, 40), 15 | headLine = jsPlumbUtil.perpendicularLineTo(tail, head, 20); 16 | 17 | self.paint(connector, [head, tail, tailLine, headLine], self.lineWidth, "red", null, connectorDimensions); 18 | 19 | return [Math.min(head.x, tail.x), Math.min(head.y, tail.y), Math.max(head.x, tail.x), Math.max(head.y,tail.y)]; 20 | }; 21 | 22 | this.computeMaxSize = function() { return 50; }; 23 | 24 | this.cleanup = function() { }; // nothing to clean up for GuideLines 25 | }; 26 | 27 | // a test 28 | jsPlumb.Overlays.svg.GuideLines = function() { 29 | var path = null, self = this, path2 = null, p1_1, p1_2; 30 | jsPlumb.Overlays.GuideLines.apply(this, arguments); 31 | this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) { 32 | if (path == null) { 33 | path = _node("path"); 34 | connector.svg.appendChild(path); 35 | self.attachListeners(path, connector); 36 | self.attachListeners(path, self); 37 | 38 | p1_1 = _node("path"); 39 | connector.svg.appendChild(p1_1); 40 | self.attachListeners(p1_1, connector); 41 | self.attachListeners(p1_1, self); 42 | 43 | p1_2 = _node("path"); 44 | connector.svg.appendChild(p1_2); 45 | self.attachListeners(p1_2, connector); 46 | self.attachListeners(p1_2, self); 47 | 48 | } 49 | 50 | _attr(path, { 51 | "d" : makePath(d[0], d[1]), 52 | stroke : "red", 53 | fill : null 54 | }); 55 | 56 | _attr(p1_1, { 57 | "d" : makePath(d[2][0], d[2][1]), 58 | stroke : "blue", 59 | fill : null 60 | }); 61 | 62 | _attr(p1_2, { 63 | "d" : makePath(d[3][0], d[3][1]), 64 | stroke : "green", 65 | fill : null 66 | }); 67 | }; 68 | 69 | var makePath = function(d1, d2) { 70 | return "M " + d1.x + "," + d1.y + 71 | " L" + d2.x + "," + d2.y; 72 | }; 73 | }; -------------------------------------------------------------------------------- /js/1.4.0/yui.jsPlumb-1.4.0-RC1.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jsPlumb 3 | * 4 | * Title:jsPlumb 1.4.0 5 | * 6 | * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas 7 | * elements, or VML. 8 | * 9 | * This file contains the YUI3 adapter. 10 | * 11 | * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org) 12 | * 13 | * http://jsplumb.org 14 | * http://github.com/sporritt/jsplumb 15 | * http://code.google.com/p/jsplumb 16 | * 17 | * Dual licensed under the MIT and GPL2 licenses. 18 | */ 19 | 20 | /** 21 | * addClass adds a class to the given element 22 | * animate calls the underlying library's animate functionality 23 | * appendElement appends a child element to a parent element. 24 | * bind binds some event to an element 25 | * dragEvents a dictionary of event names 26 | * extend extend some js object with another. probably not overly necessary; jsPlumb could just do this internally. 27 | * getAttribute gets some attribute from an element 28 | * getDragObject gets the object that is being dragged, by extracting it from the arguments passed to a drag callback 29 | * getDragScope gets the drag scope for a given element. 30 | * getElementObject turns an id or dom element into an element object of the underlying library's type. 31 | * getOffset gets an element's offset 32 | * getOriginalEvent gets the original browser event from some wrapper event. 33 | * getScrollLeft gets an element's scroll left. TODO: is this actually used? will it be? 34 | * getScrollTop gets an element's scroll top. TODO: is this actually used? will it be? 35 | * getSize gets an element's size. 36 | * getUIPosition gets the position of some element that is currently being dragged, by extracting it from the arguments passed to a drag callback. 37 | * initDraggable initializes an element to be draggable 38 | * initDroppable initializes an element to be droppable 39 | * isDragSupported returns whether or not drag is supported for some element. 40 | * isDropSupported returns whether or not drop is supported for some element. 41 | * removeClass removes a class from a given element. 42 | * removeElement removes some element completely from the DOM. 43 | * setAttribute sets an attribute on some element. 44 | * setDraggable sets whether or not some element should be draggable. 45 | * setDragScope sets the drag scope for a given element. 46 | * setOffset sets the offset of some element. 47 | */ 48 | (function() { 49 | 50 | if (!Array.prototype.indexOf) { 51 | Array.prototype.indexOf = function( v, b, s ) { 52 | for( var i = +b || 0, l = this.length; i < l; i++ ) { 53 | if( this[i]===v || s && this[i]==v ) { return i; } 54 | } 55 | return -1; 56 | }; 57 | } 58 | 59 | var Y; 60 | 61 | YUI().use('node', 'dd', 'dd-constrain', 'anim', 'node-event-simulate', function(_Y) { 62 | Y = _Y; 63 | Y.on("domready", function() { jsPlumb.init(); }); 64 | }); 65 | 66 | /** 67 | * adds the given value to the given list, with the given scope. creates the scoped list 68 | * if necessary. 69 | * used by initDraggable and initDroppable. 70 | */ 71 | var _add = function(list, scope, value) { 72 | var l = list[scope]; 73 | if (!l) { 74 | l = []; 75 | list[scope] = l; 76 | } 77 | l.push(value); 78 | }, 79 | ddEvents = [ "drag:mouseDown", "drag:afterMouseDown", "drag:mouseup", 80 | "drag:align", "drag:removeHandle", "drag:addHandle", "drag:removeInvalid", "drag:addInvalid", 81 | "drag:start", "drag:end", "drag:drag", "drag:over", "drag:enter", 82 | "drag:exit", "drag:drophit", "drag:dropmiss", "drop:over", "drop:enter", "drop:exit", "drop:hit" 83 | ], 84 | animEvents = [ "tween" ], 85 | /** 86 | * helper function to curry callbacks for some element. 87 | */ 88 | _wrapper = function(fn) { 89 | return function() { 90 | try { 91 | return fn.apply(this, arguments); 92 | } 93 | catch (e) { } 94 | }; 95 | }, 96 | /** 97 | * extracts options from the given options object, leaving out event handlers. 98 | */ 99 | _getDDOptions = function(options) { 100 | var o = {}; 101 | for (var i in options) if (ddEvents.indexOf(i) == -1) o[i] = options[i]; 102 | return o; 103 | }, 104 | /** 105 | * attaches all event handlers found in options to the given dragdrop object, and registering 106 | * the given el as the element of interest. 107 | */ 108 | _attachListeners = function(dd, options, eventList) { 109 | for (var ev in options) { 110 | if (eventList.indexOf(ev) != -1) { 111 | var w = _wrapper(options[ev]); 112 | dd.on(ev, w); 113 | } 114 | } 115 | }, 116 | _droppables = {}, 117 | _droppableOptions = {}, 118 | _draggablesByScope = {}, 119 | _draggablesById = {}, 120 | _droppableScopesById = {}, 121 | _checkHover = function(el, entering) { 122 | if (el) { 123 | var id = el.get("id"); 124 | if (id) { 125 | var options = _droppableOptions[id]; 126 | if (options) { 127 | if (options['hoverClass']) { 128 | if (entering) el.addClass(options['hoverClass']); 129 | else el.removeClass(options['hoverClass']); 130 | } 131 | } 132 | } 133 | } 134 | }, 135 | _lastDragObject = null, 136 | _extend = function(o1, o2) { 137 | for (var i in o2) 138 | o1[i] = o2[i]; 139 | return o1; 140 | }, 141 | _getAttribute = function(el, attributeId) { 142 | return el.getAttribute(attributeId); 143 | }, 144 | _getElementObject = function(el) { 145 | if (el == null) return null; 146 | var eee = null; 147 | eee = typeof el == 'string' ? Y.one('#' + el) : el._node ? el : Y.one(el); 148 | return eee; 149 | }; 150 | 151 | jsPlumb.CurrentLibrary = { 152 | 153 | addClass : function(el, clazz) { 154 | jsPlumb.CurrentLibrary.getElementObject(el).addClass(clazz); 155 | }, 156 | 157 | /** 158 | * animates the given element. 159 | */ 160 | animate : function(el, properties, options) { 161 | var o = _extend({node:el, to:properties}, options), 162 | id = _getAttribute(el, "id"); 163 | o["tween"] = jsPlumb.wrap(properties["tween"], function() { 164 | // TODO should use a current instance. 165 | jsPlumb.repaint(id); 166 | }); 167 | var a = new Y.Anim(o); 168 | _attachListeners(a, o, animEvents); 169 | a.run(); 170 | }, 171 | 172 | appendElement : function(child, parent) { 173 | _getElementObject (parent).append(child); 174 | }, 175 | 176 | /** 177 | * event binding wrapper. 178 | */ 179 | bind : function(el, event, callback) { 180 | _getElementObject(el).on(event, callback); 181 | }, 182 | 183 | dragEvents : { 184 | "start":"drag:start", "stop":"drag:end", "drag":"drag:drag", "step":"step", 185 | "over":"drop:enter", "out":"drop:exit", "drop":"drop:hit" 186 | }, 187 | 188 | extend : _extend, 189 | 190 | getAttribute : _getAttribute, 191 | 192 | getClientXY : function(eventObject) { 193 | return [eventObject.clientX, eventObject.clientY]; 194 | }, 195 | 196 | /** 197 | * takes the args passed to an event function and returns you an object representing that which is being dragged. 198 | */ 199 | getDragObject : function(eventArgs) { 200 | // this is a workaround for the unfortunate fact that in YUI3, the 'drop:exit' event does 201 | // not contain a reference to the drag that just exited. single-threaded js to the 202 | // rescue: we'll just keep it for ourselves. 203 | if (eventArgs[0].drag) _lastDragObject = eventArgs[0].drag.el; 204 | return _lastDragObject; 205 | }, 206 | 207 | getDragScope : function(el) { 208 | var id = jsPlumb.getId(el), 209 | dd = _draggablesById[id]; 210 | return dd.scope; 211 | }, 212 | 213 | getDropEvent : function(args) { 214 | return args[0]; 215 | }, 216 | 217 | getDropScope : function(el) { 218 | var id = jsPlumb.getId(el); 219 | return _droppableScopesById[id]; 220 | }, 221 | 222 | getDOMElement : function(el) { 223 | if (typeof(el) == "String") 224 | return document.getElementById(el); 225 | else if (el._node) 226 | return el._node; 227 | else return el; 228 | }, 229 | 230 | getElementObject : _getElementObject, 231 | 232 | getOffset : function(el) { 233 | var o = Y.DOM.getXY(el._node); 234 | return {left:o[0], top:o[1]}; 235 | }, 236 | 237 | getOriginalEvent : function(e) { 238 | return e._event; 239 | }, 240 | 241 | getPageXY : function(eventObject) { 242 | return [eventObject.pageX, eventObject.pageY]; 243 | }, 244 | 245 | getParent : function(el) { 246 | return jsPlumb.CurrentLibrary.getElementObject(el).get("parentNode"); 247 | }, 248 | 249 | getScrollLeft : function(el) { 250 | return 0; 251 | }, 252 | 253 | getScrollTop : function(el) { 254 | return 0; 255 | }, 256 | 257 | getSelector : function(context, spec) { 258 | var _convert = function(s) { return s && s ._nodes ? s._nodes : []; }; 259 | 260 | if (arguments.length == 2) { 261 | return _convert(jsPlumb.CurrentLibrary.getElementObject(context).all(spec)); 262 | } 263 | else { 264 | return _convert(Y.all(context)); 265 | } 266 | }, 267 | 268 | getSize : function(el) { 269 | return [ el._node.offsetWidth, el._node.offsetHeight ]; 270 | }, 271 | 272 | getTagName : function(el) { 273 | var e = jsPlumb.CurrentLibrary.getElementObject(el); 274 | return e != null && e._node != null ? e._node.tagName : null; 275 | }, 276 | 277 | getUIPosition : function(args, zoom) { 278 | zoom = zoom || 1; 279 | var n = args[0].currentTarget.el._node, 280 | o = Y.DOM.getXY(n); 281 | return {left:o[0] / zoom, top:o[1] / zoom}; 282 | }, 283 | 284 | hasClass : function(el, clazz) { 285 | return el.hasClass(clazz); 286 | }, 287 | 288 | initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) { 289 | var _opts = _getDDOptions(options), 290 | id = _jsPlumb.getId(el); 291 | _opts.node = "#" + id; 292 | var dd = new Y.DD.Drag(_opts), 293 | containment = options.constrain2node || options.containment; 294 | dd.el = el; 295 | 296 | if (containment) { 297 | dd.plug(Y.Plugin.DDConstrained, { 298 | constrain2node: containment 299 | }); 300 | } 301 | 302 | if (isPlumbedComponent) { 303 | var scope = options['scope'] || _jsPlumb.Defaults.Scope; 304 | dd.scope = scope; 305 | _add(_draggablesByScope, scope, dd); 306 | } 307 | 308 | _draggablesById[id] = dd; 309 | 310 | _attachListeners(dd, options, ddEvents); 311 | }, 312 | 313 | initDroppable : function(el, options) { 314 | var _opts = _getDDOptions(options), 315 | id = jsPlumb.getId(el); 316 | _opts.node = "#" + id; 317 | var dd = new Y.DD.Drop(_opts); 318 | 319 | _droppableOptions[id] = options; 320 | 321 | options = _extend({}, options); 322 | var scope = options['scope'] || jsPlumb.Defaults.Scope; 323 | _droppableScopesById[id] = scope; 324 | 325 | options["drop:enter"] = jsPlumb.wrap(options["drop:enter"], function(e) { 326 | if (e.drag.scope !== scope) return true; 327 | _checkHover(el, true); 328 | }, true); 329 | options["drop:exit"] = jsPlumb.wrap(options["drop:exit"], function(e) { 330 | _checkHover(el, false); 331 | }); 332 | options["drop:hit"] = jsPlumb.wrap(options["drop:hit"], function(e) { 333 | if (e.drag.scope !== scope) return true; 334 | _checkHover(el, false); 335 | }, true); 336 | 337 | _attachListeners(dd, options, ddEvents); 338 | }, 339 | 340 | isAlreadyDraggable : function(el) { 341 | el = _getElementObject(el); 342 | return el.hasClass("yui3-dd-draggable"); 343 | }, 344 | 345 | isDragSupported : function(el) { return true; }, 346 | isDropSupported : function(el) { return true; }, 347 | removeClass : function(el, clazz) { 348 | jsPlumb.CurrentLibrary.getElementObject(el).removeClass(clazz); 349 | }, 350 | removeElement : function(el) { _getElementObject(el).remove(); }, 351 | 352 | setAttribute : function(el, attributeName, attributeValue) { 353 | el.setAttribute(attributeName, attributeValue); 354 | }, 355 | 356 | /** 357 | * sets the draggable state for the given element 358 | */ 359 | setDraggable : function(el, draggable) { 360 | var id = jsPlumb.getId(el), 361 | dd = _draggablesById[id]; 362 | if (dd) dd.set("lock", !draggable); 363 | }, 364 | 365 | setDragScope : function(el, scope) { 366 | var id = jsPlumb.getId(el), 367 | dd = _draggablesById[id]; 368 | if (dd) dd.scope = scope; 369 | }, 370 | 371 | setOffset : function(el, o) { 372 | el = _getElementObject(el); 373 | el.set("top", o.top); 374 | el.set("left", o.left); 375 | }, 376 | 377 | stopDrag : function() { 378 | Y.DD.DDM.stopDrag(); 379 | }, 380 | 381 | trigger : function(el, event, originalEvent) { 382 | originalEvent.stopPropagation(); 383 | _getElementObject(el).simulate(event, { 384 | pageX:originalEvent.pageX, 385 | pageY:originalEvent.pageY, 386 | clientX:originalEvent.clientX, 387 | clientY:originalEvent.clientY 388 | }); 389 | }, 390 | 391 | /** 392 | * event unbinding wrapper. 393 | */ 394 | unbind : function(el, event, callback) { 395 | _getElementObject(el).detach(event, callback); 396 | } 397 | }; 398 | })(); -------------------------------------------------------------------------------- /js/jquery.fancybox-thumbs.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Thumbnail helper for fancyBox 3 | * version: 1.0.7 (Mon, 01 Oct 2012) 4 | * @requires fancyBox v2.0 or later 5 | * 6 | * Usage: 7 | * $(".fancybox").fancybox({ 8 | * helpers : { 9 | * thumbs: { 10 | * width : 50, 11 | * height : 50 12 | * } 13 | * } 14 | * }); 15 | * 16 | */ 17 | (function ($) { 18 | //Shortcut for fancyBox object 19 | var F = $.fancybox; 20 | 21 | //Add helper object 22 | F.helpers.thumbs = { 23 | defaults : { 24 | width : 50, // thumbnail width 25 | height : 50, // thumbnail height 26 | position : 'bottom', // 'top' or 'bottom' 27 | source : function ( item ) { // function to obtain the URL of the thumbnail image 28 | var href; 29 | 30 | if (item.element) { 31 | href = $(item.element).find('img').attr('src'); 32 | } 33 | 34 | if (!href && item.type === 'image' && item.href) { 35 | href = item.href; 36 | } 37 | 38 | return href; 39 | } 40 | }, 41 | 42 | wrap : null, 43 | list : null, 44 | width : 0, 45 | 46 | init: function (opts, obj) { 47 | var that = this, 48 | list, 49 | thumbWidth = opts.width, 50 | thumbHeight = opts.height, 51 | thumbSource = opts.source; 52 | 53 | //Build list structure 54 | list = ''; 55 | 56 | for (var n = 0; n < obj.group.length; n++) { 57 | list += '
  • '; 58 | } 59 | 60 | this.wrap = $('
    ').addClass(opts.position).appendTo('body'); 61 | this.list = $('').appendTo(this.wrap); 62 | 63 | //Load each thumbnail 64 | $.each(obj.group, function (i) { 65 | var href = thumbSource( obj.group[ i ] ); 66 | 67 | if (!href) { 68 | return; 69 | } 70 | 71 | $("").load(function () { 72 | var width = this.width, 73 | height = this.height, 74 | widthRatio, heightRatio, parent; 75 | 76 | if (!that.list || !width || !height) { 77 | return; 78 | } 79 | 80 | //Calculate thumbnail width/height and center it 81 | widthRatio = width / thumbWidth; 82 | heightRatio = height / thumbHeight; 83 | 84 | parent = that.list.children().eq(i).find('a'); 85 | 86 | if (widthRatio >= 1 && heightRatio >= 1) { 87 | if (widthRatio > heightRatio) { 88 | width = Math.floor(width / heightRatio); 89 | height = thumbHeight; 90 | 91 | } else { 92 | width = thumbWidth; 93 | height = Math.floor(height / widthRatio); 94 | } 95 | } 96 | 97 | $(this).css({ 98 | width : width, 99 | height : height, 100 | top : Math.floor(thumbHeight / 2 - height / 2), 101 | left : Math.floor(thumbWidth / 2 - width / 2) 102 | }); 103 | 104 | parent.width(thumbWidth).height(thumbHeight); 105 | 106 | $(this).hide().appendTo(parent).fadeIn(300); 107 | 108 | }).attr('src', href); 109 | }); 110 | 111 | //Set initial width 112 | this.width = this.list.children().eq(0).outerWidth(true); 113 | 114 | this.list.width(this.width * (obj.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5))); 115 | }, 116 | 117 | beforeLoad: function (opts, obj) { 118 | //Remove self if gallery do not have at least two items 119 | if (obj.group.length < 2) { 120 | obj.helpers.thumbs = false; 121 | 122 | return; 123 | } 124 | 125 | //Increase bottom margin to give space for thumbs 126 | obj.margin[ opts.position === 'top' ? 0 : 2 ] += ((opts.height) + 15); 127 | }, 128 | 129 | afterShow: function (opts, obj) { 130 | //Check if exists and create or update list 131 | if (this.list) { 132 | this.onUpdate(opts, obj); 133 | 134 | } else { 135 | this.init(opts, obj); 136 | } 137 | 138 | //Set active element 139 | this.list.children().removeClass('active').eq(obj.index).addClass('active'); 140 | }, 141 | 142 | //Center list 143 | onUpdate: function (opts, obj) { 144 | if (this.list) { 145 | this.list.stop(true).animate({ 146 | 'left': Math.floor($(window).width() * 0.5 - (obj.index * this.width + this.width * 0.5)) 147 | }, 150); 148 | } 149 | }, 150 | 151 | beforeClose: function () { 152 | if (this.wrap) { 153 | this.wrap.remove(); 154 | } 155 | 156 | this.wrap = null; 157 | this.list = null; 158 | this.width = 0; 159 | } 160 | } 161 | 162 | }(jQuery)); -------------------------------------------------------------------------------- /js/jquery.getimagedata.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * jQuery $.getImageData Plugin 0.3 4 | * http://www.maxnov.com/getimagedata 5 | * 6 | * Written by Max Novakovic (http://www.maxnov.com/) 7 | * Date: Thu Jan 13 2011 8 | * 9 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 10 | * 11 | * Includes jQuery JSONP Core Plugin 2.1.4 12 | * http://code.google.com/p/jquery-jsonp/ 13 | * Copyright 2010, Julian Aubourg 14 | * Released under the MIT License. 15 | * 16 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 17 | * 18 | * Copyright 2011, Max Novakovic 19 | * Dual licensed under the MIT or GPL Version 2 licenses. 20 | * http://www.maxnov.com/getimagedata/#license 21 | * 22 | */ 23 | (function(e,b){function m(){}function r(a){s=[a]}function c(a,b,e){return a&&a.apply(b.context||b,e)}function k(a){function k(g){!l++&&b(function(){n();h&&(u[d]={s:[g]});y&&(g=y.apply(a,[g]));c(a.success,a,[g,z]);c(A,a,[a,z])},0)}function t(g){!l++&&b(function(){n();h&&g!=B&&(u[d]=g);c(a.error,a,[a,g]);c(A,a,[a,g])},0)}a=e.extend({},C,a);var A=a.complete,y=a.dataFilter,D=a.callbackParameter,E=a.callback,O=a.cache,h=a.pageCache,F=a.charset,d=a.url,f=a.data,G=a.timeout,p,l=0,n=m;a.abort=function(){!l++&& 24 | n()};if(!1===c(a.beforeSend,a,[a])||l)return a;d=d||v;f=f?"string"==typeof f?f:e.param(f,a.traditional):v;d+=f?(/\?/.test(d)?"&":"?")+f:v;D&&(d+=(/\?/.test(d)?"&":"?")+encodeURIComponent(D)+"=?");!O&&!h&&(d+=(/\?/.test(d)?"&":"?")+"_"+(new Date).getTime()+"=");d=d.replace(/=\?(&|$)/,"="+E+"$1");h&&(p=u[d])?p.s?k(p.s[0]):t(p):b(function(a,c,f){if(!l){f=0" ).html( "" ).find("i").length; 89 | 90 | // ###################### MAIN FUNCTION ## 91 | function jsonp( xOptions ) { 92 | 93 | // Build data with default 94 | xOptions = $.extend( {} , xOptionsDefaults , xOptions ); 95 | 96 | // References to xOptions members (for better minification) 97 | var successCallback = xOptions.success, 98 | errorCallback = xOptions.error, 99 | completeCallback = xOptions.complete, 100 | dataFilter = xOptions.dataFilter, 101 | callbackParameter = xOptions.callbackParameter, 102 | successCallbackName = xOptions.callback, 103 | cacheFlag = xOptions.cache, 104 | pageCacheFlag = xOptions.pageCache, 105 | charset = xOptions.charset, 106 | url = xOptions.url, 107 | data = xOptions.data, 108 | timeout = xOptions.timeout, 109 | pageCached, 110 | 111 | // Abort/done flag 112 | done = 0, 113 | 114 | // Life-cycle functions 115 | cleanUp = noop, 116 | 117 | // Support vars 118 | supportOnload, 119 | supportOnreadystatechange, 120 | 121 | // Request execution vars 122 | firstChild, 123 | script, 124 | scriptAfter, 125 | timeoutTimer; 126 | 127 | // If we have Deferreds: 128 | // - substitute callbacks 129 | // - promote xOptions to a promise 130 | Deferred && Deferred(function( defer ) { 131 | defer.done( successCallback ).fail( errorCallback ); 132 | successCallback = defer.resolve; 133 | errorCallback = defer.reject; 134 | }).promise( xOptions ); 135 | 136 | // Create the abort method 137 | xOptions.abort = function() { 138 | !( done++ ) && cleanUp(); 139 | }; 140 | 141 | // Call beforeSend if provided (early abort if false returned) 142 | if ( callIfDefined( xOptions.beforeSend , xOptions , [ xOptions ] ) === !1 || done ) { 143 | return xOptions; 144 | } 145 | 146 | // Control entries 147 | url = url || STR_EMPTY; 148 | data = data ? ( (typeof data) == "string" ? data : $.param( data , xOptions.traditional ) ) : STR_EMPTY; 149 | 150 | // Build final url 151 | url += data ? ( qMarkOrAmp( url ) + data ) : STR_EMPTY; 152 | 153 | // Add callback parameter if provided as option 154 | callbackParameter && ( url += qMarkOrAmp( url ) + encodeURIComponent( callbackParameter ) + "=?" ); 155 | 156 | // Add anticache parameter if needed 157 | !cacheFlag && !pageCacheFlag && ( url += qMarkOrAmp( url ) + "_" + ( new Date() ).getTime() + "=" ); 158 | 159 | // Replace last ? by callback parameter 160 | url = url.replace( /=\?(&|$)/ , "=" + successCallbackName + "$1" ); 161 | 162 | // Success notifier 163 | function notifySuccess( json ) { 164 | 165 | if ( !( done++ ) ) { 166 | 167 | cleanUp(); 168 | // Pagecache if needed 169 | pageCacheFlag && ( pageCache [ url ] = { s: [ json ] } ); 170 | // Apply the data filter if provided 171 | dataFilter && ( json = dataFilter.apply( xOptions , [ json ] ) ); 172 | // Call success then complete 173 | callIfDefined( successCallback , xOptions , [ json , STR_SUCCESS, xOptions ] ); 174 | callIfDefined( completeCallback , xOptions , [ xOptions , STR_SUCCESS ] ); 175 | 176 | } 177 | } 178 | 179 | // Error notifier 180 | function notifyError( type ) { 181 | 182 | if ( !( done++ ) ) { 183 | 184 | // Clean up 185 | cleanUp(); 186 | // If pure error (not timeout), cache if needed 187 | pageCacheFlag && type != STR_TIMEOUT && ( pageCache[ url ] = type ); 188 | // Call error then complete 189 | callIfDefined( errorCallback , xOptions , [ xOptions , type ] ); 190 | callIfDefined( completeCallback , xOptions , [ xOptions , type ] ); 191 | 192 | } 193 | } 194 | 195 | // Check page cache 196 | if ( pageCacheFlag && ( pageCached = pageCache[ url ] ) ) { 197 | 198 | pageCached.s ? notifySuccess( pageCached.s[ 0 ] ) : notifyError( pageCached ); 199 | 200 | } else { 201 | 202 | // Install the generic callback 203 | // (BEWARE: global namespace pollution ahoy) 204 | win[ successCallbackName ] = genericCallback; 205 | 206 | // Create the script tag 207 | script = $( STR_SCRIPT_TAG )[ 0 ]; 208 | script.id = STR_JQUERY_JSONP + count++; 209 | 210 | // Set charset if provided 211 | if ( charset ) { 212 | script[ STR_CHARSET ] = charset; 213 | } 214 | 215 | opera && opera.version() < 11.60 ? 216 | // onerror is not supported: do not set as async and assume in-order execution. 217 | // Add a trailing script to emulate the event 218 | ( ( scriptAfter = $( STR_SCRIPT_TAG )[ 0 ] ).text = "document.getElementById('" + script.id + "')." + STR_ON_ERROR + "()" ) 219 | : 220 | // onerror is supported: set the script as async to avoid requests blocking each others 221 | ( script[ STR_ASYNC ] = STR_ASYNC ) 222 | 223 | ; 224 | 225 | // Internet Explorer: event/htmlFor trick 226 | if ( oldIE ) { 227 | script.htmlFor = script.id; 228 | script.event = STR_ON_CLICK; 229 | } 230 | 231 | // Attached event handlers 232 | script[ STR_ON_LOAD ] = script[ STR_ON_ERROR ] = script[ STR_ON_READY_STATE_CHANGE ] = function ( result ) { 233 | 234 | // Test readyState if it exists 235 | if ( !script[ STR_READY_STATE ] || !/i/.test( script[ STR_READY_STATE ] ) ) { 236 | 237 | try { 238 | 239 | script[ STR_ON_CLICK ] && script[ STR_ON_CLICK ](); 240 | 241 | } catch( _ ) {} 242 | 243 | result = lastValue; 244 | lastValue = 0; 245 | result ? notifySuccess( result[ 0 ] ) : notifyError( STR_ERROR ); 246 | 247 | } 248 | }; 249 | 250 | // Set source 251 | script.src = url; 252 | 253 | // Re-declare cleanUp function 254 | cleanUp = function( i ) { 255 | timeoutTimer && clearTimeout( timeoutTimer ); 256 | script[ STR_ON_READY_STATE_CHANGE ] = script[ STR_ON_LOAD ] = script[ STR_ON_ERROR ] = null; 257 | head[ STR_REMOVE_CHILD ]( script ); 258 | scriptAfter && head[ STR_REMOVE_CHILD ]( scriptAfter ); 259 | }; 260 | 261 | // Append main script 262 | head[ STR_INSERT_BEFORE ]( script , ( firstChild = head.firstChild ) ); 263 | 264 | // Append trailing script if needed 265 | scriptAfter && head[ STR_INSERT_BEFORE ]( scriptAfter , firstChild ); 266 | 267 | // If a timeout is needed, install it 268 | timeoutTimer = timeout > 0 && setTimeout( function() { 269 | notifyError( STR_TIMEOUT ); 270 | } , timeout ); 271 | 272 | } 273 | 274 | return xOptions; 275 | } 276 | 277 | // ###################### SETUP FUNCTION ## 278 | jsonp.setup = function( xOptions ) { 279 | $.extend( xOptionsDefaults , xOptions ); 280 | }; 281 | 282 | // ###################### INSTALL in jQuery ## 283 | $.jsonp = jsonp; 284 | 285 | } )( jQuery ); 286 | -------------------------------------------------------------------------------- /js/jquery.mousewheel.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) 2 | * Licensed under the MIT License (LICENSE.txt). 3 | * 4 | * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. 5 | * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. 6 | * Thanks to: Seamus Leahy for adding deltaX and deltaY 7 | * 8 | * Version: 3.0.6 9 | * 10 | * Requires: 1.2.2+ 11 | */ 12 | 13 | (function($) { 14 | 15 | var types = ['DOMMouseScroll', 'mousewheel']; 16 | 17 | if ($.event.fixHooks) { 18 | for ( var i=types.length; i; ) { 19 | $.event.fixHooks[ types[--i] ] = $.event.mouseHooks; 20 | } 21 | } 22 | 23 | $.event.special.mousewheel = { 24 | setup: function() { 25 | if ( this.addEventListener ) { 26 | for ( var i=types.length; i; ) { 27 | this.addEventListener( types[--i], handler, false ); 28 | } 29 | } else { 30 | this.onmousewheel = handler; 31 | } 32 | }, 33 | 34 | teardown: function() { 35 | if ( this.removeEventListener ) { 36 | for ( var i=types.length; i; ) { 37 | this.removeEventListener( types[--i], handler, false ); 38 | } 39 | } else { 40 | this.onmousewheel = null; 41 | } 42 | } 43 | }; 44 | 45 | $.fn.extend({ 46 | mousewheel: function(fn) { 47 | return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); 48 | }, 49 | 50 | unmousewheel: function(fn) { 51 | return this.unbind("mousewheel", fn); 52 | } 53 | }); 54 | 55 | 56 | function handler(event) { 57 | var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0; 58 | event = $.event.fix(orgEvent); 59 | event.type = "mousewheel"; 60 | 61 | // Old school scrollwheel delta 62 | if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; } 63 | if ( orgEvent.detail ) { delta = -orgEvent.detail/3; } 64 | 65 | // New school multidimensional scroll (touchpads) deltas 66 | deltaY = delta; 67 | 68 | // Gecko 69 | if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) { 70 | deltaY = 0; 71 | deltaX = -1*delta; 72 | } 73 | 74 | // Webkit 75 | if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; } 76 | if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; } 77 | 78 | // Add event and delta to the front of the arguments 79 | args.unshift(event, delta, deltaX, deltaY); 80 | 81 | return ($.event.dispatch || $.event.handle).apply(this, args); 82 | } 83 | 84 | })(jQuery); -------------------------------------------------------------------------------- /js/jquery.ui.touch-punch.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery UI Touch Punch 0.2.2 3 | * 4 | * Copyright 2011, Dave Furfero 5 | * Dual licensed under the MIT or GPL Version 2 licenses. 6 | * 7 | * Depends: 8 | * jquery.ui.widget.js 9 | * jquery.ui.mouse.js 10 | */ 11 | (function(b){b.support.touch="ontouchend" in document;if(!b.support.touch){return;}var c=b.ui.mouse.prototype,e=c._mouseInit,a;function d(g,h){if(g.originalEvent.touches.length>1){return;}g.preventDefault();var i=g.originalEvent.changedTouches[0],f=document.createEvent("MouseEvents");f.initMouseEvent(h,true,true,window,1,i.screenX,i.screenY,i.clientX,i.clientY,false,false,false,false,0,null);g.target.dispatchEvent(f);}c._touchStart=function(g){var f=this;if(a||!f._mouseCapture(g.originalEvent.changedTouches[0])){return;}a=true;f._touchMoved=false;d(g,"mouseover");d(g,"mousemove");d(g,"mousedown");};c._touchMove=function(f){if(!a){return;}this._touchMoved=true;d(f,"mousemove");};c._touchEnd=function(f){if(!a){return;}d(f,"mouseup");d(f,"mouseout");if(!this._touchMoved){d(f,"click");}a=false;};c._mouseInit=function(){var f=this;f.element.bind("touchstart",b.proxy(f,"_touchStart")).bind("touchmove",b.proxy(f,"_touchMove")).bind("touchend",b.proxy(f,"_touchEnd"));e.call(f);};})(jQuery); -------------------------------------------------------------------------------- /js/jsBezier-0.6-min.js: -------------------------------------------------------------------------------- 1 | (function(){"undefined"==typeof Math.sgn&&(Math.sgn=function(a){return 0==a?0:0l?l=p:pb.location&&(b.location=0);return w(a,b.location)},nearestPointOnCurve:function(a,b){var f=x(a,b);return{point:v(b,b.length-1,f.location,null,null),location:f.location}},pointOnCurve:s,pointAlongCurveFrom:function(a,b,f){return t(a,b,f).point},perpendicularToCurveAt:function(a,b,f,d){b=t(a,b,null==d?0:d);a=w(a,b.location);d=Math.atan(-1/a);a=f/2*Math.sin(d); 8 | f=f/2*Math.cos(d);return[{x:b.point.x+f,y:b.point.y+a},{x:b.point.x-f,y:b.point.y-a}]},locationAlongCurveFrom:function(a,b,f){return t(a,b,f).location},getLength:function(a){if(A(a))return 0;for(var b=s(a,0),f=0,d=0,g=null;1>d;)d+=0.005,g=s(a,d),f+=z(g,b),b=g;return f}}})(); -------------------------------------------------------------------------------- /js/jsPlumb/classList.js: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * classList.js: Cross-browser full element.classList implementation. 4 | * 2011-06-15 5 | * 6 | * By Eli Grey, http://eligrey.com 7 | * Public Domain. 8 | * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. 9 | 10 | TODO: merge this and the SVG stuff form jsplumb util. 11 | 12 | */ 13 | 14 | /*global self, document, DOMException */ 15 | 16 | /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 17 | 18 | if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) { 19 | 20 | (function (view) { 21 | 22 | "use strict"; 23 | 24 | var 25 | classListProp = "classList" 26 | , protoProp = "prototype" 27 | , elemCtrProto = (view.HTMLElement || view.Element)[protoProp] 28 | , objCtr = Object 29 | , strTrim = String[protoProp].trim || function () { 30 | return this.replace(/^\s+|\s+$/g, ""); 31 | } 32 | , arrIndexOf = Array[protoProp].indexOf || function (item) { 33 | var 34 | i = 0 35 | , len = this.length 36 | ; 37 | for (; i < len; i++) { 38 | if (i in this && this[i] === item) { 39 | return i; 40 | } 41 | } 42 | return -1; 43 | } 44 | // Vendors: please allow content code to instantiate DOMExceptions 45 | , DOMEx = function (type, message) { 46 | this.name = type; 47 | this.code = DOMException[type]; 48 | this.message = message; 49 | } 50 | , checkTokenAndGetIndex = function (classList, token) { 51 | if (token === "") { 52 | throw new DOMEx( 53 | "SYNTAX_ERR" 54 | , "An invalid or illegal string was specified" 55 | ); 56 | } 57 | if (/\s/.test(token)) { 58 | throw new DOMEx( 59 | "INVALID_CHARACTER_ERR" 60 | , "String contains an invalid character" 61 | ); 62 | } 63 | return arrIndexOf.call(classList, token); 64 | } 65 | , ClassList = function (elem) { 66 | var 67 | trimmedClasses = strTrim.call(elem.className) 68 | , classes = trimmedClasses ? trimmedClasses.split(/\s+/) : [] 69 | , i = 0 70 | , len = classes.length 71 | ; 72 | for (; i < len; i++) { 73 | this.push(classes[i]); 74 | } 75 | this._updateClassName = function () { 76 | elem.className = this.toString(); 77 | }; 78 | } 79 | , classListProto = ClassList[protoProp] = [] 80 | , classListGetter = function () { 81 | return new ClassList(this); 82 | } 83 | ; 84 | // Most DOMException implementations don't allow calling DOMException's toString() 85 | // on non-DOMExceptions. Error's toString() is sufficient here. 86 | DOMEx[protoProp] = Error[protoProp]; 87 | classListProto.item = function (i) { 88 | return this[i] || null; 89 | }; 90 | classListProto.contains = function (token) { 91 | token += ""; 92 | return checkTokenAndGetIndex(this, token) !== -1; 93 | }; 94 | classListProto.add = function (token) { 95 | token += ""; 96 | if (checkTokenAndGetIndex(this, token) === -1) { 97 | this.push(token); 98 | this._updateClassName(); 99 | } 100 | }; 101 | classListProto.remove = function (token) { 102 | token += ""; 103 | var index = checkTokenAndGetIndex(this, token); 104 | if (index !== -1) { 105 | this.splice(index, 1); 106 | this._updateClassName(); 107 | } 108 | }; 109 | classListProto.toggle = function (token) { 110 | token += ""; 111 | if (checkTokenAndGetIndex(this, token) === -1) { 112 | this.add(token); 113 | } else { 114 | this.remove(token); 115 | } 116 | }; 117 | classListProto.toString = function () { 118 | return this.join(" "); 119 | }; 120 | 121 | if (objCtr.defineProperty) { 122 | var classListPropDesc = { 123 | get: classListGetter 124 | , enumerable: true 125 | , configurable: true 126 | }; 127 | try { 128 | objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 129 | } catch (ex) { // IE 8 doesn't support enumerable:true 130 | if (ex.number === -0x7FF5EC54) { 131 | classListPropDesc.enumerable = false; 132 | objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); 133 | } 134 | } 135 | } else if (objCtr[protoProp].__defineGetter__) { 136 | elemCtrProto.__defineGetter__(classListProp, classListGetter); 137 | } 138 | 139 | }(self)); 140 | 141 | } -------------------------------------------------------------------------------- /js/jsPlumb/jsBezier-0.6-min.js: -------------------------------------------------------------------------------- 1 | (function(){"undefined"==typeof Math.sgn&&(Math.sgn=function(a){return 0==a?0:0l?l=p:pb.location&&(b.location=0);return w(a,b.location)},nearestPointOnCurve:function(a,b){var f=x(a,b);return{point:v(b,b.length-1,f.location,null,null),location:f.location}},pointOnCurve:s,pointAlongCurveFrom:function(a,b,f){return t(a,b,f).point},perpendicularToCurveAt:function(a,b,f,d){b=t(a,b,null==d?0:d);a=w(a,b.location);d=Math.atan(-1/a);a=f/2*Math.sin(d); 8 | f=f/2*Math.cos(d);return[{x:b.point.x+f,y:b.point.y+a},{x:b.point.x-f,y:b.point.y-a}]},locationAlongCurveFrom:function(a,b,f){return t(a,b,f).location},getLength:function(a){if(A(a))return 0;for(var b=s(a,0),f=0,d=0,g=null;1>d;)d+=0.005,g=s(a,d),f+=z(g,b),b=g;return f}}})(); -------------------------------------------------------------------------------- /js/jsPlumb/src/connectors-bezier.js: -------------------------------------------------------------------------------- 1 | 2 | ;(function() { 3 | 4 | var Bezier = function(params) { 5 | params = params || {}; 6 | 7 | var self = this, 8 | _super = jsPlumb.Connectors.AbstractConnector.apply(this, arguments), 9 | stub = params.stub || 50, 10 | majorAnchor = params.curviness || 150, 11 | minorAnchor = 10; 12 | 13 | this.type = "Bezier"; 14 | this.getCurviness = function() { return majorAnchor; }; 15 | 16 | this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) { 17 | // determine if the two anchors are perpendicular to each other in their orientation. we swap the control 18 | // points around if so (code could be tightened up) 19 | var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint), 20 | too = targetEndpoint.anchor.getOrientation(targetEndpoint), 21 | perpendicular = soo[0] != too[0] || soo[1] == too[1], 22 | p = []; 23 | 24 | if (!perpendicular) { 25 | if (soo[0] === 0) // X 26 | p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor); 27 | else p.push(point[0] - (majorAnchor * soo[0])); 28 | 29 | if (soo[1] === 0) // Y 30 | p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor); 31 | else p.push(point[1] + (majorAnchor * too[1])); 32 | } 33 | else { 34 | if (too[0] === 0) // X 35 | p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor); 36 | else p.push(point[0] + (majorAnchor * too[0])); 37 | 38 | if (too[1] === 0) // Y 39 | p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor); 40 | else p.push(point[1] + (majorAnchor * soo[1])); 41 | } 42 | 43 | return p; 44 | }; 45 | 46 | this._compute = function(paintInfo, p) { 47 | var sp = p.sourcePos, 48 | tp = p.targetPos, 49 | _w = Math.abs(sp[0] - tp[0]), 50 | _h = Math.abs(sp[1] - tp[1]), 51 | _sx = sp[0] < tp[0] ? _w : 0, 52 | _sy = sp[1] < tp[1] ? _h : 0, 53 | _tx = sp[0] < tp[0] ? 0 : _w, 54 | _ty = sp[1] < tp[1] ? 0 : _h, 55 | _CP = self._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint), 56 | _CP2 = self._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint); 57 | 58 | _super.addSegment(this, "Bezier", { 59 | x1:_sx, y1:_sy, x2:_tx, y2:_ty, 60 | cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1] 61 | }); 62 | }; 63 | }; 64 | 65 | jsPlumb.registerConnectorType(Bezier, "Bezier"); 66 | 67 | })(); -------------------------------------------------------------------------------- /js/jsPlumb/src/dom-adapter.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jsPlumb 3 | * 4 | * Title:jsPlumb 1.5.5 5 | * 6 | * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas 7 | * elements, or VML. 8 | * 9 | * This file contains the base functionality for DOM type adapters. 10 | * 11 | * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org) 12 | * 13 | * http://jsplumb.org 14 | * http://github.com/sporritt/jsplumb 15 | * http://code.google.com/p/jsplumb 16 | * 17 | * Dual licensed under the MIT and GPL2 licenses. 18 | */ 19 | ;(function() { 20 | 21 | var canvasAvailable = !!document.createElement('canvas').getContext, 22 | svgAvailable = !!window.SVGAngle || document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1"), 23 | // http://stackoverflow.com/questions/654112/how-do-you-detect-support-for-vml-or-svg-in-a-browser 24 | vmlAvailable = function() { 25 | if (vmlAvailable.vml === undefined) { 26 | var a = document.body.appendChild(document.createElement('div')); 27 | a.innerHTML = ''; 28 | var b = a.firstChild; 29 | if (b != null && b.style != null) { 30 | b.style.behavior = "url(#default#VML)"; 31 | vmlAvailable.vml = b ? typeof b.adj == "object": true; 32 | } 33 | else 34 | vmlAvailable.vml = false; 35 | a.parentNode.removeChild(a); 36 | } 37 | return vmlAvailable.vml; 38 | }; 39 | 40 | /** 41 | Manages dragging for some instance of jsPlumb. 42 | */ 43 | var DragManager = function(_currentInstance) { 44 | var _draggables = {}, _dlist = [], _delements = {}, _elementsWithEndpoints = {}, 45 | // elementids mapped to the draggable to which they belong. 46 | _draggablesForElements = {}; 47 | 48 | /** 49 | register some element as draggable. right now the drag init stuff is done elsewhere, and it is 50 | possible that will continue to be the case. 51 | */ 52 | this.register = function(el) { 53 | var jpcl = jsPlumb.CurrentLibrary, 54 | _el = jpcl.getElementObject(el), 55 | id = _currentInstance.getId(el), 56 | parentOffset = jpcl.getOffset(_el); 57 | 58 | if (!_draggables[id]) { 59 | _draggables[id] = el; 60 | _dlist.push(el); 61 | _delements[id] = {}; 62 | } 63 | 64 | // look for child elements that have endpoints and register them against this draggable. 65 | var _oneLevel = function(p, startOffset) { 66 | if (p) { 67 | for (var i = 0; i < p.childNodes.length; i++) { 68 | if (p.childNodes[i].nodeType != 3 && p.childNodes[i].nodeType != 8) { 69 | var cEl = jpcl.getElementObject(p.childNodes[i]), 70 | cid = _currentInstance.getId(p.childNodes[i], null, true); 71 | if (cid && _elementsWithEndpoints[cid] && _elementsWithEndpoints[cid] > 0) { 72 | var cOff = jpcl.getOffset(cEl); 73 | _delements[id][cid] = { 74 | id:cid, 75 | offset:{ 76 | left:cOff.left - parentOffset.left, 77 | top:cOff.top - parentOffset.top 78 | } 79 | }; 80 | _draggablesForElements[cid] = id; 81 | } 82 | _oneLevel(p.childNodes[i]); 83 | } 84 | } 85 | } 86 | }; 87 | 88 | _oneLevel(el); 89 | }; 90 | 91 | // refresh the offsets for child elements of this element. 92 | this.updateOffsets = function(elId) { 93 | var jpcl = jsPlumb.CurrentLibrary, 94 | el = jpcl.getElementObject(elId), 95 | domEl = jpcl.getDOMElement(el), 96 | id = _currentInstance.getId(domEl), 97 | children = _delements[id], 98 | parentOffset = jpcl.getOffset(el); 99 | 100 | if (children) { 101 | for (var i in children) { 102 | var cel = jpcl.getElementObject(i), 103 | cOff = jpcl.getOffset(cel); 104 | 105 | _delements[id][i] = { 106 | id:i, 107 | offset:{ 108 | left:cOff.left - parentOffset.left, 109 | top:cOff.top - parentOffset.top 110 | } 111 | }; 112 | _draggablesForElements[i] = id; 113 | } 114 | } 115 | }; 116 | 117 | /** 118 | notification that an endpoint was added to the given el. we go up from that el's parent 119 | node, looking for a parent that has been registered as a draggable. if we find one, we add this 120 | el to that parent's list of elements to update on drag (if it is not there already) 121 | */ 122 | this.endpointAdded = function(el) { 123 | var jpcl = jsPlumb.CurrentLibrary, b = document.body, id = _currentInstance.getId(el), 124 | c = jpcl.getElementObject(el), 125 | cLoc = jsPlumb.CurrentLibrary.getOffset(c), 126 | p = el.parentNode, done = p == b; 127 | 128 | _elementsWithEndpoints[id] = _elementsWithEndpoints[id] ? _elementsWithEndpoints[id] + 1 : 1; 129 | 130 | while (p != null && p != b) { 131 | var pid = _currentInstance.getId(p, null, true); 132 | if (pid && _draggables[pid]) { 133 | var idx = -1, pEl = jpcl.getElementObject(p), pLoc = jpcl.getOffset(pEl); 134 | 135 | if (_delements[pid][id] == null) { 136 | _delements[pid][id] = { 137 | id:id, 138 | offset:{ 139 | left:cLoc.left - pLoc.left, 140 | top:cLoc.top - pLoc.top 141 | } 142 | }; 143 | _draggablesForElements[id] = pid; 144 | } 145 | break; 146 | } 147 | p = p.parentNode; 148 | } 149 | }; 150 | 151 | this.endpointDeleted = function(endpoint) { 152 | if (_elementsWithEndpoints[endpoint.elementId]) { 153 | _elementsWithEndpoints[endpoint.elementId]--; 154 | if (_elementsWithEndpoints[endpoint.elementId] <= 0) { 155 | for (var i in _delements) { 156 | if (_delements[i]) { 157 | delete _delements[i][endpoint.elementId]; 158 | delete _draggablesForElements[endpoint.elementId]; 159 | } 160 | } 161 | } 162 | } 163 | }; 164 | 165 | this.changeId = function(oldId, newId) { 166 | _delements[newId] = _delements[oldId]; 167 | _delements[oldId] = {}; 168 | _draggablesForElements[newId] = _draggablesForElements[oldId]; 169 | _draggablesForElements[oldId] = null; 170 | }; 171 | 172 | this.getElementsForDraggable = function(id) { 173 | return _delements[id]; 174 | }; 175 | 176 | this.elementRemoved = function(elementId) { 177 | var elId = _draggablesForElements[elementId]; 178 | if (elId) { 179 | delete _delements[elId][elementId]; 180 | delete _draggablesForElements[elementId]; 181 | } 182 | }; 183 | 184 | this.reset = function() { 185 | _draggables = {}; 186 | _dlist = []; 187 | _delements = {}; 188 | _elementsWithEndpoints = {}; 189 | }; 190 | 191 | // 192 | // notification drag ended. from 1.5.5 we check automatically if need to update some 193 | // ancestor's offsets. 194 | // 195 | this.dragEnded = function(el) { 196 | var id = _currentInstance.getId(el), 197 | ancestor = _draggablesForElements[id]; 198 | 199 | if (ancestor) this.updateOffsets(ancestor); 200 | }; 201 | 202 | this.setParent = function(el, elId, p, pId) { 203 | var current = _draggablesForElements[elId]; 204 | if (current) { 205 | if (!_delements[pId]) 206 | _delements[pId] = {}; 207 | _delements[pId][elId] = _delements[current][elId]; 208 | delete _delements[current][elId]; 209 | var pLoc = jsPlumb.CurrentLibrary.getOffset(p), 210 | cLoc = jsPlumb.CurrentLibrary.getOffset(el); 211 | _delements[pId][elId].offset = { 212 | left:cLoc.left - pLoc.left, 213 | top:cLoc.top - pLoc.top 214 | }; 215 | _draggablesForElements[elId] = pId; 216 | } 217 | }; 218 | 219 | }; 220 | 221 | // for those browsers that dont have it. they still don't have it! but at least they won't crash. 222 | if (!window.console) 223 | window.console = { time:function(){}, timeEnd:function(){}, group:function(){}, groupEnd:function(){}, log:function(){} }; 224 | 225 | window.jsPlumbAdapter = { 226 | 227 | headless:false, 228 | 229 | getAttribute:function(el, attName) { 230 | return el.getAttribute(attName); 231 | }, 232 | 233 | setAttribute:function(el, a, v) { 234 | el.setAttribute(a, v); 235 | }, 236 | 237 | appendToRoot : function(node) { 238 | document.body.appendChild(node); 239 | }, 240 | getRenderModes : function() { 241 | return [ "canvas", "svg", "vml" ]; 242 | }, 243 | isRenderModeAvailable : function(m) { 244 | return { 245 | "canvas":canvasAvailable, 246 | "svg":svgAvailable, 247 | "vml":vmlAvailable() 248 | }[m]; 249 | }, 250 | getDragManager : function(_jsPlumb) { 251 | return new DragManager(_jsPlumb); 252 | }, 253 | setRenderMode : function(mode) { 254 | var renderMode; 255 | 256 | if (mode) { 257 | mode = mode.toLowerCase(); 258 | 259 | var canvasAvailable = this.isRenderModeAvailable("canvas"), 260 | svgAvailable = this.isRenderModeAvailable("svg"), 261 | vmlAvailable = this.isRenderModeAvailable("vml"); 262 | 263 | // now test we actually have the capability to do this. 264 | if (mode === "svg") { 265 | if (svgAvailable) renderMode = "svg"; 266 | else if (canvasAvailable) renderMode = "canvas"; 267 | else if (vmlAvailable) renderMode = "vml"; 268 | } 269 | else if (mode === "canvas" && canvasAvailable) renderMode = "canvas"; 270 | else if (vmlAvailable) renderMode = "vml"; 271 | } 272 | 273 | return renderMode; 274 | } 275 | }; 276 | 277 | 278 | /* 279 | 280 | addClass: 281 | 282 | add: function( elem, classNames ) { 283 | jQuery.each((classNames || "").split(/\s+/), function(i, className){ 284 | if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) 285 | elem.className += (elem.className ? " " : "") + className; 286 | }); 287 | }, 288 | */ 289 | 290 | /* 291 | 292 | removeClass: 293 | 294 | elem.className = classNames !== undefined ? 295 | jQuery.grep(elem.className.split(/\s+/), function(className){ 296 | return !jQuery.className.has( classNames, className ); 297 | }).join(" ") : 298 | 299 | */ 300 | 301 | })(); -------------------------------------------------------------------------------- /js/jsPlumb/src/drag.js: -------------------------------------------------------------------------------- 1 | /* 2 | * this is experimental and probably will not be used. solutions exist for most libraries. but of course if 3 | * i want to support multiple scopes at some stage then i will have to do dragging inside jsPlumb. 4 | */ 5 | ;(function() { 6 | 7 | window.jsPlumbDrag = function(_jsPlumb) { 8 | 9 | var ta = new TouchAdapter(); 10 | 11 | this.draggable = function(selector) { 12 | var el, elId, da = [], elo, d = false, 13 | isInSelector = function(el) { 14 | if (typeof selector == "string") 15 | return selector === _jsPlumb.getId(el); 16 | 17 | for (var i = 0; i < selector.length; i++) { 18 | var _sel = jsPlumb.CurrentLibrary.getDOMElement(selector[i]); 19 | if (_sel == el) return true; 20 | } 21 | return false; 22 | }; 23 | 24 | ta.bind(document, "mousedown", function(e) { 25 | var target = e.target || e.srcElement; 26 | if (isInSelector(target)) { 27 | el = jsPlumb.CurrentLibrary.getElementObject(target); 28 | elId = _jsPlumb.getId(el); 29 | elo = jsPlumb.CurrentLibrary.getOffset(el); 30 | da = [e.pageX, e.pageY]; 31 | d = true; 32 | } 33 | }); 34 | 35 | ta.bind(document, "mousemove", function(e) { 36 | if (d) { 37 | var dx = e.pageX - da[0], 38 | dy = e.pageY - da[1]; 39 | 40 | jsPlumb.CurrentLibrary.setOffset(el, { 41 | left:elo.left + dx, 42 | top:elo.top + dy 43 | }); 44 | _jsPlumb.repaint(elId); 45 | e.preventDefault(); 46 | e.stopPropagation(); 47 | } 48 | }); 49 | ta.bind(document, "mouseup", function(e) { 50 | el = null; 51 | d = false; 52 | }); 53 | }; 54 | 55 | var isIOS = ((/iphone|ipad/gi).test(navigator.appVersion)); 56 | if (isIOS) 57 | _jsPlumb.draggable = this.draggable; 58 | 59 | }; 60 | 61 | })(); -------------------------------------------------------------------------------- /js/jsPlumb/src/jquery.jsPlumb.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jsPlumb 3 | * 4 | * Title:jsPlumb 1.5.5 5 | * 6 | * Provides a way to visually connect elements on an HTML page, using either SVG, Canvas 7 | * elements, or VML. 8 | * 9 | * This file contains the jQuery adapter. 10 | * 11 | * Copyright (c) 2010 - 2013 Simon Porritt (http://jsplumb.org) 12 | * 13 | * http://jsplumb.org 14 | * http://github.com/sporritt/jsplumb 15 | * http://code.google.com/p/jsplumb 16 | * 17 | * Dual licensed under the MIT and GPL2 licenses. 18 | */ 19 | /* 20 | * the library specific functions, such as find offset, get id, get attribute, extend etc. 21 | * the full list is: 22 | * 23 | * addClass adds a class to the given element 24 | * animate calls the underlying library's animate functionality 25 | * appendElement appends a child element to a parent element. 26 | * bind binds some event to an element 27 | * dragEvents a dictionary of event names 28 | * extend extend some js object with another. probably not overly necessary; jsPlumb could just do this internally. 29 | * getDragObject gets the object that is being dragged, by extracting it from the arguments passed to a drag callback 30 | * getDragScope gets the drag scope for a given element. 31 | * getDropScope gets the drop scope for a given element. 32 | * getElementObject turns an id or dom element into an element object of the underlying library's type. 33 | * getOffset gets an element's offset 34 | * getOriginalEvent gets the original browser event from some wrapper event 35 | * getPageXY gets the page event's xy location. 36 | * getParent gets the parent of some element. 37 | * getScrollLeft gets an element's scroll left. TODO: is this actually used? will it be? 38 | * getScrollTop gets an element's scroll top. TODO: is this actually used? will it be? 39 | * getSize gets an element's size. 40 | * getUIPosition gets the position of some element that is currently being dragged, by extracting it from the arguments passed to a drag callback. 41 | * hasClass returns whether or not the given element has the given class. 42 | * initDraggable initializes an element to be draggable 43 | * initDroppable initializes an element to be droppable 44 | * isDragSupported returns whether or not drag is supported for some element. 45 | * isDropSupported returns whether or not drop is supported for some element. 46 | * removeClass removes a class from a given element. 47 | * removeElement removes some element completely from the DOM. 48 | * setDragFilter sets a filter for some element that indicates areas of the element that should not respond to dragging. 49 | * setDraggable sets whether or not some element should be draggable. 50 | * setDragScope sets the drag scope for a given element. 51 | * setOffset sets the offset of some element. 52 | * trigger triggers some event on an element. 53 | * unbind unbinds some listener from some element. 54 | */ 55 | (function($) { 56 | 57 | //var getBoundingClientRectSupported = "getBoundingClientRect" in document.documentElement; 58 | 59 | var _getElementObject = function(el) { 60 | return typeof(el) == "string" ? $("#" + el) : $(el); 61 | }; 62 | 63 | jsPlumb.CurrentLibrary = { 64 | 65 | /** 66 | * adds the given class to the element object. 67 | */ 68 | addClass : function(el, clazz) { 69 | el = _getElementObject(el); 70 | try { 71 | if (el[0].className.constructor == SVGAnimatedString) { 72 | jsPlumbUtil.svg.addClass(el[0], clazz); 73 | } 74 | } 75 | catch (e) { 76 | // SVGAnimatedString not supported; no problem. 77 | } 78 | try { 79 | el.addClass(clazz); 80 | } 81 | catch (e) { 82 | // you probably have jQuery 1.9 and Firefox. 83 | } 84 | }, 85 | 86 | /** 87 | * animates the given element. 88 | */ 89 | animate : function(el, properties, options) { 90 | el.animate(properties, options); 91 | }, 92 | 93 | /** 94 | * appends the given child to the given parent. 95 | 96 | TODO: REMOVE! 97 | 98 | */ 99 | appendElement : function(child, parent) { 100 | _getElementObject(parent).append(child); 101 | }, 102 | 103 | /** 104 | * executes an ajax call. 105 | */ 106 | ajax : function(params) { 107 | params = params || {}; 108 | params.type = params.type || "get"; 109 | $.ajax(params); 110 | }, 111 | 112 | /** 113 | * event binding wrapper. it just so happens that jQuery uses 'bind' also. yui3, for example, 114 | * uses 'on'. 115 | */ 116 | bind : function(el, event, callback) { 117 | el = _getElementObject(el); 118 | el.bind(event, callback); 119 | }, 120 | 121 | destroyDraggable : function(el) { 122 | if ($(el).data("draggable")) 123 | $(el).draggable("destroy"); 124 | }, 125 | 126 | destroyDroppable : function(el) { 127 | if ($(el).data("droppable")) 128 | $(el).droppable("destroy"); 129 | }, 130 | 131 | /** 132 | * mapping of drag events for jQuery 133 | */ 134 | dragEvents : { 135 | 'start':'start', 'stop':'stop', 'drag':'drag', 'step':'step', 136 | 'over':'over', 'out':'out', 'drop':'drop', 'complete':'complete' 137 | }, 138 | 139 | /** 140 | * wrapper around the library's 'extend' functionality (which it hopefully has. 141 | * otherwise you'll have to do it yourself). perhaps jsPlumb could do this for you 142 | * instead. it's not like its hard. 143 | */ 144 | extend : function(o1, o2) { 145 | return $.extend(o1, o2); 146 | }, 147 | 148 | getClientXY : function(eventObject) { 149 | return [eventObject.clientX, eventObject.clientY]; 150 | }, 151 | 152 | /** 153 | * takes the args passed to an event function and returns you an object representing that which is being dragged. 154 | */ 155 | getDragObject : function(eventArgs) { 156 | return eventArgs[1].draggable || eventArgs[1].helper; 157 | }, 158 | 159 | getDragScope : function(el) { 160 | return $(el).draggable("option", "scope"); 161 | }, 162 | 163 | getDropEvent : function(args) { 164 | return args[0]; 165 | }, 166 | 167 | getDropScope : function(el) { 168 | return $(el).droppable("option", "scope"); 169 | }, 170 | 171 | /** 172 | * gets a DOM element from the given input, which might be a string (in which case we just do document.getElementById), 173 | * a selector (in which case we return el[0]), or a DOM element already (we assume this if it's not either of the other 174 | * two cases). this is the opposite of getElementObject below. 175 | */ 176 | getDOMElement : function(el) { 177 | if (el == null) return null; 178 | if (typeof(el) == "string") return document.getElementById(el); 179 | else if (el.context || el.length != null) return el[0]; 180 | else return el; 181 | }, 182 | 183 | /** 184 | * gets an "element object" from the given input. this means an object that is used by the 185 | * underlying library on which jsPlumb is running. 'el' may already be one of these objects, 186 | * in which case it is returned as-is. otherwise, 'el' is a String, the library's lookup 187 | * function is used to find the element, using the given String as the element's id. 188 | * 189 | */ 190 | getElementObject : _getElementObject, 191 | 192 | /** 193 | * gets the offset for the element object. this should return a js object like this: 194 | * 195 | * { left:xxx, top: xxx } 196 | */ 197 | getOffset : function(el) { 198 | return el.offset(); 199 | }, 200 | 201 | getOriginalEvent : function(e) { 202 | return e.originalEvent; 203 | }, 204 | 205 | getPageXY : function(eventObject) { 206 | return [eventObject.pageX, eventObject.pageY]; 207 | }, 208 | 209 | getParent : function(el) { 210 | return _getElementObject(el).parent(); 211 | }, 212 | 213 | getScrollLeft : function(el) { 214 | return el.scrollLeft(); 215 | }, 216 | 217 | getScrollTop : function(el) { 218 | return el.scrollTop(); 219 | }, 220 | 221 | getSelector : function(context, spec) { 222 | if (arguments.length == 2) 223 | return _getElementObject(context).find(spec); 224 | else 225 | return $(context); 226 | }, 227 | 228 | /** 229 | * gets the size for the element object, in an array : [ width, height ]. 230 | */ 231 | getSize : function(el) { 232 | el = $(el); 233 | return [el.outerWidth(), el.outerHeight()]; 234 | }, 235 | 236 | getTagName : function(el) { 237 | var e = _getElementObject(el); 238 | return e.length > 0 ? e[0].tagName : null; 239 | }, 240 | 241 | /** 242 | * takes the args passed to an event function and returns you an object that gives the 243 | * position of the object being moved, as a js object with the same params as the result of 244 | * getOffset, ie: { left: xxx, top: xxx }. 245 | * 246 | * different libraries have different signatures for their event callbacks. 247 | * see getDragObject as well 248 | */ 249 | getUIPosition : function(eventArgs, zoom) { 250 | 251 | zoom = zoom || 1; 252 | // this code is a workaround for the case that the element being dragged has a margin set on it. jquery UI passes 253 | // in the wrong offset if the element has a margin (it doesn't take the margin into account). the getBoundingClientRect 254 | // method, which is in pretty much all browsers now, reports the right numbers. but it introduces a noticeable lag, which 255 | // i don't like. 256 | 257 | /*if ( getBoundingClientRectSupported ) { 258 | var r = eventArgs[1].helper[0].getBoundingClientRect(); 259 | return { left : r.left, top: r.top }; 260 | } else {*/ 261 | if (eventArgs.length == 1) { 262 | ret = { left: eventArgs[0].pageX, top:eventArgs[0].pageY }; 263 | } 264 | else { 265 | var ui = eventArgs[1], 266 | _offset = ui.offset; 267 | 268 | ret = _offset || ui.absolutePosition; 269 | 270 | // adjust ui position to account for zoom, because jquery ui does not do this. 271 | ui.position.left /= zoom; 272 | ui.position.top /= zoom; 273 | } 274 | return { left:ret.left / zoom, top: ret.top / zoom }; 275 | }, 276 | 277 | hasClass : function(el, clazz) { 278 | return el.hasClass(clazz); 279 | }, 280 | 281 | /** 282 | * initialises the given element to be draggable. 283 | */ 284 | initDraggable : function(el, options, isPlumbedComponent, _jsPlumb) { 285 | options = options || {}; 286 | el = $(el); 287 | 288 | options.start = jsPlumbUtil.wrap(options.start, function() { 289 | $("body").addClass(_jsPlumb.dragSelectClass); 290 | }, false); 291 | 292 | options.stop = jsPlumbUtil.wrap(options.stop, function() { 293 | $("body").removeClass(_jsPlumb.dragSelectClass); 294 | }); 295 | 296 | // remove helper directive if present and no override 297 | if (!options.doNotRemoveHelper) 298 | options.helper = null; 299 | if (isPlumbedComponent) 300 | options.scope = options.scope || jsPlumb.Defaults.Scope; 301 | el.draggable(options); 302 | }, 303 | 304 | /** 305 | * initialises the given element to be droppable. 306 | */ 307 | initDroppable : function(el, options) { 308 | options.scope = options.scope || jsPlumb.Defaults.Scope; 309 | $(el).droppable(options); 310 | }, 311 | 312 | isAlreadyDraggable : function(el) { 313 | return $(el).hasClass("ui-draggable"); 314 | }, 315 | 316 | /** 317 | * returns whether or not drag is supported (by the library, not whether or not it is disabled) for the given element. 318 | */ 319 | isDragSupported : function(el, options) { 320 | return $(el).draggable; 321 | }, 322 | 323 | /** 324 | * returns whether or not drop is supported (by the library, not whether or not it is disabled) for the given element. 325 | */ 326 | isDropSupported : function(el, options) { 327 | return $(el).droppable; 328 | }, 329 | 330 | /** 331 | * removes the given class from the element object. 332 | */ 333 | removeClass : function(el, clazz) { 334 | el = _getElementObject(el); 335 | try { 336 | if (el[0].className.constructor == SVGAnimatedString) { 337 | jsPlumbUtil.svg.removeClass(el[0], clazz); 338 | return; 339 | } 340 | } 341 | catch (e) { 342 | // SVGAnimatedString not supported; no problem. 343 | } 344 | el.removeClass(clazz); 345 | }, 346 | 347 | removeElement : function(element) { 348 | _getElementObject(element).remove(); 349 | }, 350 | 351 | setDragFilter : function(el, filter) { 352 | if (jsPlumb.CurrentLibrary.isAlreadyDraggable(el)) 353 | el.draggable("option", "cancel", filter); 354 | }, 355 | 356 | setDraggable : function(el, draggable) { 357 | el.draggable("option", "disabled", !draggable); 358 | }, 359 | 360 | setDragScope : function(el, scope) { 361 | el.draggable("option", "scope", scope); 362 | }, 363 | 364 | setOffset : function(el, o) { 365 | _getElementObject(el).offset(o); 366 | }, 367 | 368 | /** 369 | * note that jquery ignores the name of the event you wanted to trigger, and figures it out for itself. 370 | * the other libraries do not. yui, in fact, cannot even pass an original event. we have to pull out stuff 371 | * from the originalEvent to put in an options object for YUI. 372 | * @param el 373 | * @param event 374 | * @param originalEvent 375 | */ 376 | trigger : function(el, event, originalEvent) { 377 | var h = jQuery._data(_getElementObject(el)[0], "handle"); 378 | h(originalEvent); 379 | }, 380 | 381 | unbind : function(el, event, callback) { 382 | el = _getElementObject(el); 383 | el.unbind(event, callback); 384 | } 385 | }; 386 | 387 | $(document).ready(jsPlumb.init); 388 | 389 | })(jQuery); 390 | 391 | -------------------------------------------------------------------------------- /js/jsPlumb/src/overlays-guidelines.js: -------------------------------------------------------------------------------- 1 | // this is really just a test overlay, so its undocumented and doesnt take any parameters. but i was loth to delete it. 2 | jsPlumb.Overlays.GuideLines = function() { 3 | var self = this; 4 | self.length = 50; 5 | self.lineWidth = 5; 6 | this.type = "GuideLines"; 7 | AbstractOverlay.apply(this, arguments); 8 | jsPlumb.jsPlumbUIComponent.apply(this, arguments); 9 | this.draw = function(connector, currentConnectionPaintStyle, connectorDimensions) { 10 | 11 | var head = connector.pointAlongPathFrom(self.loc, self.length / 2), 12 | mid = connector.pointOnPath(self.loc), 13 | tail = jsPlumbGeom.pointOnLine(head, mid, self.length), 14 | tailLine = jsPlumbGeom.perpendicularLineTo(head, tail, 40), 15 | headLine = jsPlumbGeom.perpendicularLineTo(tail, head, 20); 16 | 17 | self.paint(connector, [head, tail, tailLine, headLine], self.lineWidth, "red", null, connectorDimensions); 18 | 19 | return [Math.min(head.x, tail.x), Math.min(head.y, tail.y), Math.max(head.x, tail.x), Math.max(head.y,tail.y)]; 20 | }; 21 | 22 | this.computeMaxSize = function() { return 50; }; 23 | 24 | this.cleanup = function() { }; // nothing to clean up for GuideLines 25 | }; 26 | 27 | // a test 28 | jsPlumb.Overlays.svg.GuideLines = function() { 29 | var path = null, self = this, path2 = null, p1_1, p1_2; 30 | jsPlumb.Overlays.GuideLines.apply(this, arguments); 31 | this.paint = function(connector, d, lineWidth, strokeStyle, fillStyle) { 32 | if (path == null) { 33 | path = _node("path"); 34 | connector.svg.appendChild(path); 35 | self.attachListeners(path, connector); 36 | self.attachListeners(path, self); 37 | 38 | p1_1 = _node("path"); 39 | connector.svg.appendChild(p1_1); 40 | self.attachListeners(p1_1, connector); 41 | self.attachListeners(p1_1, self); 42 | 43 | p1_2 = _node("path"); 44 | connector.svg.appendChild(p1_2); 45 | self.attachListeners(p1_2, connector); 46 | self.attachListeners(p1_2, self); 47 | 48 | } 49 | 50 | _attr(path, { 51 | "d" : makePath(d[0], d[1]), 52 | stroke : "red", 53 | fill : null 54 | }); 55 | 56 | _attr(p1_1, { 57 | "d" : makePath(d[2][0], d[2][1]), 58 | stroke : "blue", 59 | fill : null 60 | }); 61 | 62 | _attr(p1_2, { 63 | "d" : makePath(d[3][0], d[3][1]), 64 | stroke : "green", 65 | fill : null 66 | }); 67 | }; 68 | 69 | var makePath = function(d1, d2) { 70 | return "M " + d1.x + "," + d1.y + 71 | " L" + d2.x + "," + d2.y; 72 | }; 73 | }; -------------------------------------------------------------------------------- /js/lod/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LODmilla-frontend 3 | * 4 | * https://github.com/dsd-sztaki-hu/LODmilla-frontend 5 | * 6 | * Copyright (c) 2013 Sandor Turbucz, Zoltan Toth, Andras Micsik - MTA SZTAKI DSD 7 | * 8 | */ 9 | 10 | $(document).ready(function() { 11 | jsPlumb.ready(function() { 12 | 13 | jsPlumbInstance = jsPlumb.getInstance({ 14 | Container:"graph", 15 | Connector: [ Profile.connectorType, { stub: Profile.connectorStub, gap: Profile.connectorGap } ], 16 | ConnectionsDetachable: true, 17 | EndpointHoverStyle: { fillStyle: "#f00"}, 18 | 19 | hoverPaintStyle: { fillStyle: "#f00"}, 20 | ReattachConnections : true, 21 | DragOptions: { cursor: "crosshair" }, 22 | DropOptions: {}, 23 | Scope : "jsPlumb_DefaultScope", 24 | ConnectionOverlays : [ 25 | [ "Label", { 26 | label: Profile.defaultConnectionURI, 27 | cssClass: "connectionBox label opacityItem", 28 | location: Profile.connectionLabelLocation 29 | }], 30 | ["PlainArrow", { 31 | location: Profile.connectionArrowLocation, 32 | width: Profile.connectionArrowWidth, 33 | length: Profile.connectionArrowLength, 34 | direction: 1 35 | // foldback:0.2 36 | // id:"myArrow" 37 | }] 38 | ] 39 | , 40 | // Anchor: [ "Assign", { 41 | // position:"Fixed" 42 | // }] 43 | // Anchor: [ "Assign", { 44 | // position:"Grid", 45 | // grid:[3,3] 46 | // }] 47 | // Anchor: [ 'Top', 'Right', 'Bottom', 'Left', 'TopRight','BottomRight','TopLeft','BottomLeft'] // faster, but a bit different 48 | // TODO set back to Continuous 49 | Anchor: "Continuous" 50 | // Anchor: "AutoDefault" 51 | // Anchor: [ 'Top', 'Right', 'Bottom', 'Left'] 52 | // anchor:[ "Perimeter", { shape:"Square", anchorCount:150 }] 53 | }); 54 | 55 | jsPlumbInstance.registerConnectionTypes({ 56 | "basicConnection": { 57 | paintStyle: { 58 | strokeStyle: Profile.defaultConnectionsColor, lineWidth: 2 59 | // outlineColor:"blue", outlineWidth:1 60 | }, 61 | hoverPaintStyle: {strokeStyle: Profile.highlightedConnectionsColor, lineWidth: 3}, 62 | ConnectorZIndex: 100 63 | }, 64 | "selectedConnection":{ 65 | paintStyle: {strokeStyle: Profile.defaultConnectionsColor, lineWidth: 4}, 66 | hoverPaintStyle: {strokeStyle: Profile.highlightedConnectionsColor, lineWidth: 5}, 67 | ConnectorZIndex: 101 68 | } 69 | }); 70 | jsPlumbInstance.registerEndpointTypes({ 71 | "basicEndpoint":{ 72 | paintStyle:{fillStyle: Profile.highlightedConnectionsColor} 73 | }, 74 | "selectedEndpoint":{ 75 | paintStyle:{fillStyle:Profile.highlightedConnectionsColor} 76 | } 77 | }); 78 | 79 | Graph.init($('#main')); 80 | Sidemenu.init(Graph.canvas.parent()); 81 | Profile.init(); 82 | 83 | addCanvasHandlers(); 84 | addPaletteHandlers(); 85 | addBottomMenuHandlers(); 86 | addNodeHandlers(); 87 | 88 | 89 | $("#footerWrapper").position({my: "right bottom", at: "right-50 bottom-8", of: window}); 90 | $(window).resize(function() { 91 | $("#footerWrapper").position({my: "right bottom", at: "right-50 bottom-8", of: window}); 92 | }); 93 | 94 | 95 | if (Profile.QueryString.id !== undefined) { 96 | var undoActionLabel = 'action_httpParam_loadGraph'; 97 | BackendCommunicator.load(Profile.QueryString.id, null, null, Graph.load, undoActionLabel); 98 | } 99 | if (Profile.QueryString.url !== undefined) { 100 | // var resource_id = decodeURIComponent(Profile.QueryString.url); 101 | var resource_id = Profile.QueryString.url; 102 | Graph.addNode(resource_id,false,false,false,false,false); 103 | var undoActionLabel = 'action_httpParam_loadUri'; 104 | var nodeList = [{resource_id:resource_id, action:'added',highlighted:false}]; 105 | Graph.logUndoAction(undoActionLabel, nodeList); 106 | } 107 | 108 | $(".fancybox").fancybox({ 109 | 'type':'image', 110 | beforeLoad: function() { 111 | return fancyBoxOpen; 112 | } 113 | }); 114 | 115 | Helper.loadScreen = document.getElementById('loadScreen'); 116 | Helper.loadText = document.getElementById('loadScreenText'); 117 | 118 | resetInspector(); 119 | }); 120 | 121 | 122 | }); 123 | 124 | document.addEventListener( 125 | "keydown", 126 | function(event) 127 | { 128 | if (event.keyCode === 17) 129 | { 130 | document.body.style.cursor = 'crosshair'; 131 | } 132 | }, 133 | false 134 | ); 135 | 136 | document.addEventListener( 137 | "keydown", 138 | function(event) 139 | { 140 | if (event.keyCode === 18) 141 | { 142 | document.body.style.cursor = 'vertical-text'; 143 | } 144 | }, 145 | false 146 | ); 147 | 148 | document.addEventListener( 149 | "keyup", 150 | function(event) 151 | { 152 | if (event.keyCode === 17 || event.keyCode === 18) 153 | { 154 | document.body.style.cursor = 'default'; 155 | } 156 | }, 157 | false 158 | ); 159 | 160 | 161 | -------------------------------------------------------------------------------- /js/lod/connection.class.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LODmilla-frontend 3 | * 4 | * https://github.com/dsd-sztaki-hu/LODmilla-frontend 5 | * 6 | * Copyright (c) 2013 Sandor Turbucz, Zoltan Toth, Andras Micsik - MTA SZTAKI DSD 7 | * 8 | */ 9 | 10 | /* 11 | * Class:Connection 12 | */ 13 | var Connection = function(target, connectionUri, direction, endpointLabel) { 14 | this.target = target; 15 | this.connectionUri = connectionUri; 16 | 17 | this.direction = direction; 18 | this.endpointLabel = endpointLabel; 19 | 20 | this.getConnectionLabelShort = function(){ 21 | var label = this.connectionUri; 22 | label = Profile.getPropertyLabel(this.connectionUri); 23 | label = Helper.getCapitalizedString(label); 24 | return label; 25 | }; 26 | }; -------------------------------------------------------------------------------- /js/lod/export.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Attila Gyorok on 2014.07.23.. 3 | * Source: http://jsfiddle.net/hybrid13i/JXrwM/, http://jsfiddle.net/sturtevant/AZFvQ/ 4 | */ 5 | 6 | function getColor(type) 7 | { 8 | if (type == "work") return "#feeacb"; 9 | if (type == "group") return "#e5ecf1"; 10 | return "#e0f5d6"; 11 | } 12 | 13 | function exportToDot() { 14 | 15 | var dot = ''; 16 | dot += "digraph " + $("#graph_name").val() + "{\r\n" 17 | $.each(Graph.nodes, function(index, node) { 18 | dot += '\"' + node.resource_id + "\"[label=\"" + node.label 19 | + "\" pos=\"" + node.left + "," + node.top + "!\"" 20 | + " fillcolor=\"" + getColor(node.type) + "\"" 21 | + " shape=box style=filled" 22 | + "]\n"; 23 | }); 24 | var conns = jsPlumbInstance.getAllConnections(); 25 | $.each(conns, function() { 26 | var source = $(this.source).attr('uri'); 27 | var target = $(this.target).attr('uri'); 28 | var overlay = this.getOverlay("label"); 29 | dot += '\"' + source +'\"->' + '\"' + target + '\"' + '[label=\"' + overlay.label + '\"]\n'; 30 | }); 31 | 32 | dot += "}" 33 | 34 | //Generate a file name 35 | var fileName = "LODmilla_graph"; 36 | 37 | //Initialize file format you want csv or xls 38 | var uri = 'data:text;charset=utf-8,' + escape(dot); 39 | 40 | // Now the little tricky part. 41 | // you can use either>> window.open(uri); 42 | // but this will not work in some browsers 43 | // or you will not get the correct file extension 44 | 45 | //this trick will generate a temp tag 46 | var link = document.createElement("a"); 47 | link.href = uri; 48 | 49 | //set the visibility hidden so it will not effect on your web-layout 50 | link.style = "visibility:hidden"; 51 | link.download = fileName + ".gv"; 52 | 53 | //this part will append the anchor tag and remove it after automatic click 54 | document.body.appendChild(link); 55 | link.click(); 56 | document.body.removeChild(link); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /js/lod/helper.class.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LODmilla-frontend 3 | * 4 | * https://github.com/dsd-sztaki-hu/LODmilla-frontend 5 | * 6 | * Copyright (c) 2013 Sandor Turbucz, Zoltan Toth - MTA SZTAKI DSD 7 | * 8 | */ 9 | 10 | /** 11 | * Created by turbo on 2014.04.30.. 12 | */ 13 | var Helper = new function(){ 14 | 15 | this.isLoadScreenOpen = false; 16 | this.loadScreen; 17 | this.loadText; 18 | 19 | this.getCapitalizedString = function(str) { 20 | return str.charAt(0).toUpperCase() + str.slice(1); 21 | }; 22 | 23 | this.truncateString = function(str, maxlen) { 24 | if (str && str.length > maxlen) { 25 | str = str.substring(0, maxlen) + '..'; 26 | } 27 | return str; 28 | }; 29 | 30 | this.getEndpointLabelOrUriEnd = function(item, direction) { 31 | var label = decodeURIComponent(item[direction].value); 32 | if (item.label && item.label.value) { 33 | label = item.label.value; 34 | } 35 | else { 36 | label = this.getShortTypeFromURL(label); 37 | // label = label.replace(/\/+$/, "").split('/'); 38 | // label = label[(label.length) - 1]; 39 | } 40 | return label; 41 | }; 42 | 43 | this.getShortTypeFromURL = function(node_uri) { 44 | var node_uri_orig = node_uri; 45 | while (node_uri.indexOf('/') > -1) { 46 | node_uri = node_uri.substring(node_uri.indexOf('/') + 1); 47 | } 48 | while (node_uri.indexOf('#') > -1) { 49 | node_uri = node_uri.substring(node_uri.indexOf('#') + 1); 50 | } 51 | // TODO: ha nincs semmi az utolso / vagy # utan, akkor valamit adjon vissza, jelenleg akkor az egesz URLt 52 | if (!node_uri || node_uri === "") 53 | return node_uri_orig; 54 | else 55 | return node_uri; 56 | }; 57 | 58 | this.getLodServerBaseUrl = function(uri) { 59 | var temp = uri.replace('http://', ''); 60 | return 'http://' + temp.substring(0, temp.indexOf('/')); 61 | }; 62 | 63 | this.getDictionaryListSorted = function(dictionaryList){ 64 | var sorted = []; 65 | for (var prop in dictionaryList){ 66 | if (dictionaryList.hasOwnProperty(prop)){ 67 | sorted.push({key: dictionaryList[prop], value: prop}); 68 | } 69 | } 70 | sorted.sort(function(a, b){ 71 | var labelA = a.key.toLowerCase(), labelB = b.key.toLowerCase(); 72 | if (labelA < labelB) return -1; 73 | if (labelA > labelB) return 1; 74 | return 0; 75 | }); 76 | return sorted; 77 | }; 78 | 79 | this.alertDialog = function(title, text) { 80 | if ($("#alert-dialog").length) { 81 | return; 82 | } 83 | $('#main').append('

    ' + text + '

    '); 84 | $("#alert-dialog").dialog({ 85 | autoOpen: true, 86 | height: 200, 87 | width: 400, 88 | modal: true, 89 | buttons: { 90 | "Close": function() { 91 | $(this).dialog("close"); 92 | } 93 | }, 94 | close: function() { 95 | $(this).remove(); 96 | } 97 | }); 98 | }; 99 | 100 | this.isUrl = function(s) { 101 | var regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ 102 | return regexp.test(s); 103 | } 104 | 105 | this.getImgSrc = function(uri) { 106 | return '' ; 107 | //+ '" style=width:' + Profile.imageWidth + ';height:' + Profile.imageHeight + 108 | //';margin-bottom:32px;position:relative;" />' 109 | } 110 | 111 | this.pushCollImgStr = function(number, array, connectionURI, propertyName, addConnectionBtn) { 112 | array.push("

    ", propertyName, " (",number,") ", addConnectionBtn, "

      "); 113 | } 114 | 115 | this.showLoadScreen = function() 116 | { 117 | if (!this.isLoadScreenOpen) { 118 | this.isLoadScreenOpen = true; 119 | this.loadScreen.style.display = "inherit"; 120 | this.loadText.style.display = "inherit"; 121 | } 122 | } 123 | 124 | this.closeLoadScreen = function() 125 | { 126 | if (this.isLoadScreenOpen) { 127 | this.loadScreen.style.display = "none"; 128 | this.loadText.style.display = "none"; 129 | this.isLoadScreenOpen = false; 130 | } 131 | } 132 | 133 | }; 134 | -------------------------------------------------------------------------------- /js/lod/jsplumb/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Attila Gyorok on 2014.07.29.. 3 | */ 4 | 5 | var resetDrawingCounter = 0, blockResetDrawing = false; 6 | 7 | function repaintNodes() 8 | { 9 | Helper.showLoadScreen(); 10 | setTimeout(delayedRepaintNodes, 10); 11 | } 12 | 13 | function delayedRepaintNodes() 14 | { 15 | var $res; 16 | var $node = [], $child = [], length = 0; 17 | var $tnode; 18 | var i; 19 | // repaintEverything() nem működik megbízhatóan automatikusan kiszámolt anchorral, tudnak a hibáról 20 | // console.time('Repaint all'); 21 | jsPlumbInstance.setSuspendDrawing(false, false); 22 | $res = $('.resourceNodeBox'); 23 | $res.each(function() { 24 | $tnode = $(this); 25 | $node.push($tnode); 26 | $child.push($tnode.children().detach()); 27 | length++; 28 | }); 29 | 30 | i = 0; 31 | $res.each(function() { 32 | jsPlumbInstance.repaint(this); 33 | }); 34 | for (i = 0; i < length; i++) 35 | { 36 | $node[i].append($child[i]); 37 | } 38 | jsPlumbInstance.setSuspendDrawing(false, true); 39 | // console.timeEnd('Repaint all'); 40 | Helper.closeLoadScreen(); 41 | } 42 | 43 | function refreshNodeModelPosition(node, dx, dy) 44 | { 45 | node.left = node.left - dx / Graph.zoomRatio; 46 | node.top = node.top - dy / Graph.zoomRatio; 47 | } 48 | 49 | function refreshNodeVisiblePosition($node, dx, dy) 50 | { 51 | var position = $node.position(); 52 | $node.css('left', position['left'] - dx); 53 | $node.css('top', position['top'] - dy); 54 | } 55 | 56 | function moveNode(event) 57 | { 58 | var $node = $(this); 59 | if ($node.find('.node-highlight').hasClass('opened')) return; 60 | var node = Graph.getNode(this.getAttribute('uri')); 61 | refreshNodeModelPosition(node, mousePositionLeft - event.pageX, mousePositionTop - event.pageY); 62 | } 63 | 64 | function moveNodes(event) 65 | { 66 | var dx = mousePositionLeft - event.pageX; 67 | var dy = mousePositionTop - event.pageY; 68 | 69 | $('.resourceNodeBox').each(function() { 70 | var $node = $(this); 71 | var node = Graph.getNode(this.getAttribute('uri')); 72 | refreshNodeModelPosition(node, dx, dy); 73 | refreshNodeVisiblePosition($node, dx, dy); 74 | }); 75 | mousePositionLeft = event.pageX; 76 | mousePositionTop = event.pageY; 77 | } 78 | 79 | function moveNodesExcept(event, selected, repaint) 80 | { 81 | var dx = mousePositionLeft - event.pageX; 82 | var dy = mousePositionTop - event.pageY; 83 | 84 | $('.resourceNodeBox').each(function() { 85 | var $node = $(this); 86 | if (!$node.find('.node-highlight').hasClass('opened')) return; 87 | var node = Graph.getNode(this.getAttribute('uri')); 88 | 89 | if (node.resource_id == selected) { 90 | refreshNodeModelPosition(node, dx, dy); 91 | } 92 | else 93 | { 94 | refreshNodeModelPosition(node, dx, dy); 95 | refreshNodeVisiblePosition($node, dx, dy); 96 | } 97 | if (repaint) jsPlumbInstance.repaint($node); 98 | }); 99 | mousePositionLeft = event.pageX; 100 | mousePositionTop = event.pageY; 101 | } 102 | 103 | function zoom(ratio, x, y) 104 | { 105 | var slider = $("#zoomSlider"), 106 | sliderValue = $("#zoomSliderValue"); 107 | 108 | if (slider) { 109 | slider.slider("value", ratio); 110 | } 111 | if (sliderValue) { 112 | sliderValue.html("Zoom value: " + ratio); 113 | } 114 | 115 | if (blockResetDrawing) 116 | decideZoom(ratio, x, y); 117 | else 118 | { 119 | jsPlumbInstance.setSuspendDrawing(true); 120 | blockResetDrawing = true; 121 | decideZoom(ratio, x, y); 122 | setTimeout(checkDrawing, 1000); 123 | } 124 | } 125 | 126 | function decideZoom(ratio) 127 | { 128 | resetDrawingCounter++; 129 | var cx = $(document).scrollLeft() + window.screen.width / 2, 130 | cy = $(document).scrollTop() + window.screen.height / 2; 131 | if (ratio > 0.699) 132 | nodeSizeToNormal(); 133 | else 134 | nodeSizeToLabel(); 135 | applyZoom(ratio, cx, cy); 136 | resetDrawingCounter--; 137 | } 138 | 139 | function checkDrawing() 140 | { 141 | if (resetDrawingCounter == 0) { 142 | jsPlumbInstance.setSuspendDrawing(false, false); 143 | repaintNodes(); 144 | blockResetDrawing = false; 145 | } 146 | if (resetDrawingCounter > 0) setTimeout(checkDrawing, 1000); 147 | } 148 | 149 | function applyZoom(ratio, x, y) 150 | { 151 | // console.log('normal: ' + ratio); 152 | $('.resourceNodeBox').each(function() { 153 | var vis_node = $(this); 154 | var node = Graph.getNode(this.getAttribute('uri')); 155 | vis_node.css('left', x + (node.left - x) * ratio); 156 | vis_node.css('top', y + (node.top - y) * ratio); 157 | vis_node.css('width', node.width * ratio); 158 | vis_node.css('height', node.height * ratio); 159 | if (vis_node.hasClass('normalSizeNode')) 160 | vis_node.find('.nodeImage img').css('max-height', 75 * ratio - 36); //perfect 161 | }); 162 | } 163 | 164 | function nodeSizeToNormal() 165 | { 166 | $('.labelSizeNode').each(function() { 167 | var vis_node = $(this); 168 | 169 | vis_node.find('.endpointLink').css('visibility', 'visible'); 170 | vis_node.find('.node-button').css('visibility', 'visible'); 171 | vis_node.find('.node-connection-source').css('visibility', 'visible'); 172 | vis_node.find('.resourceLabel').css('font-size', '12px').css('position', 'relative').css('top','0px') 173 | .css('max-height','30px').css('cursor','auto').unbind('click'); 174 | vis_node.find('.nodeImage').css('visibility', 'visible'); 175 | vis_node.css('padding', '0.5em').css('padding-top', '2em').css('padding-bottom', '1.5em'); 176 | vis_node.removeClass('labelSizeNode'); 177 | vis_node.addClass('normalSizeNode'); 178 | }); 179 | $('.label').css('visibility','visible'); 180 | } 181 | 182 | function nodeSizeToLabel() 183 | { 184 | $('.normalSizeNode').each(function() { 185 | var vis_node = $(this); 186 | vis_node.css('padding', '5px'); 187 | var $img = vis_node.find('.nodeImage'); 188 | $img.css('visibility', 'hidden').css('max-height','0px'); 189 | vis_node.find('.endpointLink').css('visibility', 'hidden'); 190 | vis_node.find('.node-button').css('visibility', 'hidden'); 191 | vis_node.find('.node-connection-source').css('visibility', 'hidden'); 192 | vis_node.find('.resourceLabel').css('position', 'absolute').css('top', '10%') 193 | .css('max-height','90%').css('font-size', '9px').css('cursor','pointer') 194 | .on('click', function(event) { 195 | if (event.ctrlKey || event.altKey) return; 196 | var resource_id = this.parentNode.getAttribute('uri'); 197 | if (Graph.getNode(resource_id).type !== Profile.unloadedNodeType){ 198 | var node = Graph.getNode(this.parentNode.getAttribute('uri')); 199 | if($(this).parent().hasClass('opened')){ 200 | node.vis_closeNode(); 201 | } 202 | else{ 203 | node.vis_openNode(); 204 | } 205 | } 206 | }); 207 | vis_node.removeClass('normalSizeNode'); 208 | vis_node.addClass('labelSizeNode'); 209 | }); 210 | $('.label').css('visibility','hidden'); 211 | } 212 | 213 | function changeActiveTab(targetTabName) 214 | { 215 | if (targetTabName && targetTabName !== '') { 216 | var tabId = $("#nodeOpenedContentTabs ul[role='tablist'] li." + targetTabName).attr('aria-controls'); 217 | 218 | var targetTabId; 219 | try{ 220 | targetTabId = parseInt(tabId.replace("itemtab-", "")); 221 | } 222 | // ha nincs ilyen ID-ju tab az inspectorban (azaz pl. nincs out, vagy in kapcsolata a megnyitni kivant nodenak) 223 | catch (ex){ 224 | targetTabId = 0; 225 | } 226 | $("#nodeOpenedContentTabs").tabs("option", "active", targetTabId); 227 | return tabId; 228 | } 229 | return null; 230 | } 231 | 232 | function setInspector(targetTabName, property, target) { 233 | $.jStorage.set("targetTabName", targetTabName); 234 | $.jStorage.set("property", property); 235 | $.jStorage.set("target", target); 236 | } 237 | 238 | function resetInspector(targetTabName, property, target) { 239 | $.jStorage.deleteKey("targetTabName"); 240 | $.jStorage.deleteKey("property"); 241 | $.jStorage.deleteKey("target"); 242 | } -------------------------------------------------------------------------------- /js/lod/layout/grid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Attila Gyorok on 2014.07.14.. 3 | */ 4 | 5 | /** 6 | * Places the nodes on a grid structure. 7 | */ 8 | function gridLayout(buffer, min_distance) { 9 | // var sorted_nodes = []; 10 | var i; 11 | var length = buffer.vertexes.length; 12 | //nxn matrix 13 | var n = Math.sqrt(length); 14 | n = Math.ceil(n * 10) / 10; 15 | var mx = $(document).scrollLeft() + (window.screen.width - n * min_distance) / 2, 16 | my = $(document).scrollTop() + (window.screen.height - n * min_distance) / 2; 17 | // sorted_nodes = buffer.vertexes.slice(); 18 | 19 | var act; 20 | 21 | var x = 0, y = 0; 22 | for (i = 0; i < length; i++) 23 | { 24 | act = buffer.vertexes[i]; 25 | act.gridX = x; 26 | act.gridY = y; 27 | x++; 28 | if (x > n) 29 | { 30 | x = 0; 31 | y++; 32 | } 33 | } 34 | 35 | var r1, r2; 36 | var t1, nt1, t2, nt2; 37 | var tmpX, tmpY; 38 | for (i = 0; i < 10000; i++) 39 | { 40 | r1 = Math.floor(Math.random() * length); 41 | r2 = Math.floor(Math.random() * length); 42 | if (r1 == r2) { 43 | i--; 44 | continue; 45 | } 46 | r1 = buffer.vertexes[r1]; 47 | r2 = buffer.vertexes[r2]; 48 | t1 = checkCrossing(r1, r1, buffer); 49 | nt1 = checkCrossing(r1, r2, buffer); 50 | t2 = checkCrossing(r2, r2, buffer); 51 | nt2 = checkCrossing(r2, r1, buffer); 52 | if (t1 + t2 > nt1 + nt2) 53 | { 54 | //swap grid pos 55 | tmpX = r1.gridX; 56 | tmpY = r1.gridY; 57 | r1.gridX = r2.gridX; 58 | r1.gridY = r2.gridY; 59 | r2.gridX = tmpX; 60 | r2.gridY = tmpY; 61 | } 62 | } 63 | 64 | var node; 65 | for (i = 0; i < length; i++) 66 | { 67 | act = buffer.vertexes[i]; 68 | if (act.isVirtual) continue; 69 | node = Graph.nodes[act.id]; 70 | node.left = act.gridX * min_distance * 2 + mx; 71 | node.top = act.gridY * min_distance * 2 + my; 72 | } 73 | 74 | 75 | // sorted_nodes.sort( function(a,b) { 76 | // if (a.inConnCounter + a.outConnCounter > b.inConnCounter + b.outConnCounter) return -1; 77 | // return 1; 78 | // }); 79 | 80 | // var x = 0, y = 0; 81 | // var act; 82 | // for (index in sorted_nodes) 83 | // { 84 | // act = Graph.nodes[sorted_nodes[index].id]; 85 | // act.left = x * 200 + mx; 86 | // act.top = y * 200 + my; 87 | // x++; 88 | // if (x > n) 89 | // { 90 | // x = 0; 91 | // y++; 92 | // } 93 | // } 94 | 95 | //setbufferpos 96 | var original; 97 | for (var index in buffer.vertexes) { 98 | var act = buffer.vertexes[index]; 99 | if (act.isVirtual == false) { 100 | original = Graph.getNode(act.id); 101 | act.left = original.left; 102 | act.top = original.top; 103 | } 104 | } 105 | } 106 | 107 | function gridLayoutGroup(buffer, min_distance) 108 | { 109 | var i,j ; 110 | var length = buffer.groups.length; 111 | var gl, gx, gy, maxgl = 0, actg; 112 | //nxn matrix 113 | var n = Math.sqrt(length); 114 | n = Math.ceil(n * 10) / 10; 115 | 116 | for (i = 0; i < length; i++) 117 | { 118 | act = buffer.groups[i]; 119 | gl = act.vertexes.length; 120 | if (gl > maxgl) maxgl = gl; 121 | } 122 | 123 | var ng = Math.sqrt(maxgl); 124 | ng = Math.ceil(ng * 10) / 10; 125 | var mx = $(document).scrollLeft() + (window.screen.width - n * ng * min_distance) / 2, 126 | my = $(document).scrollTop() + (window.screen.height - n * ng * min_distance) / 2; 127 | var act; 128 | 129 | var x = 0, y = 0; 130 | for (i = 0; i < length; i++) 131 | { 132 | act = buffer.groups[i]; 133 | act.gridX = x; 134 | act.gridY = y; 135 | x++; 136 | if (x > n) 137 | { 138 | x = 0; 139 | y++; 140 | } 141 | } 142 | 143 | var r1, r2, r1g, r2g; 144 | var t1, nt1, t2, nt2; 145 | var tmpX, tmpY; 146 | for (i = 0; i < 10000; i++) 147 | { 148 | r1 = Math.floor(Math.random() * length); 149 | r2 = Math.floor(Math.random() * length); 150 | if (r1 == r2) { 151 | i--; 152 | continue; 153 | } 154 | r1g = buffer.groups[r1]; 155 | r2g = buffer.groups[r2]; 156 | t1 = checkCrossingGroup(r1g, r1g, buffer, r1); 157 | nt1 = checkCrossingGroup(r1g, r2g, buffer, r1); 158 | t2 = checkCrossingGroup(r2g, r2g, buffer, r2); 159 | nt2 = checkCrossingGroup(r2g, r1g, buffer, r2); 160 | if (t1 + t2 > nt1 + nt2) 161 | { 162 | //swap grid pos 163 | tmpX = r1g.gridX; 164 | tmpY = r1g.gridY; 165 | r1g.gridX = r2g.gridX; 166 | r1g.gridY = r2g.gridY; 167 | r2g.gridX = tmpX; 168 | r2g.gridY = tmpY; 169 | } 170 | } 171 | 172 | var node; 173 | var gs; 174 | for (i = 0; i < length; i++) 175 | { 176 | actg = buffer.groups[i]; 177 | gl = actg.vertexes.length; 178 | gs = Math.sqrt(gl); 179 | gs = Math.ceil(gs * 10) / 10; 180 | x = 0; 181 | y = 0; 182 | for (j = 0; j < gl; j++) 183 | { 184 | act = actg.vertexes[j]; 185 | if (act.isVirtual) continue; 186 | node = Graph.nodes[act.id]; 187 | node.left = (actg.gridX * (ng + 1) + x)* min_distance * 2 + mx; 188 | node.top = (actg.gridY * (ng + 1) + y) * min_distance * 2 + my; 189 | x++; 190 | if (x > gs) 191 | { 192 | x = 0; 193 | y++; 194 | } 195 | } 196 | } 197 | 198 | //setbufferpos 199 | var original; 200 | for (var index in buffer.vertexes) { 201 | var act = buffer.vertexes[index]; 202 | if (act.isVirtual == false) { 203 | original = Graph.getNode(act.id); 204 | act.left = original.left; 205 | act.top = original.top; 206 | } 207 | } 208 | } 209 | 210 | function gridLayoutGroupAdaptive(buffer, min_distance) 211 | { 212 | var length = buffer.groups.length; 213 | 214 | if (length == 1) { 215 | return; 216 | } 217 | 218 | var rng = CustomRandom(23), 219 | act, 220 | i,j, 221 | gl, gx, gy, 222 | maxgl = 0, actg; 223 | 224 | //nxn matrix 225 | var n = Math.sqrt(length), 226 | nx = Math.ceil(n), 227 | ny = Math.floor(n); 228 | 229 | if (nx * ny < length) ny++; 230 | 231 | for (i = 0; i < length; i++) 232 | { 233 | act = buffer.groups[i]; 234 | gl = act.vertexes.length; 235 | if (gl > maxgl) maxgl = gl; 236 | } 237 | 238 | var ng = Math.sqrt(maxgl), 239 | ngx = Math.ceil(ng), 240 | ngy = Math.floor(ng); 241 | 242 | if (ngx * ngy < ng) ngy++; 243 | 244 | var x = 0, y = 0; 245 | for (i = 0; i < length; i++) 246 | { 247 | act = buffer.groups[i]; 248 | act.gridX = x; 249 | act.gridY = y; 250 | x++; 251 | if (x >= nx) 252 | { 253 | x = 0; 254 | y++; 255 | } 256 | } 257 | 258 | var r1, r2, r1g, r2g; 259 | var t1, nt1, t2, nt2; 260 | var tmpX, tmpY; 261 | for (i = 0; i < 10000; i++) 262 | { 263 | r1 = Math.floor(rng.next() * length); 264 | r2 = Math.floor(rng.next() * length); 265 | if (r1 == r2) { 266 | i--; 267 | continue; 268 | } 269 | r1g = buffer.groups[r1]; 270 | r2g = buffer.groups[r2]; 271 | t1 = checkCrossingGroup(r1g, r1g, buffer, r1); 272 | nt1 = checkCrossingGroup(r1g, r2g, buffer, r1); 273 | t2 = checkCrossingGroup(r2g, r2g, buffer, r2); 274 | nt2 = checkCrossingGroup(r2g, r1g, buffer, r2); 275 | if (t1 + t2 > nt1 + nt2) 276 | { 277 | //swap grid pos 278 | tmpX = r1g.gridX; 279 | tmpY = r1g.gridY; 280 | r1g.gridX = r2g.gridX; 281 | r1g.gridY = r2g.gridY; 282 | r2g.gridX = tmpX; 283 | r2g.gridY = tmpY; 284 | } 285 | } 286 | 287 | var maxX = [nx]; 288 | var maxY = [ny]; 289 | for (i = 0; i < nx; i++) 290 | { 291 | maxX[i] = 0; 292 | } 293 | for (i = 0; i < ny; i++) 294 | { 295 | maxY[i] = 0; 296 | } 297 | tmp = 0; 298 | var gsx, gsy; 299 | for (i = 0; i < length; i++) 300 | { 301 | actg = buffer.groups[i]; 302 | gl = actg.vertexes.length; 303 | gs = Math.sqrt(gl); 304 | gsx = Math.ceil(gs); 305 | gsy = Math.floor(gs); 306 | if (gsx * gsy < gs) gsy++; 307 | if (maxX[actg.gridX] < gsx) maxX[actg.gridX] = gsx; 308 | if (maxY[actg.gridY] < gsy) maxY[actg.gridY] = gsy; 309 | } 310 | var diffX = [nx]; 311 | var diffY = [ny]; 312 | //space 313 | for (i = 0; i < nx; i++) 314 | { 315 | diffX[i] = maxX[i] + 0.25; 316 | } 317 | for (i = 0; i < ny; i++) 318 | { 319 | diffY[i] = maxY[i] + 0.25; 320 | } 321 | //sum 322 | for (i = 1; i < nx; i++) 323 | { 324 | diffX[i] += diffX[i - 1]; 325 | } 326 | for (i = 1; i < ny; i++) 327 | { 328 | diffY[i] += diffY[i - 1]; 329 | } 330 | var posX = [nx]; 331 | posX[0] = 0; 332 | for (i = 1; i < nx; i++) 333 | { 334 | posX[i] = diffX[i - 1]; 335 | } 336 | var posY = [ny]; 337 | posY[0] = 0; 338 | for (i = 1; i < ny; i++) 339 | { 340 | posY[i] = diffY[i - 1]; 341 | } 342 | var mx = $(document).scrollLeft() + (window.screen.width - diffX[nx-1] * min_distance) / 2, //nx*ngx 343 | my = $(document).scrollTop() + (window.screen.height - diffY[ny-1] * min_distance) / 2; 344 | var node; 345 | var gs; 346 | for (i = 0; i < length; i++) 347 | { 348 | actg = buffer.groups[i]; 349 | gl = actg.vertexes.length; 350 | gs = Math.sqrt(gl); 351 | gsx = Math.ceil(gs); 352 | gsy = Math.floor(gs); 353 | if (gsx * gsy < gl) gsy++; 354 | x = 0; 355 | y = 0; 356 | for (j = 0; j < gl; j++) 357 | { 358 | act = actg.vertexes[j]; 359 | if (act.isVirtual) continue; 360 | node = Graph.nodes[act.id]; 361 | node.left = (posX[actg.gridX] + (maxX[actg.gridX] - gsx) / 2 + x) * min_distance * 2 + mx; 362 | node.top = (posY[actg.gridY] + (maxY[actg.gridY] - gsy) / 2 + y) * min_distance * 2 + my; 363 | x++; 364 | if (x >= gsx) 365 | { 366 | x = 0; 367 | y++; 368 | } 369 | } 370 | } 371 | 372 | //setbufferpos 373 | var original; 374 | for (var index in buffer.vertexes) { 375 | act = buffer.vertexes[index]; 376 | if (act.isVirtual == false) { 377 | original = Graph.getNode(act.id); 378 | act.left = original.left; 379 | act.top = original.top; 380 | } 381 | } 382 | } 383 | 384 | function checkCrossing(n1, n2, buffer) { 385 | var x = n2.gridX; 386 | var y = n2.gridY; 387 | var dx, dy; 388 | var i; 389 | var length = n1.targets.length; 390 | var diff = 0; 391 | var act; 392 | for (i = 0; i < length; i++) 393 | { 394 | act = buffer.vertexes[n1.targets[i]]; 395 | dx = act.gridX - x; 396 | dy = act.gridY - y; 397 | diff += dx * dx + dy * dy; 398 | } 399 | length = n1.sources.length; 400 | for (i = 0; i < length; i++) 401 | { 402 | act = buffer.vertexes[n1.sources[i]]; 403 | dx = act.gridX - x; 404 | dy = act.gridY - y; 405 | diff += dx * dx + dy * dy; 406 | } 407 | return diff; 408 | } 409 | 410 | function checkCrossingGroup(n1, n2, buffer, index) { 411 | var x = n2.gridX; 412 | var y = n2.gridY; 413 | var dx, dy; 414 | var i; 415 | var length = buffer.groups.length; 416 | var diff = 0; 417 | var act; 418 | for (i = 0; i < length; i++) 419 | { 420 | if (buffer.groupsConnected[index][i] == 0) continue; 421 | act = buffer.groups[i]; 422 | dx = act.gridX - x; 423 | dy = act.gridY - y; 424 | diff += dx * dx + dy * dy; 425 | } 426 | return diff; 427 | } 428 | 429 | //http://michalbe.blogspot.hu/2011/02/javascript-random-numbers-with-custom_23.html 430 | var CustomRandom = function(nseed) { 431 | 432 | var seed; 433 | if (nseed) { 434 | seed = nseed; 435 | } 436 | 437 | if (seed == null) { 438 | //before you will correct me in this comparison, read Andrea Giammarchi's text about coercion http://goo.gl/N4jCB 439 | 440 | seed = (new Date()).getTime(); 441 | //if there is no seed, use timestamp 442 | } 443 | 444 | return { 445 | next : function(min, max) { 446 | var x = Math.sin(seed++) * 10000; 447 | return x - Math.floor(x); 448 | // if 'min' and 'max' are not provided, return random number between 0 & 1 449 | } 450 | } 451 | } -------------------------------------------------------------------------------- /js/lod/layout/radial.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dsd-sztaki-hu/LODmilla-frontend/017630d506ade2a9d03552686db7ccc8fc31372a/js/lod/layout/radial.js -------------------------------------------------------------------------------- /js/lod/layout/virtual.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Attila Gyorok on 2014.07.14.. 3 | */ 4 | 5 | //detecting virtual nodes - the ones that are not visible, but can be predicted from the DB 6 | 7 | function ConnectionHolder(id, targetId) { 8 | this.id = id; 9 | this.pairs = []; 10 | this.pairs.push(targetId); 11 | } 12 | 13 | function ConnectionCounter() { 14 | this.inConns = []; 15 | this.outConns = []; 16 | } 17 | 18 | /** 19 | * Adds an incoming connection to the list. 20 | * @param id This is the connection's target id. 21 | * @param sourceId This is the connection's source id. 22 | */ 23 | ConnectionCounter.prototype.addIncomingConnection = function(id, sourceId) 24 | { 25 | var found = false; 26 | 27 | for (var index in this.inConns) 28 | { 29 | var conn = this.inConns[index]; 30 | if (conn.id == sourceId) 31 | { 32 | found = true; 33 | if (conn.pairs.indexOf(id) < 0) conn.pairs.push(id); 34 | } 35 | } 36 | if (!found) 37 | { 38 | this.inConns.push( new ConnectionHolder(sourceId, id) ); 39 | } 40 | } 41 | 42 | /** 43 | * Adds an outgoing connection to the list. 44 | * @param id This is the connection's source id. 45 | * @param targetId This is the connection's target id. 46 | */ 47 | ConnectionCounter.prototype.addOutgoingConnection = function(id, targetId) 48 | { 49 | var found = false; 50 | for (var index in this.outConns) 51 | { 52 | var conn = this.outConns[index]; 53 | if (conn.id == targetId) 54 | { 55 | found = true; 56 | if (conn.pairs.indexOf(id) < 0) conn.pairs.push(id); 57 | } 58 | } 59 | if (!found) 60 | { 61 | this.outConns.push( new ConnectionHolder(targetId, id) ); 62 | } 63 | } 64 | 65 | function addVirtualNodes(buffer, virtualWeight) 66 | { 67 | //known unseen virtual points 68 | //connection match from the database 69 | 70 | var cc = new ConnectionCounter(); 71 | for (var index in Graph.nodes) 72 | { 73 | i = Graph.nodes[index]; 74 | for (var index2 in i.connections) 75 | { 76 | var c = i.connections[index2]; 77 | if (c.direction == "out") 78 | cc.addOutgoingConnection(i.resource_id, c.target); 79 | else 80 | cc.addIncomingConnection(i.resource_id, c.target); 81 | } 82 | } 83 | 84 | //add virtual nodes to the visible nodes 85 | 86 | //incoming connections 87 | var virtualcounter = 0; 88 | for (var index in cc.inConns) { 89 | i = cc.inConns[index]; 90 | if (i.pairs.length > 1) { 91 | var v = buffer.addVertex(i.id, "virtual_" + virtualcounter, virtualWeight, true, 0, 0, "virtual_" + virtualcounter++); 92 | var v_zero = buffer.getVertexById(i.pairs[0]); 93 | var center_left = v_zero.left, center_top = v_zero.top; 94 | var length = i.pairs.length; 95 | var v_index = buffer.getVertexIndex(v); 96 | for (var index2 in i.pairs) { 97 | //var tindex = buffer.getVertexIndexById(i.pairs[index2]); 98 | var d_v = buffer.getVertexById(i.pairs[index2]); 99 | buffer.addConnection(v.id, d_v.id); 100 | // var d_v = buffer.getVertexByIndex(tindex); 101 | center_left = (center_left + d_v.left) / 2.0; //this is not necessary for the first time 102 | center_top = (center_top + d_v.top) / 2.0; //but a lot cleaner this way 103 | } 104 | v.left = center_left; //placing the virtual nodes in the center of the visible nodes 105 | v.top = center_top; 106 | } 107 | } 108 | 109 | //outgoing connections 110 | for (var index in cc.outConns) { 111 | i = cc.outConns[index]; 112 | if (i.pairs.length > 1) { 113 | var v = buffer.addVertex(i.id, "virtual_" + virtualcounter++, virtualWeight, true, 0, 0, "virtual_" + virtualcounter++); 114 | var v_zero = buffer.getVertexById(i.pairs[0]); 115 | var center_left = v_zero.left, center_top = v_zero.top; 116 | for (var index2 in i.pairs) { 117 | var t = buffer.getVertexById(i.pairs[index2]); 118 | buffer.addConnection(t.id, v.id); 119 | center_left = (center_left + t.left) / 2.0; 120 | center_top = (center_top + t.top) / 2.0; 121 | } 122 | v.left = center_left; 123 | v.top = center_top; 124 | } 125 | } 126 | } 127 | 128 | function addVirtualTypeNodes(buffer, virtualWeight) 129 | { 130 | //known unseen virtual points 131 | //connection match from the database 132 | 133 | var cc = new ConnectionCounter(); 134 | for (var index in Graph.nodes) 135 | { 136 | i = Graph.nodes[index]; 137 | cc.addOutgoingConnection(i.resource_id, i.type); 138 | } 139 | var virtualcounter = 0; 140 | //add virtual nodes to the visible nodes 141 | //outgoing connections 142 | for (var index in cc.outConns) { 143 | i = cc.outConns[index]; 144 | if (i.pairs.length > 1) { 145 | var v = buffer.addVertex(i.id, "virtual_" + virtualcounter++, virtualWeight, true, 0, 0, "virtual_" + virtualcounter++); 146 | var v_zero = buffer.getVertexById(i.pairs[0]); 147 | var center_left = v_zero.left, center_top = v_zero.top; 148 | for (var index2 in i.pairs) { 149 | var t = buffer.getVertexById(i.pairs[index2]); 150 | buffer.addConnection(t.id, v.id); 151 | center_left = (center_left + t.left) / 2.0; 152 | center_top = (center_top + t.top) / 2.0; 153 | } 154 | v.left = center_left; 155 | v.top = center_top; 156 | } 157 | } 158 | } -------------------------------------------------------------------------------- /js/lod/server_connector.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LODmilla-frontend 3 | * 4 | * https://github.com/dsd-sztaki-hu/LODmilla-frontend 5 | * 6 | * Copyright (c) 2013 Sandor Turbucz, Zoltan Toth, Andras Micsik - MTA SZTAKI DSD 7 | * 8 | */ 9 | 10 | Profile.data_getService = function(resourceURI) { 11 | var service = ''; 12 | // TODO: meg jobb matching a services_json-bol a prefixekre...van amelyik lod itemnel generalt, uh kitalalando hogy legyen ez 13 | try{ 14 | $.each(this.services, function(key, value) { 15 | var resourcePath = resourceURI.split('//')[1]; 16 | // var resourcePrefix = resourceURI.split('//')[0] + '//' + resourcePath.split('/', resourcePath.split('/').length-1).join('/'); 17 | var resourcePrefix = resourceURI.split('//')[0] + '//' + resourcePath.split('/')[0]; 18 | 19 | var isPrefixFound = false; 20 | //console.log("value", value); 21 | for (var prefix in value.prefix){ 22 | //console.log("prefix", prefix); 23 | if (value.prefix[prefix]){ 24 | // if (value.prefix[prefix] === resourcePrefix){ 25 | //console.log("matching", prefix, value.prefix[prefix], resourcePrefix); 26 | if (value.prefix[prefix].indexOf(resourcePrefix) !== -1){ 27 | isPrefixFound = true; 28 | } 29 | } 30 | } 31 | if (value.disabled !== 'true' && isPrefixFound) { 32 | service = value; 33 | } 34 | }); 35 | } 36 | catch (e){ console.log("EXCEPTION", e); } 37 | console.log("Using service", service); 38 | return service; 39 | }; 40 | 41 | Profile.data_makeSparql = function(service, sparqlTemplate, resourceURI) { 42 | var sparql = ""; 43 | 44 | var s = encodeURIComponent(service.sparqlTemplates[sparqlTemplate].replace(/\{URI\}/ig, resourceURI)); 45 | sparql = service.endpoint + '?'; 46 | sparql += 'output=json'; 47 | sparql += '&format=application/json'; 48 | sparql += '&timeout=0'; 49 | sparql += '&query=' + s; 50 | 51 | return sparql; 52 | }; 53 | 54 | Profile.data_getConnectionsLabels = function(resourceURI, object, callbackFunc, highlight, undoActionLabel) { 55 | var service = this.data_getService(resourceURI); 56 | var url = ''; 57 | 58 | if (service && service !== '') { 59 | url = this.data_makeSparql(service, 'resourceConnectionsLabels', resourceURI); 60 | } 61 | else { 62 | url = this.serverProxyUrl + 'lod_resource_proxy.jsp?url=' + encodeURIComponent(resourceURI); 63 | } 64 | $.jsonp({ 65 | url: url, 66 | callbackParameter: "callback", 67 | callback: "mpadJson", 68 | beforeSend: function() { 69 | }, 70 | success: function(json) { 71 | object[callbackFunc].call(object, json, service, highlight, undoActionLabel); 72 | }, 73 | error: function(jqXHR, textStatus, errorThrown) { 74 | object[callbackFunc].call(object, false, false, highlight, undoActionLabel); 75 | } 76 | }); 77 | }; 78 | 79 | var BackendCommunicator = new function() { 80 | this.findPath = function(nodes, depth, nodes_max, callbackfunc, undoActionLabel) { 81 | $.jsonp({ 82 | url: Profile.serverProxyUrl + "graph_conn_search.jsp", 83 | cache: false, 84 | callbackParameter: 'callback', 85 | callback: 'mpadCB', 86 | data: {'urls': nodes, 'path_max': depth, 'nodes_max': nodes_max}, 87 | beforeSend: function() { 88 | }, 89 | success: function(json, textStatus, xOptions) { 90 | callbackfunc(json, undoActionLabel); 91 | }, 92 | error: function(jqXHR, textStatus, errorThrown) { 93 | callbackfunc({error: textStatus}, undoActionLabel); 94 | console.log('error 1'); 95 | console.log(jqXHR); 96 | console.log(textStatus); 97 | console.log(errorThrown); 98 | } 99 | }); 100 | }; 101 | this.findContent = function(nodes, depth, nodes_max, searchText, callbackfunc, undoActionLabel) { 102 | $.jsonp({ 103 | url: Profile.serverProxyUrl + "graph_content_search.jsp", 104 | cache: false, 105 | callbackParameter: 'callback', 106 | callback: 'mpadCB', 107 | data: {'urls': nodes, 'path_max': depth, 'nodes_max': nodes_max, 'search': searchText}, 108 | beforeSend: function() { 109 | }, 110 | success: function(json, textStatus, xOptions) { 111 | callbackfunc(json, undoActionLabel); 112 | }, 113 | error: function(jqXHR, textStatus, errorThrown) { 114 | callbackfunc({error: textStatus}, undoActionLabel); 115 | console.log('error 1'); 116 | console.log(jqXHR); 117 | console.log(textStatus); 118 | console.log(errorThrown); 119 | } 120 | }); 121 | }; 122 | this.findConnections = function(nodes, depth, nodes_max, searchText, callbackfunc, undoActionLabel) { 123 | $.jsonp({ 124 | url: Profile.serverProxyUrl + "graph_link_search.jsp", 125 | cache: false, 126 | callbackParameter: 'callback', 127 | callback: 'mpadCB', 128 | data: {'urls': nodes, 'path_max': depth, 'nodes_max': nodes_max, 'search': searchText}, 129 | beforeSend: function() { 130 | }, 131 | success: function(json, textStatus, xOptions) { 132 | callbackfunc(json, undoActionLabel); 133 | }, 134 | error: function(jqXHR, textStatus, errorThrown) { 135 | callbackfunc({error: textStatus}, undoActionLabel); 136 | console.log('error 1'); 137 | console.log(jqXHR); 138 | console.log(textStatus); 139 | console.log(errorThrown); 140 | } 141 | }); 142 | }; 143 | this.load = function(graphid, user_name, graph_name, callbackfunc, undoActionLabel) { 144 | $.jsonp({ 145 | url: Profile.serverProxyUrl + "graph_load.jsp", 146 | cache: false, 147 | callbackParameter: 'callback', 148 | callback: 'mpadCB', 149 | data: {'graph_name': graph_name, 'user_name': user_name, 'graph_id': graphid}, 150 | beforeSend: function() { 151 | }, 152 | success: function(json, textStatus, xOptions) { 153 | callbackfunc(json, undoActionLabel); 154 | }, 155 | error: function(jqXHR, textStatus, errorThrown) { 156 | callbackfunc({error: textStatus}, undoActionLabel); 157 | console.log('error 1'); 158 | console.log(jqXHR); 159 | console.log(textStatus); 160 | console.log(errorThrown); 161 | } 162 | }); 163 | }; 164 | 165 | this.save = function(user_name, graph_name, graph, callbackfunc) { 166 | $.ajax({ 167 | url: Profile.serverProxyUrl + "graph_save.jsp", 168 | cache: false, 169 | callbackParameter: 'callback', 170 | callback: 'mpadCB', 171 | type: "POST", 172 | data: {'user_name': user_name, 'graph_name': graph_name, 'graph': graph}, 173 | beforeSend: function() { 174 | }, 175 | success: function(json, textStatus, xOptions) { 176 | callbackfunc(json); 177 | }, 178 | error: function(jqXHR, textStatus, errorThrown) { 179 | callbackfunc({error: textStatus}); 180 | console.log('error 2'); 181 | console.log(jqXHR); 182 | console.log(textStatus); 183 | console.log(errorThrown); 184 | } 185 | }); 186 | }; 187 | 188 | this.graphNameAutocomplete = function(request, response) { 189 | //TODO: it is not too nice to include jquery here... 190 | var user_name = $("#user_name").val(); 191 | $.jsonp({ 192 | url: Profile.serverProxyUrl + "graph_name_autocomplete.jsp", 193 | cache: false, 194 | callbackParameter: 'callback', 195 | callback: 'mpadCB', 196 | async: "false", 197 | data: { 198 | user_name: user_name, 199 | graph_name: request.term 200 | }, 201 | success: function(json, textStatus, xOptions) { 202 | Sidemenu.graphNameAutoComplete(json, response); 203 | }, 204 | error: function(jqXHR, textStatus, errorThrown) { 205 | Sidemenu.graphNameAutoComplete({error: textStatus}, response); 206 | console.log('error 3'); 207 | console.log(jqXHR); 208 | console.log(textStatus); 209 | console.log(errorThrown); 210 | } 211 | }); 212 | }; 213 | }; 214 | 215 | -------------------------------------------------------------------------------- /js/lod/service.class.js: -------------------------------------------------------------------------------- 1 | /* 2 | * LODmilla-frontend 3 | * 4 | * https://github.com/dsd-sztaki-hu/LODmilla-frontend 5 | * 6 | * Copyright (c) 2013 Sandor Turbucz, Zoltan Toth, Andras Micsik - MTA SZTAKI DSD 7 | * 8 | */ 9 | 10 | var Service = function(name,shortDescription,description,endpoint,prefix,graph,sparqlTemplates,disabled){ 11 | 12 | this.name = name; 13 | this.shortDescription = shortDescription; 14 | this.description = description; 15 | this.endpoint = endpoint; 16 | this.prefix = prefix; 17 | this.graph = graph; 18 | this.disabled = disabled; 19 | 20 | this.sparqlTemplates = sparqlTemplates; 21 | 22 | }; 23 | 24 | 25 | -------------------------------------------------------------------------------- /js/lod/services.js: -------------------------------------------------------------------------------- 1 | var Lodmilla_services = { 2 | "http://lod.sztaki.hu/sztaki": { 3 | "shortDescription": { 4 | "en": "Sztaki" 5 | }, 6 | "description": { 7 | "en": "LOD at Sztaki (/sztaki)" 8 | }, 9 | "sparql": { 10 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 11 | }, 12 | "endpoint": "http://lod.sztaki.hu/sparql", 13 | "prefix": { 14 | "author": "http://lod.sztaki.hu/sztaki/auth", 15 | "item": "http://lod.sztaki.hu/sztaki/item" 16 | }, 17 | "graph": "http://lod.sztaki.hu/sztaki", 18 | "disabled": "false" 19 | }, 20 | "http://lod.sztaki.hu/nda": { 21 | "shortDescription": { 22 | "en": "Sztaki" 23 | }, 24 | "description": { 25 | "en": "LOD at Sztaki (/nda)" 26 | }, 27 | "sparql": { 28 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 29 | }, 30 | "endpoint": "http://lod.sztaki.hu/sparql", 31 | "prefix": { 32 | "default": "http://lod.sztaki.hu/data" 33 | }, 34 | "graph": "http://lod.sztaki.hu/nda", 35 | "disabled": "false" 36 | }, 37 | "http://www.civilkapocs.hu": { 38 | "shortDescription": { 39 | "en": "Civilkapocs" 40 | }, 41 | "description": { 42 | "en": "Civilkapocs" 43 | }, 44 | "sparql": { 45 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"hu\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"hu\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"hu\"||lang(?proplabel)=\"\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"hu\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"hu\"||lang(?proplabel)=\"\") } } }" 46 | }, 47 | "endpoint": "http://civilkapocs.hu:8890/sparql", 48 | "prefix": { 49 | "default": "http://www.civilkapocs.hu/rdf" 50 | }, 51 | "graph": "http://civilkapocs.hu", 52 | "disabled": "false" 53 | }, 54 | "http://lod.nik.uni-obuda.hu": { 55 | "shortDescription": { 56 | "en": "Uni Obuda" 57 | }, 58 | "description": { 59 | "en": "Obuda University" 60 | }, 61 | "sparql": { 62 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 63 | }, 64 | "endpoint": "http://lod.nik.uni-obuda.hu/sparql", 65 | "prefix": { 66 | "default": "http://lod.nik.uni-obuda.hu/" 67 | }, 68 | "graph": "http://lod.nik.uni-obuda.hu/graph", 69 | "disabled": "false" 70 | }, 71 | "http://dbpedia.org": { 72 | "shortDescription": { 73 | "en": "DBpedia" 74 | }, 75 | "description": { 76 | "en": "DBpedia is a community effort to extract structured information from Wikipedia and to make this information available on the Web. DBpedia allows you to ask sophisticated queries against Wikipedia, and to link other data sets on the Web to Wikipedia data." 77 | }, 78 | "sparql": { 79 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 80 | }, 81 | "endpoint": "http://dbpedia.org/sparql", 82 | "prefix": { 83 | "default": "http://dbpedia.org/resource" 84 | }, 85 | "graph": "http://dbpedia.org", 86 | "disabled": "false" 87 | }, 88 | "http://wikidata.dbpedia.org": { 89 | "shortDescription": { 90 | "en": "DBpedia Wikidata" 91 | }, 92 | "description": { 93 | "en": "Wikidata is a free and open knowledge base that can be read and edited by both humans and machines." 94 | }, 95 | "sparql": { 96 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 97 | }, 98 | "endpoint": "http://wikidata.dbpedia.org/sparql", 99 | "prefix": { 100 | "default": "http://wikidata.dbpedia.org/resource" 101 | }, 102 | "graph": "http://wikidata.dbpedia.org", 103 | "disabled": "false" 104 | }, 105 | "http://wikidata.org": { 106 | "shortDescription": { 107 | "en": "Wikidata" 108 | }, 109 | "description": { 110 | "en": "Wikidata is a free and open knowledge base that can be read and edited by both humans and machines." 111 | }, 112 | "sparql": { 113 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 114 | }, 115 | "endpoint": "http://query.wikidata.org/", 116 | "prefix": { 117 | "default": "http://www.wikidata.org/entity" 118 | }, 119 | "graph": "http://wikidata.org", 120 | "disabled": "false" 121 | }, 122 | "http://data.szepmuveszeti.hu/": { 123 | "shortDescription": { 124 | "en": "Szépművészeti" 125 | }, 126 | "description": { 127 | "en": "Szépművészeti" 128 | }, 129 | "sparql": { 130 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 131 | }, 132 | "endpoint": "http://data.szepmuveszeti.hu/sparql", 133 | "prefix": { 134 | "default": "http://data.szepmuveszeti.hu/", 135 | "resource": "http://data.szepmuveszeti.hu/id/resource/" 136 | }, 137 | "graph": "http://data.szepmuveszeti.hu/", 138 | "disabled": "false" 139 | }, 140 | "http://europeana.ontotext.com/": { 141 | "shortDescription": { 142 | "en": "Europeana" 143 | }, 144 | "description": { 145 | "en": "Europeana" 146 | }, 147 | "sparql": { 148 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 149 | }, 150 | "endpoint": "http://europeana.ontotext.com/sparql.json", 151 | "prefix": { 152 | "default": "http://data.europeana.eu" 153 | }, 154 | "graph": "http://data.europeana.eu", 155 | "disabled": "true" 156 | }, 157 | "http://collection.britishmuseum.org/": { 158 | "shortDescription": { 159 | "en": "British Museum" 160 | }, 161 | "description": { 162 | "en": "British Museum's collection" 163 | }, 164 | "sparql": { 165 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 166 | }, 167 | "endpoint": "http://collection.britishmuseum.org/sparql.json", 168 | "prefix": { 169 | "default": "http://collection.britishmuseum.org" 170 | }, 171 | "graph": "http://collection.britishmuseum.org/", 172 | "disabled": "true" 173 | }, 174 | "http://factforge.net/": { 175 | "shortDescription": { 176 | "en": "FactForge" 177 | }, 178 | "description": { 179 | "en": "FactForge" 180 | }, 181 | "sparql": { 182 | "resourceConnectionsLabels": "select distinct * where { { <{URI}> ?prop ?out. FILTER(!isLiteral(?out) || lang(?out)=\"\" || lang(?out)=\"en\") OPTIONAL { ?out rdfs:label ?label. FILTER(lang(?label)=\"en\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } UNION { ?in ?prop <{URI}> OPTIONAL { ?in rdfs:label ?label. FILTER(lang(?label)=\"en\"||lang(?label)=\"\") } OPTIONAL { ?prop rdfs:label ?proplabel. FILTER(lang(?proplabel)=\"en\"||lang(?proplabel)=\"\"||lang(?proplabel)=\"en-us\") } } }" 183 | }, 184 | "endpoint": "http://factforge.net/sparql", 185 | "prefix": { 186 | "default": "http://factforge.net/", 187 | "resource": "http://factforge.net/resource", 188 | "dbpedia": "http://factforge.net/resource/dbpedia" 189 | }, 190 | "graph": "http://factforge.net/", 191 | "disabled": "true" 192 | } 193 | 194 | }; -------------------------------------------------------------------------------- /js/md5.js: -------------------------------------------------------------------------------- 1 | function md5cycle(x, k) { 2 | var a = x[0], b = x[1], c = x[2], d = x[3]; 3 | 4 | a = ff(a, b, c, d, k[0], 7, -680876936); 5 | d = ff(d, a, b, c, k[1], 12, -389564586); 6 | c = ff(c, d, a, b, k[2], 17, 606105819); 7 | b = ff(b, c, d, a, k[3], 22, -1044525330); 8 | a = ff(a, b, c, d, k[4], 7, -176418897); 9 | d = ff(d, a, b, c, k[5], 12, 1200080426); 10 | c = ff(c, d, a, b, k[6], 17, -1473231341); 11 | b = ff(b, c, d, a, k[7], 22, -45705983); 12 | a = ff(a, b, c, d, k[8], 7, 1770035416); 13 | d = ff(d, a, b, c, k[9], 12, -1958414417); 14 | c = ff(c, d, a, b, k[10], 17, -42063); 15 | b = ff(b, c, d, a, k[11], 22, -1990404162); 16 | a = ff(a, b, c, d, k[12], 7, 1804603682); 17 | d = ff(d, a, b, c, k[13], 12, -40341101); 18 | c = ff(c, d, a, b, k[14], 17, -1502002290); 19 | b = ff(b, c, d, a, k[15], 22, 1236535329); 20 | 21 | a = gg(a, b, c, d, k[1], 5, -165796510); 22 | d = gg(d, a, b, c, k[6], 9, -1069501632); 23 | c = gg(c, d, a, b, k[11], 14, 643717713); 24 | b = gg(b, c, d, a, k[0], 20, -373897302); 25 | a = gg(a, b, c, d, k[5], 5, -701558691); 26 | d = gg(d, a, b, c, k[10], 9, 38016083); 27 | c = gg(c, d, a, b, k[15], 14, -660478335); 28 | b = gg(b, c, d, a, k[4], 20, -405537848); 29 | a = gg(a, b, c, d, k[9], 5, 568446438); 30 | d = gg(d, a, b, c, k[14], 9, -1019803690); 31 | c = gg(c, d, a, b, k[3], 14, -187363961); 32 | b = gg(b, c, d, a, k[8], 20, 1163531501); 33 | a = gg(a, b, c, d, k[13], 5, -1444681467); 34 | d = gg(d, a, b, c, k[2], 9, -51403784); 35 | c = gg(c, d, a, b, k[7], 14, 1735328473); 36 | b = gg(b, c, d, a, k[12], 20, -1926607734); 37 | 38 | a = hh(a, b, c, d, k[5], 4, -378558); 39 | d = hh(d, a, b, c, k[8], 11, -2022574463); 40 | c = hh(c, d, a, b, k[11], 16, 1839030562); 41 | b = hh(b, c, d, a, k[14], 23, -35309556); 42 | a = hh(a, b, c, d, k[1], 4, -1530992060); 43 | d = hh(d, a, b, c, k[4], 11, 1272893353); 44 | c = hh(c, d, a, b, k[7], 16, -155497632); 45 | b = hh(b, c, d, a, k[10], 23, -1094730640); 46 | a = hh(a, b, c, d, k[13], 4, 681279174); 47 | d = hh(d, a, b, c, k[0], 11, -358537222); 48 | c = hh(c, d, a, b, k[3], 16, -722521979); 49 | b = hh(b, c, d, a, k[6], 23, 76029189); 50 | a = hh(a, b, c, d, k[9], 4, -640364487); 51 | d = hh(d, a, b, c, k[12], 11, -421815835); 52 | c = hh(c, d, a, b, k[15], 16, 530742520); 53 | b = hh(b, c, d, a, k[2], 23, -995338651); 54 | 55 | a = ii(a, b, c, d, k[0], 6, -198630844); 56 | d = ii(d, a, b, c, k[7], 10, 1126891415); 57 | c = ii(c, d, a, b, k[14], 15, -1416354905); 58 | b = ii(b, c, d, a, k[5], 21, -57434055); 59 | a = ii(a, b, c, d, k[12], 6, 1700485571); 60 | d = ii(d, a, b, c, k[3], 10, -1894986606); 61 | c = ii(c, d, a, b, k[10], 15, -1051523); 62 | b = ii(b, c, d, a, k[1], 21, -2054922799); 63 | a = ii(a, b, c, d, k[8], 6, 1873313359); 64 | d = ii(d, a, b, c, k[15], 10, -30611744); 65 | c = ii(c, d, a, b, k[6], 15, -1560198380); 66 | b = ii(b, c, d, a, k[13], 21, 1309151649); 67 | a = ii(a, b, c, d, k[4], 6, -145523070); 68 | d = ii(d, a, b, c, k[11], 10, -1120210379); 69 | c = ii(c, d, a, b, k[2], 15, 718787259); 70 | b = ii(b, c, d, a, k[9], 21, -343485551); 71 | 72 | x[0] = add32(a, x[0]); 73 | x[1] = add32(b, x[1]); 74 | x[2] = add32(c, x[2]); 75 | x[3] = add32(d, x[3]); 76 | 77 | } 78 | 79 | function cmn(q, a, b, x, s, t) { 80 | a = add32(add32(a, q), add32(x, t)); 81 | return add32((a << s) | (a >>> (32 - s)), b); 82 | } 83 | 84 | function ff(a, b, c, d, x, s, t) { 85 | return cmn((b & c) | ((~b) & d), a, b, x, s, t); 86 | } 87 | 88 | function gg(a, b, c, d, x, s, t) { 89 | return cmn((b & d) | (c & (~d)), a, b, x, s, t); 90 | } 91 | 92 | function hh(a, b, c, d, x, s, t) { 93 | return cmn(b ^ c ^ d, a, b, x, s, t); 94 | } 95 | 96 | function ii(a, b, c, d, x, s, t) { 97 | return cmn(c ^ (b | (~d)), a, b, x, s, t); 98 | } 99 | 100 | function md51(s) { 101 | txt = ''; 102 | var n = s.length, 103 | state = [1732584193, -271733879, -1732584194, 271733878], i; 104 | for (i=64; i<=s.length; i+=64) { 105 | md5cycle(state, md5blk(s.substring(i-64, i))); 106 | } 107 | s = s.substring(i-64); 108 | var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0]; 109 | for (i=0; i>2] |= s.charCodeAt(i) << ((i%4) << 3); 111 | tail[i>>2] |= 0x80 << ((i%4) << 3); 112 | if (i > 55) { 113 | md5cycle(state, tail); 114 | for (i=0; i<16; i++) tail[i] = 0; 115 | } 116 | tail[14] = n*8; 117 | md5cycle(state, tail); 118 | return state; 119 | } 120 | 121 | /* there needs to be support for Unicode here, 122 | * unless we pretend that we can redefine the MD-5 123 | * algorithm for multi-byte characters (perhaps 124 | * by adding every four 16-bit characters and 125 | * shortening the sum to 32 bits). Otherwise 126 | * I suggest performing MD-5 as if every character 127 | * was two bytes--e.g., 0040 0025 = @%--but then 128 | * how will an ordinary MD-5 sum be matched? 129 | * There is no way to standardize text to something 130 | * like UTF-8 before transformation; speed cost is 131 | * utterly prohibitive. The JavaScript standard 132 | * itself needs to look at this: it should start 133 | * providing access to strings as preformed UTF-8 134 | * 8-bit unsigned value arrays. 135 | */ 136 | function md5blk(s) { /* I figured global was faster. */ 137 | var md5blks = [], i; /* Andy King said do it this way. */ 138 | for (i=0; i<64; i+=4) { 139 | md5blks[i>>2] = s.charCodeAt(i) 140 | + (s.charCodeAt(i+1) << 8) 141 | + (s.charCodeAt(i+2) << 16) 142 | + (s.charCodeAt(i+3) << 24); 143 | } 144 | return md5blks; 145 | } 146 | 147 | var hex_chr = '0123456789abcdef'.split(''); 148 | 149 | function rhex(n) 150 | { 151 | var s='', j=0; 152 | for(; j<4; j++) 153 | s += hex_chr[(n >> (j * 8 + 4)) & 0x0F] 154 | + hex_chr[(n >> (j * 8)) & 0x0F]; 155 | return s; 156 | } 157 | 158 | function hex(x) { 159 | for (var i=0; i> 16) + (y >> 16) + (lsw >> 16); 182 | return (msw << 16) | (lsw & 0xFFFF); 183 | } 184 | } 185 | --------------------------------------------------------------------------------