├── CODE_OF_CONDUCT.md ├── LICENSE-Bootstrap ├── LICENSE-VisJS ├── LICENSE.md ├── Mobile.png ├── README.md ├── SECURITY.md ├── clickArco.png ├── clickNodo.png ├── clickSfondo.png ├── clickarco.gif ├── clicknodo.gif ├── clicksfondo.gif ├── css ├── bootstrap.min.css ├── bootstrap.min.css.map ├── main.css ├── vis-network.min.css └── vis.map ├── desktop.png ├── eserciziDefault ├── es1-5nodi1verso │ ├── edges.json │ ├── grafo.png │ ├── nodes.json │ ├── soluzione1.png │ ├── soluzione2.png │ ├── soluzione3.png │ └── soluzione4.png ├── es2-10nodi1verso │ ├── edges.json │ ├── grafo.png │ ├── nodes.json │ ├── soluzione1.png │ ├── soluzione2.png │ ├── soluzione3.png │ └── soluzione4.png └── es3-grafoQualsiasi │ ├── edges.json │ ├── grafo.png │ ├── nodes.json │ ├── soluzione1.png │ ├── soluzione2.png │ └── soluzione3.png ├── index.html ├── js ├── bootstrap.min.js ├── bootstrap.min.js.map ├── main.js ├── vis.js.map └── vis.min.js ├── preview.gif └── socialpreview.png /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /LICENSE-Bootstrap: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2024 The Bootstrap Authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE-VisJS: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014-2017 Almende B.V. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # GNU GENERAL PUBLIC LICENSE 2 | 3 | Version 3, 29 June 2007 4 | 5 | Copyright (C) 2007 Free Software Foundation, Inc. 6 | 7 | 8 | Everyone is permitted to copy and distribute verbatim copies of this 9 | license document, but changing it is not allowed. 10 | 11 | ## Preamble 12 | 13 | The GNU General Public License is a free, copyleft license for 14 | software and other kinds of works. 15 | 16 | The licenses for most software and other practical works are designed 17 | to take away your freedom to share and change the works. By contrast, 18 | the GNU General Public License is intended to guarantee your freedom 19 | to share and change all versions of a program--to make sure it remains 20 | free software for all its users. We, the Free Software Foundation, use 21 | the GNU General Public License for most of our software; it applies 22 | also to any other work released this way by its authors. You can apply 23 | it to your programs, too. 24 | 25 | When we speak of free software, we are referring to freedom, not 26 | price. Our General Public Licenses are designed to make sure that you 27 | have the freedom to distribute copies of free software (and charge for 28 | them if you wish), that you receive source code or can get it if you 29 | want it, that you can change the software or use pieces of it in new 30 | free programs, and that you know you can do these things. 31 | 32 | To protect your rights, we need to prevent others from denying you 33 | these rights or asking you to surrender the rights. Therefore, you 34 | have certain responsibilities if you distribute copies of the 35 | software, or if you modify it: responsibilities to respect the freedom 36 | of others. 37 | 38 | For example, if you distribute copies of such a program, whether 39 | gratis or for a fee, you must pass on to the recipients the same 40 | freedoms that you received. You must make sure that they, too, receive 41 | or can get the source code. And you must show them these terms so they 42 | know their rights. 43 | 44 | Developers that use the GNU GPL protect your rights with two steps: 45 | (1) assert copyright on the software, and (2) offer you this License 46 | giving you legal permission to copy, distribute and/or modify it. 47 | 48 | For the developers' and authors' protection, the GPL clearly explains 49 | that there is no warranty for this free software. For both users' and 50 | authors' sake, the GPL requires that modified versions be marked as 51 | changed, so that their problems will not be attributed erroneously to 52 | authors of previous versions. 53 | 54 | Some devices are designed to deny users access to install or run 55 | modified versions of the software inside them, although the 56 | manufacturer can do so. This is fundamentally incompatible with the 57 | aim of protecting users' freedom to change the software. The 58 | systematic pattern of such abuse occurs in the area of products for 59 | individuals to use, which is precisely where it is most unacceptable. 60 | Therefore, we have designed this version of the GPL to prohibit the 61 | practice for those products. If such problems arise substantially in 62 | other domains, we stand ready to extend this provision to those 63 | domains in future versions of the GPL, as needed to protect the 64 | freedom of users. 65 | 66 | Finally, every program is threatened constantly by software patents. 67 | States should not allow patents to restrict development and use of 68 | software on general-purpose computers, but in those that do, we wish 69 | to avoid the special danger that patents applied to a free program 70 | could make it effectively proprietary. To prevent this, the GPL 71 | assures that patents cannot be used to render the program non-free. 72 | 73 | The precise terms and conditions for copying, distribution and 74 | modification follow. 75 | 76 | ## TERMS AND CONDITIONS 77 | 78 | ### 0. Definitions. 79 | 80 | "This License" refers to version 3 of the GNU General Public License. 81 | 82 | "Copyright" also means copyright-like laws that apply to other kinds 83 | of works, such as semiconductor masks. 84 | 85 | "The Program" refers to any copyrightable work licensed under this 86 | License. Each licensee is addressed as "you". "Licensees" and 87 | "recipients" may be individuals or organizations. 88 | 89 | To "modify" a work means to copy from or adapt all or part of the work 90 | in a fashion requiring copyright permission, other than the making of 91 | an exact copy. The resulting work is called a "modified version" of 92 | the earlier work or a work "based on" the earlier work. 93 | 94 | A "covered work" means either the unmodified Program or a work based 95 | on the Program. 96 | 97 | To "propagate" a work means to do anything with it that, without 98 | permission, would make you directly or secondarily liable for 99 | infringement under applicable copyright law, except executing it on a 100 | computer or modifying a private copy. Propagation includes copying, 101 | distribution (with or without modification), making available to the 102 | public, and in some countries other activities as well. 103 | 104 | To "convey" a work means any kind of propagation that enables other 105 | parties to make or receive copies. Mere interaction with a user 106 | through a computer network, with no transfer of a copy, is not 107 | conveying. 108 | 109 | An interactive user interface displays "Appropriate Legal Notices" to 110 | the extent that it includes a convenient and prominently visible 111 | feature that (1) displays an appropriate copyright notice, and (2) 112 | tells the user that there is no warranty for the work (except to the 113 | extent that warranties are provided), that licensees may convey the 114 | work under this License, and how to view a copy of this License. If 115 | the interface presents a list of user commands or options, such as a 116 | menu, a prominent item in the list meets this criterion. 117 | 118 | ### 1. Source Code. 119 | 120 | The "source code" for a work means the preferred form of the work for 121 | making modifications to it. "Object code" means any non-source form of 122 | a work. 123 | 124 | A "Standard Interface" means an interface that either is an official 125 | standard defined by a recognized standards body, or, in the case of 126 | interfaces specified for a particular programming language, one that 127 | is widely used among developers working in that language. 128 | 129 | The "System Libraries" of an executable work include anything, other 130 | than the work as a whole, that (a) is included in the normal form of 131 | packaging a Major Component, but which is not part of that Major 132 | Component, and (b) serves only to enable use of the work with that 133 | Major Component, or to implement a Standard Interface for which an 134 | implementation is available to the public in source code form. A 135 | "Major Component", in this context, means a major essential component 136 | (kernel, window system, and so on) of the specific operating system 137 | (if any) on which the executable work runs, or a compiler used to 138 | produce the work, or an object code interpreter used to run it. 139 | 140 | The "Corresponding Source" for a work in object code form means all 141 | the source code needed to generate, install, and (for an executable 142 | work) run the object code and to modify the work, including scripts to 143 | control those activities. However, it does not include the work's 144 | System Libraries, or general-purpose tools or generally available free 145 | programs which are used unmodified in performing those activities but 146 | which are not part of the work. For example, Corresponding Source 147 | includes interface definition files associated with source files for 148 | the work, and the source code for shared libraries and dynamically 149 | linked subprograms that the work is specifically designed to require, 150 | such as by intimate data communication or control flow between those 151 | subprograms and other parts of the work. 152 | 153 | The Corresponding Source need not include anything that users can 154 | regenerate automatically from other parts of the Corresponding Source. 155 | 156 | The Corresponding Source for a work in source code form is that same 157 | work. 158 | 159 | ### 2. Basic Permissions. 160 | 161 | All rights granted under this License are granted for the term of 162 | copyright on the Program, and are irrevocable provided the stated 163 | conditions are met. This License explicitly affirms your unlimited 164 | permission to run the unmodified Program. The output from running a 165 | covered work is covered by this License only if the output, given its 166 | content, constitutes a covered work. This License acknowledges your 167 | rights of fair use or other equivalent, as provided by copyright law. 168 | 169 | You may make, run and propagate covered works that you do not convey, 170 | without conditions so long as your license otherwise remains in force. 171 | You may convey covered works to others for the sole purpose of having 172 | them make modifications exclusively for you, or provide you with 173 | facilities for running those works, provided that you comply with the 174 | terms of this License in conveying all material for which you do not 175 | control copyright. Those thus making or running the covered works for 176 | you must do so exclusively on your behalf, under your direction and 177 | control, on terms that prohibit them from making any copies of your 178 | copyrighted material outside their relationship with you. 179 | 180 | Conveying under any other circumstances is permitted solely under the 181 | conditions stated below. Sublicensing is not allowed; section 10 makes 182 | it unnecessary. 183 | 184 | ### 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 185 | 186 | No covered work shall be deemed part of an effective technological 187 | measure under any applicable law fulfilling obligations under article 188 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 189 | similar laws prohibiting or restricting circumvention of such 190 | measures. 191 | 192 | When you convey a covered work, you waive any legal power to forbid 193 | circumvention of technological measures to the extent such 194 | circumvention is effected by exercising rights under this License with 195 | respect to the covered work, and you disclaim any intention to limit 196 | operation or modification of the work as a means of enforcing, against 197 | the work's users, your or third parties' legal rights to forbid 198 | circumvention of technological measures. 199 | 200 | ### 4. Conveying Verbatim Copies. 201 | 202 | You may convey verbatim copies of the Program's source code as you 203 | receive it, in any medium, provided that you conspicuously and 204 | appropriately publish on each copy an appropriate copyright notice; 205 | keep intact all notices stating that this License and any 206 | non-permissive terms added in accord with section 7 apply to the code; 207 | keep intact all notices of the absence of any warranty; and give all 208 | recipients a copy of this License along with the Program. 209 | 210 | You may charge any price or no price for each copy that you convey, 211 | and you may offer support or warranty protection for a fee. 212 | 213 | ### 5. Conveying Modified Source Versions. 214 | 215 | You may convey a work based on the Program, or the modifications to 216 | produce it from the Program, in the form of source code under the 217 | terms of section 4, provided that you also meet all of these 218 | conditions: 219 | 220 | - a) The work must carry prominent notices stating that you modified 221 | it, and giving a relevant date. 222 | - b) The work must carry prominent notices stating that it is 223 | released under this License and any conditions added under 224 | section 7. This requirement modifies the requirement in section 4 225 | to "keep intact all notices". 226 | - c) You must license the entire work, as a whole, under this 227 | License to anyone who comes into possession of a copy. This 228 | License will therefore apply, along with any applicable section 7 229 | additional terms, to the whole of the work, and all its parts, 230 | regardless of how they are packaged. This License gives no 231 | permission to license the work in any other way, but it does not 232 | invalidate such permission if you have separately received it. 233 | - d) If the work has interactive user interfaces, each must display 234 | Appropriate Legal Notices; however, if the Program has interactive 235 | interfaces that do not display Appropriate Legal Notices, your 236 | work need not make them do so. 237 | 238 | A compilation of a covered work with other separate and independent 239 | works, which are not by their nature extensions of the covered work, 240 | and which are not combined with it such as to form a larger program, 241 | in or on a volume of a storage or distribution medium, is called an 242 | "aggregate" if the compilation and its resulting copyright are not 243 | used to limit the access or legal rights of the compilation's users 244 | beyond what the individual works permit. Inclusion of a covered work 245 | in an aggregate does not cause this License to apply to the other 246 | parts of the aggregate. 247 | 248 | ### 6. Conveying Non-Source Forms. 249 | 250 | You may convey a covered work in object code form under the terms of 251 | sections 4 and 5, provided that you also convey the machine-readable 252 | Corresponding Source under the terms of this License, in one of these 253 | ways: 254 | 255 | - a) Convey the object code in, or embodied in, a physical product 256 | (including a physical distribution medium), accompanied by the 257 | Corresponding Source fixed on a durable physical medium 258 | customarily used for software interchange. 259 | - b) Convey the object code in, or embodied in, a physical product 260 | (including a physical distribution medium), accompanied by a 261 | written offer, valid for at least three years and valid for as 262 | long as you offer spare parts or customer support for that product 263 | model, to give anyone who possesses the object code either (1) a 264 | copy of the Corresponding Source for all the software in the 265 | product that is covered by this License, on a durable physical 266 | medium customarily used for software interchange, for a price no 267 | more than your reasonable cost of physically performing this 268 | conveying of source, or (2) access to copy the Corresponding 269 | Source from a network server at no charge. 270 | - c) Convey individual copies of the object code with a copy of the 271 | written offer to provide the Corresponding Source. This 272 | alternative is allowed only occasionally and noncommercially, and 273 | only if you received the object code with such an offer, in accord 274 | with subsection 6b. 275 | - d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | - e) Convey the object code using peer-to-peer transmission, 288 | provided you inform other peers where the object code and 289 | Corresponding Source of the work are being offered to the general 290 | public at no charge under subsection 6d. 291 | 292 | A separable portion of the object code, whose source code is excluded 293 | from the Corresponding Source as a System Library, need not be 294 | included in conveying the object code work. 295 | 296 | A "User Product" is either (1) a "consumer product", which means any 297 | tangible personal property which is normally used for personal, 298 | family, or household purposes, or (2) anything designed or sold for 299 | incorporation into a dwelling. In determining whether a product is a 300 | consumer product, doubtful cases shall be resolved in favor of 301 | coverage. For a particular product received by a particular user, 302 | "normally used" refers to a typical or common use of that class of 303 | product, regardless of the status of the particular user or of the way 304 | in which the particular user actually uses, or expects or is expected 305 | to use, the product. A product is a consumer product regardless of 306 | whether the product has substantial commercial, industrial or 307 | non-consumer uses, unless such uses represent the only significant 308 | mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to 312 | install and execute modified versions of a covered work in that User 313 | Product from a modified version of its Corresponding Source. The 314 | information must suffice to ensure that the continued functioning of 315 | the modified object code is in no case prevented or interfered with 316 | solely because modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or 331 | updates for a work that has been modified or installed by the 332 | recipient, or for the User Product in which it has been modified or 333 | installed. Access to a network may be denied when the modification 334 | itself materially and adversely affects the operation of the network 335 | or violates the rules and protocols for communication across the 336 | network. 337 | 338 | Corresponding Source conveyed, and Installation Information provided, 339 | in accord with this section must be in a format that is publicly 340 | documented (and with an implementation available to the public in 341 | source code form), and must require no special password or key for 342 | unpacking, reading or copying. 343 | 344 | ### 7. Additional Terms. 345 | 346 | "Additional permissions" are terms that supplement the terms of this 347 | License by making exceptions from one or more of its conditions. 348 | Additional permissions that are applicable to the entire Program shall 349 | be treated as though they were included in this License, to the extent 350 | that they are valid under applicable law. If additional permissions 351 | apply only to part of the Program, that part may be used separately 352 | under those permissions, but the entire Program remains governed by 353 | this License without regard to the additional permissions. 354 | 355 | When you convey a copy of a covered work, you may at your option 356 | remove any additional permissions from that copy, or from any part of 357 | it. (Additional permissions may be written to require their own 358 | removal in certain cases when you modify the work.) You may place 359 | additional permissions on material, added by you to a covered work, 360 | for which you have or can give appropriate copyright permission. 361 | 362 | Notwithstanding any other provision of this License, for material you 363 | add to a covered work, you may (if authorized by the copyright holders 364 | of that material) supplement the terms of this License with terms: 365 | 366 | - a) Disclaiming warranty or limiting liability differently from the 367 | terms of sections 15 and 16 of this License; or 368 | - b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | - c) Prohibiting misrepresentation of the origin of that material, 372 | or requiring that modified versions of such material be marked in 373 | reasonable ways as different from the original version; or 374 | - d) Limiting the use for publicity purposes of names of licensors 375 | or authors of the material; or 376 | - e) Declining to grant rights under trademark law for use of some 377 | trade names, trademarks, or service marks; or 378 | - f) Requiring indemnification of licensors and authors of that 379 | material by anyone who conveys the material (or modified versions 380 | of it) with contractual assumptions of liability to the recipient, 381 | for any liability that these contractual assumptions directly 382 | impose on those licensors and authors. 383 | 384 | All other non-permissive additional terms are considered "further 385 | restrictions" within the meaning of section 10. If the Program as you 386 | received it, or any part of it, contains a notice stating that it is 387 | governed by this License along with a term that is a further 388 | restriction, you may remove that term. If a license document contains 389 | a further restriction but permits relicensing or conveying under this 390 | License, you may add to a covered work material governed by the terms 391 | of that license document, provided that the further restriction does 392 | not survive such relicensing or conveying. 393 | 394 | If you add terms to a covered work in accord with this section, you 395 | must place, in the relevant source files, a statement of the 396 | additional terms that apply to those files, or a notice indicating 397 | where to find the applicable terms. 398 | 399 | Additional terms, permissive or non-permissive, may be stated in the 400 | form of a separately written license, or stated as exceptions; the 401 | above requirements apply either way. 402 | 403 | ### 8. Termination. 404 | 405 | You may not propagate or modify a covered work except as expressly 406 | provided under this License. Any attempt otherwise to propagate or 407 | modify it is void, and will automatically terminate your rights under 408 | this License (including any patent licenses granted under the third 409 | paragraph of section 11). 410 | 411 | However, if you cease all violation of this License, then your license 412 | from a particular copyright holder is reinstated (a) provisionally, 413 | unless and until the copyright holder explicitly and finally 414 | terminates your license, and (b) permanently, if the copyright holder 415 | fails to notify you of the violation by some reasonable means prior to 416 | 60 days after the cessation. 417 | 418 | Moreover, your license from a particular copyright holder is 419 | reinstated permanently if the copyright holder notifies you of the 420 | violation by some reasonable means, this is the first time you have 421 | received notice of violation of this License (for any work) from that 422 | copyright holder, and you cure the violation prior to 30 days after 423 | your receipt of the notice. 424 | 425 | Termination of your rights under this section does not terminate the 426 | licenses of parties who have received copies or rights from you under 427 | this License. If your rights have been terminated and not permanently 428 | reinstated, you do not qualify to receive new licenses for the same 429 | material under section 10. 430 | 431 | ### 9. Acceptance Not Required for Having Copies. 432 | 433 | You are not required to accept this License in order to receive or run 434 | a copy of the Program. Ancillary propagation of a covered work 435 | occurring solely as a consequence of using peer-to-peer transmission 436 | to receive a copy likewise does not require acceptance. However, 437 | nothing other than this License grants you permission to propagate or 438 | modify any covered work. These actions infringe copyright if you do 439 | not accept this License. Therefore, by modifying or propagating a 440 | covered work, you indicate your acceptance of this License to do so. 441 | 442 | ### 10. Automatic Licensing of Downstream Recipients. 443 | 444 | Each time you convey a covered work, the recipient automatically 445 | receives a license from the original licensors, to run, modify and 446 | propagate that work, subject to this License. You are not responsible 447 | for enforcing compliance by third parties with this License. 448 | 449 | An "entity transaction" is a transaction transferring control of an 450 | organization, or substantially all assets of one, or subdividing an 451 | organization, or merging organizations. If propagation of a covered 452 | work results from an entity transaction, each party to that 453 | transaction who receives a copy of the work also receives whatever 454 | licenses to the work the party's predecessor in interest had or could 455 | give under the previous paragraph, plus a right to possession of the 456 | Corresponding Source of the work from the predecessor in interest, if 457 | the predecessor has it or can get it with reasonable efforts. 458 | 459 | You may not impose any further restrictions on the exercise of the 460 | rights granted or affirmed under this License. For example, you may 461 | not impose a license fee, royalty, or other charge for exercise of 462 | rights granted under this License, and you may not initiate litigation 463 | (including a cross-claim or counterclaim in a lawsuit) alleging that 464 | any patent claim is infringed by making, using, selling, offering for 465 | sale, or importing the Program or any portion of it. 466 | 467 | ### 11. Patents. 468 | 469 | A "contributor" is a copyright holder who authorizes use under this 470 | License of the Program or a work on which the Program is based. The 471 | work thus licensed is called the contributor's "contributor version". 472 | 473 | A contributor's "essential patent claims" are all patent claims owned 474 | or controlled by the contributor, whether already acquired or 475 | hereafter acquired, that would be infringed by some manner, permitted 476 | by this License, of making, using, or selling its contributor version, 477 | but do not include claims that would be infringed only as a 478 | consequence of further modification of the contributor version. For 479 | purposes of this definition, "control" includes the right to grant 480 | patent sublicenses in a manner consistent with the requirements of 481 | this License. 482 | 483 | Each contributor grants you a non-exclusive, worldwide, royalty-free 484 | patent license under the contributor's essential patent claims, to 485 | make, use, sell, offer for sale, import and otherwise run, modify and 486 | propagate the contents of its contributor version. 487 | 488 | In the following three paragraphs, a "patent license" is any express 489 | agreement or commitment, however denominated, not to enforce a patent 490 | (such as an express permission to practice a patent or covenant not to 491 | sue for patent infringement). To "grant" such a patent license to a 492 | party means to make such an agreement or commitment not to enforce a 493 | patent against the party. 494 | 495 | If you convey a covered work, knowingly relying on a patent license, 496 | and the Corresponding Source of the work is not available for anyone 497 | to copy, free of charge and under the terms of this License, through a 498 | publicly available network server or other readily accessible means, 499 | then you must either (1) cause the Corresponding Source to be so 500 | available, or (2) arrange to deprive yourself of the benefit of the 501 | patent license for this particular work, or (3) arrange, in a manner 502 | consistent with the requirements of this License, to extend the patent 503 | license to downstream recipients. "Knowingly relying" means you have 504 | actual knowledge that, but for the patent license, your conveying the 505 | covered work in a country, or your recipient's use of the covered work 506 | in a country, would infringe one or more identifiable patents in that 507 | country that you have reason to believe are valid. 508 | 509 | If, pursuant to or in connection with a single transaction or 510 | arrangement, you convey, or propagate by procuring conveyance of, a 511 | covered work, and grant a patent license to some of the parties 512 | receiving the covered work authorizing them to use, propagate, modify 513 | or convey a specific copy of the covered work, then the patent license 514 | you grant is automatically extended to all recipients of the covered 515 | work and works based on it. 516 | 517 | A patent license is "discriminatory" if it does not include within the 518 | scope of its coverage, prohibits the exercise of, or is conditioned on 519 | the non-exercise of one or more of the rights that are specifically 520 | granted under this License. You may not convey a covered work if you 521 | are a party to an arrangement with a third party that is in the 522 | business of distributing software, under which you make payment to the 523 | third party based on the extent of your activity of conveying the 524 | work, and under which the third party grants, to any of the parties 525 | who would receive the covered work from you, a discriminatory patent 526 | license (a) in connection with copies of the covered work conveyed by 527 | you (or copies made from those copies), or (b) primarily for and in 528 | connection with specific products or compilations that contain the 529 | covered work, unless you entered into that arrangement, or that patent 530 | license was granted, prior to 28 March 2007. 531 | 532 | Nothing in this License shall be construed as excluding or limiting 533 | any implied license or other defenses to infringement that may 534 | otherwise be available to you under applicable patent law. 535 | 536 | ### 12. No Surrender of Others' Freedom. 537 | 538 | If conditions are imposed on you (whether by court order, agreement or 539 | otherwise) that contradict the conditions of this License, they do not 540 | excuse you from the conditions of this License. If you cannot convey a 541 | covered work so as to satisfy simultaneously your obligations under 542 | this License and any other pertinent obligations, then as a 543 | consequence you may not convey it at all. For example, if you agree to 544 | terms that obligate you to collect a royalty for further conveying 545 | from those to whom you convey the Program, the only way you could 546 | satisfy both those terms and this License would be to refrain entirely 547 | from conveying the Program. 548 | 549 | ### 13. Use with the GNU Affero General Public License. 550 | 551 | Notwithstanding any other provision of this License, you have 552 | permission to link or combine any covered work with a work licensed 553 | under version 3 of the GNU Affero General Public License into a single 554 | combined work, and to convey the resulting work. The terms of this 555 | License will continue to apply to the part which is the covered work, 556 | but the special requirements of the GNU Affero General Public License, 557 | section 13, concerning interaction through a network will apply to the 558 | combination as such. 559 | 560 | ### 14. Revised Versions of this License. 561 | 562 | The Free Software Foundation may publish revised and/or new versions 563 | of the GNU General Public License from time to time. Such new versions 564 | will be similar in spirit to the present version, but may differ in 565 | detail to address new problems or concerns. 566 | 567 | Each version is given a distinguishing version number. If the Program 568 | specifies that a certain numbered version of the GNU General Public 569 | License "or any later version" applies to it, you have the option of 570 | following the terms and conditions either of that numbered version or 571 | of any later version published by the Free Software Foundation. If the 572 | Program does not specify a version number of the GNU General Public 573 | License, you may choose any version ever published by the Free 574 | Software Foundation. 575 | 576 | If the Program specifies that a proxy can decide which future versions 577 | of the GNU General Public License can be used, that proxy's public 578 | statement of acceptance of a version permanently authorizes you to 579 | choose that version for the Program. 580 | 581 | Later license versions may give you additional or different 582 | permissions. However, no additional obligations are imposed on any 583 | author or copyright holder as a result of your choosing to follow a 584 | later version. 585 | 586 | ### 15. Disclaimer of Warranty. 587 | 588 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 589 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 590 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT 591 | WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT 592 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 593 | A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND 594 | PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE 595 | DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR 596 | CORRECTION. 597 | 598 | ### 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR 602 | CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 603 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES 604 | ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT 605 | NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 606 | LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM 607 | TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER 608 | PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 609 | 610 | ### 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | ## How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these 626 | terms. 627 | 628 | To do so, attach the following notices to the program. It is safest to 629 | attach them to the start of each source file to most effectively state 630 | the exclusion of warranty; and each file should have at least the 631 | "copyright" line and a pointer to where the full notice is found. 632 | 633 | 634 | Copyright (C) 635 | 636 | This program is free software: you can redistribute it and/or modify 637 | it under the terms of the GNU General Public License as published by 638 | the Free Software Foundation, either version 3 of the License, or 639 | (at your option) any later version. 640 | 641 | This program is distributed in the hope that it will be useful, 642 | but WITHOUT ANY WARRANTY; without even the implied warranty of 643 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 644 | GNU General Public License for more details. 645 | 646 | You should have received a copy of the GNU General Public License 647 | along with this program. If not, see . 648 | 649 | Also add information on how to contact you by electronic and paper 650 | mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands \`show w' and \`show c' should show the 661 | appropriate parts of the General Public License. Of course, your 662 | program's commands might be different; for a GUI interface, you would 663 | use an "about box". 664 | 665 | You should also get your employer (if you work as a programmer) or 666 | school, if any, to sign a "copyright disclaimer" for the program, if 667 | necessary. For more information on this, and how to apply and follow 668 | the GNU GPL, see . 669 | 670 | The GNU General Public License does not permit incorporating your 671 | program into proprietary programs. If your program is a subroutine 672 | library, you may consider it more useful to permit linking proprietary 673 | applications with the library. If this is what you want to do, use the 674 | GNU Lesser General Public License instead of this License. But first, 675 | please read . 676 | -------------------------------------------------------------------------------- /Mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/Mobile.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Dijkstra Bootstrap 3 | Dijkstra Solver dal design efficace per creare e caricare esercizi su Dijkstra con visualizzazione di **Tutti i Cammini Minimi** e con **Archi Direzionabili** 4 | 5 | > [!NOTE] 6 | > Progetto scolastico 🎓 · Ⅳ 7 | 8 | 9 | 10 | --- 11 | 12 | ## Ispirazione 13 | 14 | La grafica del sito web è stata sviluppata riproponendo l'interfaccia utente offerta da [Scheduling Solver](https://process-scheduling-solver.boonsuen.com/) 15 | 16 | 17 | 18 | 19 | ## Utilizzo 20 | 21 | **Generare Esercizi** è possibile caricando i **file json** dei nodi e degli archi per rappresentare i grafici 22 | 23 | 24 | L'utente effettua il **Doppio Click** su uno di questi elementi del Grafo per: 25 | | Sfondo| Nodo | Arco | 26 | | ------------ | ------------ | ------------ | 27 | | Icona | Icona | Icona| 28 | | Nuovo Nodo | Crea Arco | Elimina Arco | 29 | | | Elimina Nodo | Direziona Arco | 30 | | | | Sdoppia Arco | 31 | | | | Modifica Arco | 32 | 33 | > Gifs from [website](https://vittoriopiotti.altervista.org/Dijkstra/index.html) 34 | 35 | 36 | ## Preview 37 | 38 | Sito Web: [Link al Sito](https://vittoriopiotti.altervista.org/Dijkstra/index.html) 39 | 40 | --- 41 | 42 | | Icona | Icona | 43 | | ------------ | ------------ | 44 | 45 | > Screenshots from [website](https://vittoriopiotti.altervista.org/Dijkstra/index.html) 46 | 47 | 48 | 49 | 50 | 51 | ## Licenze 52 | 53 | 54 | 55 | ### DijkstraSolver 56 | 57 | **Copyright** 2024 Vittorio Piotti [(GitHub page)](https://github.com/vittorioPiotti) [(Personal page)](https://vittoriopiotti.altervista.org/) 58 | 59 | **Version** [v1.0.0](https://github.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/releases/tag/v1.0.0) 60 | 61 | **License** [GPL-3.0](https://github.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/blob/main/LICENSE.md) 62 | 63 | --- 64 | 65 | ### Bootstrap 66 | 67 | **Copyright** 2011-2018 The Bootstrap Authors 68 | 69 | **Version** [v5.2](https://github.com/twbs/bootstrap/releases/tag/v5.2.0) 70 | 71 | **License** [MIT](https://github.com/twbs/bootstrap/blob/main/LICENSE) 72 | 73 | 74 | 75 | 76 | --- 77 | 78 | ### vis.js 79 | 80 | **Copyright** 2011-2017 Almende B.V, [http://almende.com](http://almende.com) 81 | 82 | **Version** [4.21.0](https://github.com/almende/vis/releases/tag/v4.21.0) 83 | 84 | **License** [Apache 2.0](http://www.apache.org/licenses/LICENSE-2.0), [MIT](http://opensource.org/licenses/MIT) 85 | 86 | 87 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /clickArco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clickArco.png -------------------------------------------------------------------------------- /clickNodo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clickNodo.png -------------------------------------------------------------------------------- /clickSfondo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clickSfondo.png -------------------------------------------------------------------------------- /clickarco.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clickarco.gif -------------------------------------------------------------------------------- /clicknodo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clicknodo.gif -------------------------------------------------------------------------------- /clicksfondo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/clicksfondo.gif -------------------------------------------------------------------------------- /css/main.css: -------------------------------------------------------------------------------- 1 | /* 2 | Dijkstra-Bootstrap v1.0.0 (https://github.com/vittorioPiotti/Dijkstra-Bootstrap/releases/tag/v1.0.0) 3 | Copyright 2024 Vittorio Piotti 4 | Licensed under GPL-3.0 (https://github.com/vittorioPiotti/Dijkstra-Bootstrap/blob/main/LICENSE.md) 5 | */ 6 | 7 | 8 | .pointer {cursor: pointer;} 9 | .pointer:hover{ 10 | background-color: rgb(211, 211, 211); 11 | } 12 | #network { 13 | width: 100%; 14 | height: 350px; 15 | border: none; 16 | } 17 | .modal { 18 | cursor: default; 19 | } 20 | #linkGitHub{ 21 | text-decoration: none; 22 | color: black; 23 | transition:0.5s; 24 | } 25 | 26 | #linkGitHub:hover { 27 | color: #008cff; 28 | transition:0.5s; 29 | } 30 | #output{ 31 | user-select: none; 32 | } 33 | -------------------------------------------------------------------------------- /css/vis-network.min.css: -------------------------------------------------------------------------------- 1 | .vis .overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.vis-active{box-shadow:0 0 10px #86d5f8}.vis [class*=span]{min-height:0;width:auto}div.vis-configuration{position:relative;display:block;float:left;font-size:12px}div.vis-configuration-wrapper{display:block;width:700px}div.vis-configuration-wrapper::after{clear:both;content:"";display:block}div.vis-configuration.vis-config-option-container{display:block;width:495px;background-color:#fff;border:2px solid #f7f8fa;border-radius:4px;margin-top:20px;left:10px;padding-left:5px}div.vis-configuration.vis-config-button{display:block;width:495px;height:25px;vertical-align:middle;line-height:25px;background-color:#f7f8fa;border:2px solid #ceced0;border-radius:4px;margin-top:20px;left:10px;padding-left:5px;cursor:pointer;margin-bottom:30px}div.vis-configuration.vis-config-button.hover{background-color:#4588e6;border:2px solid #214373;color:#fff}div.vis-configuration.vis-config-item{display:block;float:left;width:495px;height:25px;vertical-align:middle;line-height:25px}div.vis-configuration.vis-config-item.vis-config-s2{left:10px;background-color:#f7f8fa;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s3{left:20px;background-color:#e4e9f0;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-item.vis-config-s4{left:30px;background-color:#cfd8e6;padding-left:5px;border-radius:3px}div.vis-configuration.vis-config-header{font-size:18px;font-weight:700}div.vis-configuration.vis-config-label{width:120px;height:25px;line-height:25px}div.vis-configuration.vis-config-label.vis-config-s3{width:110px}div.vis-configuration.vis-config-label.vis-config-s4{width:100px}div.vis-configuration.vis-config-colorBlock{top:1px;width:30px;height:19px;border:1px solid #444;border-radius:2px;padding:0;margin:0;cursor:pointer}input.vis-configuration.vis-config-checkbox{left:-5px}input.vis-configuration.vis-config-rangeinput{position:relative;top:-5px;width:60px;padding:1px;margin:0;pointer-events:none}input.vis-configuration.vis-config-range{-webkit-appearance:none;border:0 solid #fff;background-color:rgba(0,0,0,0);width:300px;height:20px}input.vis-configuration.vis-config-range::-webkit-slider-runnable-track{width:300px;height:5px;background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(to bottom,#dedede 0,#c8c8c8 99%);border:1px solid #999;box-shadow:#aaa 0 0 3px 0;border-radius:3px}input.vis-configuration.vis-config-range::-webkit-slider-thumb{-webkit-appearance:none;border:1px solid #14334b;height:17px;width:17px;border-radius:50%;background:#3876c2;background:-moz-linear-gradient(top,#3876c2 0,#385380 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#3876c2),color-stop(100%,#385380));background:-webkit-linear-gradient(top,#3876c2 0,#385380 100%);background:-o-linear-gradient(top,#3876c2 0,#385380 100%);background:-ms-linear-gradient(top,#3876c2 0,#385380 100%);background:linear-gradient(to bottom,#3876c2 0,#385380 100%);box-shadow:#111927 0 0 1px 0;margin-top:-7px}input.vis-configuration.vis-config-range:focus{outline:0}input.vis-configuration.vis-config-range:focus::-webkit-slider-runnable-track{background:#9d9d9d;background:-moz-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#9d9d9d),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-o-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#9d9d9d 0,#c8c8c8 99%);background:linear-gradient(to bottom,#9d9d9d 0,#c8c8c8 99%)}input.vis-configuration.vis-config-range::-moz-range-track{width:300px;height:10px;background:#dedede;background:-moz-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#dedede),color-stop(99%,#c8c8c8));background:-webkit-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-o-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:-ms-linear-gradient(top,#dedede 0,#c8c8c8 99%);background:linear-gradient(to bottom,#dedede 0,#c8c8c8 99%);border:1px solid #999;box-shadow:#aaa 0 0 3px 0;border-radius:3px}input.vis-configuration.vis-config-range::-moz-range-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:-moz-focusring{outline:1px solid #fff;outline-offset:-1px}input.vis-configuration.vis-config-range::-ms-track{width:300px;height:5px;background:0 0;border-color:transparent;border-width:6px 0;color:transparent}input.vis-configuration.vis-config-range::-ms-fill-lower{background:#777;border-radius:10px}input.vis-configuration.vis-config-range::-ms-fill-upper{background:#ddd;border-radius:10px}input.vis-configuration.vis-config-range::-ms-thumb{border:none;height:16px;width:16px;border-radius:50%;background:#385380}input.vis-configuration.vis-config-range:focus::-ms-fill-lower{background:#888}input.vis-configuration.vis-config-range:focus::-ms-fill-upper{background:#ccc}.vis-configuration-popup{position:absolute;background:rgba(57,76,89,.85);border:2px solid #f2faff;line-height:30px;height:30px;width:150px;text-align:center;color:#fff;font-size:14px;border-radius:4px;-webkit-transition:opacity .3s ease-in-out;-moz-transition:opacity .3s ease-in-out;transition:opacity .3s ease-in-out}.vis-configuration-popup:after,.vis-configuration-popup:before{left:100%;top:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}.vis-configuration-popup:after{border-color:rgba(136,183,213,0);border-left-color:rgba(57,76,89,.85);border-width:8px;margin-top:-8px}.vis-configuration-popup:before{border-color:rgba(194,225,245,0);border-left-color:#f2faff;border-width:12px;margin-top:-12px}div.vis-tooltip{position:absolute;visibility:hidden;padding:5px;white-space:nowrap;font-family:verdana;font-size:14px;color:#000;background-color:#f5f4ed;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;border:1px solid #808074;box-shadow:3px 3px 10px rgba(0,0,0,.2);pointer-events:none;z-index:5}div.vis-color-picker{position:absolute;top:0;left:30px;margin-top:-140px;margin-left:30px;width:310px;height:444px;z-index:1;padding:10px;border-radius:15px;background-color:#fff;display:none;box-shadow:rgba(0,0,0,.5) 0 0 10px 0}div.vis-color-picker div.vis-arrow{position:absolute;top:147px;left:5px}div.vis-color-picker div.vis-arrow::after,div.vis-color-picker div.vis-arrow::before{right:100%;top:50%;border:solid transparent;content:" ";height:0;width:0;position:absolute;pointer-events:none}div.vis-color-picker div.vis-arrow:after{border-color:rgba(255,255,255,0);border-right-color:#fff;border-width:30px;margin-top:-30px}div.vis-color-picker div.vis-color{position:absolute;width:289px;height:289px;cursor:pointer}div.vis-color-picker div.vis-brightness{position:absolute;top:313px}div.vis-color-picker div.vis-opacity{position:absolute;top:350px}div.vis-color-picker div.vis-selector{position:absolute;top:137px;left:137px;width:15px;height:15px;border-radius:15px;border:1px solid #fff;background:#4c4c4c;background:-moz-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4c4c4c),color-stop(12%,#595959),color-stop(25%,#666),color-stop(39%,#474747),color-stop(50%,#2c2c2c),color-stop(51%,#000),color-stop(60%,#111),color-stop(76%,#2b2b2b),color-stop(91%,#1c1c1c),color-stop(100%,#131313));background:-webkit-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-o-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:-ms-linear-gradient(top,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%);background:linear-gradient(to bottom,#4c4c4c 0,#595959 12%,#666 25%,#474747 39%,#2c2c2c 50%,#000 51%,#111 60%,#2b2b2b 76%,#1c1c1c 91%,#131313 100%)}div.vis-color-picker div.vis-new-color{position:absolute;width:140px;height:20px;border:1px solid rgba(0,0,0,.1);border-radius:5px;top:380px;left:159px;text-align:right;padding-right:2px;font-size:10px;color:rgba(0,0,0,.4);vertical-align:middle;line-height:20px}div.vis-color-picker div.vis-initial-color{position:absolute;width:140px;height:20px;border:1px solid rgba(0,0,0,.1);border-radius:5px;top:380px;left:10px;text-align:left;padding-left:2px;font-size:10px;color:rgba(0,0,0,.4);vertical-align:middle;line-height:20px}div.vis-color-picker div.vis-label{position:absolute;width:300px;left:10px}div.vis-color-picker div.vis-label.vis-brightness{top:300px}div.vis-color-picker div.vis-label.vis-opacity{top:338px}div.vis-color-picker div.vis-button{position:absolute;width:68px;height:25px;border-radius:10px;vertical-align:middle;text-align:center;line-height:25px;top:410px;border:2px solid #d9d9d9;background-color:#f7f7f7;cursor:pointer}div.vis-color-picker div.vis-button.vis-cancel{left:5px}div.vis-color-picker div.vis-button.vis-load{left:82px}div.vis-color-picker div.vis-button.vis-apply{left:159px}div.vis-color-picker div.vis-button.vis-save{left:236px}div.vis-color-picker input.vis-range{width:290px;height:20px}div.vis-network div.vis-manipulation{box-sizing:content-box;border-width:0;border-bottom:1px;border-style:solid;border-color:#d6d9d8;background:#fff;background:-moz-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,#fff),color-stop(48%,#fcfcfc),color-stop(50%,#fafafa),color-stop(100%,#fcfcfc));background:-webkit-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-o-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:-ms-linear-gradient(top,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);background:linear-gradient(to bottom,#fff 0,#fcfcfc 48%,#fafafa 50%,#fcfcfc 100%);padding-top:4px;position:absolute;left:0;top:0;width:100%;height:28px}div.vis-network div.vis-edit-mode{position:absolute;left:0;top:5px;height:30px}div.vis-network div.vis-close{position:absolute;right:0;top:0;width:30px;height:30px;background-position:20px 3px;background-repeat:no-repeat;background-image:url(img/network/cross.png);cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-close:hover{opacity:.6}div.vis-network div.vis-edit-mode div.vis-button,div.vis-network div.vis-manipulation div.vis-button{float:left;font-family:verdana;font-size:12px;-moz-border-radius:15px;border-radius:15px;display:inline-block;background-position:0 0;background-repeat:no-repeat;height:24px;margin-left:10px;cursor:pointer;padding:0 8px 0 8px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-manipulation div.vis-button:hover{box-shadow:1px 1px 8px rgba(0,0,0,.2)}div.vis-network div.vis-manipulation div.vis-button:active{box-shadow:1px 1px 8px rgba(0,0,0,.5)}div.vis-network div.vis-manipulation div.vis-button.vis-back{background-image:url(img/network/backIcon.png)}div.vis-network div.vis-manipulation div.vis-button.vis-none:hover{box-shadow:1px 1px 8px transparent;cursor:default}div.vis-network div.vis-manipulation div.vis-button.vis-none:active{box-shadow:1px 1px 8px transparent}div.vis-network div.vis-manipulation div.vis-button.vis-none{padding:0}div.vis-network div.vis-manipulation div.notification{margin:2px;font-weight:700}div.vis-network div.vis-manipulation div.vis-button.vis-add{background-image:url(img/network/addNodeIcon.png)}div.vis-network div.vis-edit-mode div.vis-button.vis-edit,div.vis-network div.vis-manipulation div.vis-button.vis-edit{background-image:url(img/network/editIcon.png)}div.vis-network div.vis-edit-mode div.vis-button.vis-edit.vis-edit-mode{background-color:#fcfcfc;border:1px solid #ccc}div.vis-network div.vis-manipulation div.vis-button.vis-connect{background-image:url(img/network/connectIcon.png)}div.vis-network div.vis-manipulation div.vis-button.vis-delete{background-image:url(img/network/deleteIcon.png)}div.vis-network div.vis-edit-mode div.vis-label,div.vis-network div.vis-manipulation div.vis-label{margin:0 0 0 23px;line-height:25px}div.vis-network div.vis-manipulation div.vis-separator-line{float:left;display:inline-block;width:1px;height:21px;background-color:#bdbdbd;margin:0 7px 0 15px}div.vis-network div.vis-navigation div.vis-button{width:34px;height:34px;-moz-border-radius:17px;border-radius:17px;position:absolute;display:inline-block;background-position:2px 2px;background-repeat:no-repeat;cursor:pointer;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}div.vis-network div.vis-navigation div.vis-button:hover{box-shadow:0 0 3px 3px rgba(56,207,21,.3)}div.vis-network div.vis-navigation div.vis-button:active{box-shadow:0 0 1px 3px rgba(56,207,21,.95)}div.vis-network div.vis-navigation div.vis-button.vis-up{background-image:url(img/network/upArrow.png);bottom:50px;left:55px}div.vis-network div.vis-navigation div.vis-button.vis-down{background-image:url(img/network/downArrow.png);bottom:10px;left:55px}div.vis-network div.vis-navigation div.vis-button.vis-left{background-image:url(img/network/leftArrow.png);bottom:10px;left:15px}div.vis-network div.vis-navigation div.vis-button.vis-right{background-image:url(img/network/rightArrow.png);bottom:10px;left:95px}div.vis-network div.vis-navigation div.vis-button.vis-zoomIn{background-image:url(img/network/plus.png);bottom:10px;right:15px}div.vis-network div.vis-navigation div.vis-button.vis-zoomOut{background-image:url(img/network/minus.png);bottom:10px;right:55px}div.vis-network div.vis-navigation div.vis-button.vis-zoomExtends{background-image:url(img/network/zoomExtends.png);bottom:50px;right:15px} -------------------------------------------------------------------------------- /desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/desktop.png -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/edges.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "from": 1, 5 | "to": 2, 6 | "label": " 4 ", 7 | "arrowTo": true, 8 | "arrowFrom": false 9 | }, 10 | { 11 | "id": 2, 12 | "from": 2, 13 | "to": 4, 14 | "label": " 2 ", 15 | "arrowTo": false, 16 | "arrowFrom": true 17 | }, 18 | { 19 | "id": 3, 20 | "from": 3, 21 | "to": 2, 22 | "label": " 2 ", 23 | "arrowTo": true, 24 | "arrowFrom": false 25 | }, 26 | { 27 | "id": 4, 28 | "from": 4, 29 | "to": 1, 30 | "label": " 2 ", 31 | "arrowTo": false, 32 | "arrowFrom": true 33 | }, 34 | { 35 | "id": 5, 36 | "from": 1, 37 | "to": 3, 38 | "label": " 2 ", 39 | "arrowTo": true, 40 | "arrowFrom": false 41 | }, 42 | { 43 | "id": 7, 44 | "from": "2", 45 | "to": "5", 46 | "label": " 1 ", 47 | "arrowTo": false, 48 | "arrowFrom": true 49 | }, 50 | { 51 | "id": 14, 52 | "from": "3", 53 | "to": "5", 54 | "label": " 1 ", 55 | "arrowTo": true, 56 | "arrowFrom": false 57 | } 58 | ] -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/grafo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es1-5nodi1verso/grafo.png -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1", 4 | "label": " A " 5 | }, 6 | { 7 | "id": "2", 8 | "label": " B " 9 | }, 10 | { 11 | "id": "3", 12 | "label": " C " 13 | }, 14 | { 15 | "id": "4", 16 | "label": " D " 17 | }, 18 | { 19 | "id": "5", 20 | "label": " E " 21 | } 22 | ] -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/soluzione1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es1-5nodi1verso/soluzione1.png -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/soluzione2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es1-5nodi1verso/soluzione2.png -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/soluzione3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es1-5nodi1verso/soluzione3.png -------------------------------------------------------------------------------- /eserciziDefault/es1-5nodi1verso/soluzione4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es1-5nodi1verso/soluzione4.png -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/edges.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "from": 1, 5 | "to": 2, 6 | "label": " 8 ", 7 | "arrowTo": true, 8 | "arrowFrom": false 9 | }, 10 | { 11 | "id": 2, 12 | "from": 2, 13 | "to": 4, 14 | "label": " 6 ", 15 | "arrowTo": false, 16 | "arrowFrom": true 17 | }, 18 | { 19 | "id": 3, 20 | "from": 3, 21 | "to": 2, 22 | "label": " 4 ", 23 | "arrowTo": true, 24 | "arrowFrom": false 25 | }, 26 | { 27 | "id": 4, 28 | "from": 4, 29 | "to": 1, 30 | "label": " 2 ", 31 | "arrowTo": false, 32 | "arrowFrom": true 33 | }, 34 | { 35 | "id": 5, 36 | "from": 1, 37 | "to": 3, 38 | "label": " 4 ", 39 | "arrowTo": true, 40 | "arrowFrom": false 41 | }, 42 | { 43 | "id": 7, 44 | "from": "2", 45 | "to": "5", 46 | "label": " 2 ", 47 | "arrowTo": false, 48 | "arrowFrom": true 49 | }, 50 | { 51 | "id": 14, 52 | "from": "3", 53 | "to": "5", 54 | "label": " 2 ", 55 | "arrowTo": true, 56 | "arrowFrom": false 57 | }, 58 | { 59 | "id": 18, 60 | "from": "1", 61 | "to": "8", 62 | "label": " 1 ", 63 | "arrowTo": true, 64 | "arrowFrom": false 65 | }, 66 | { 67 | "id": 20, 68 | "from": "8", 69 | "to": "4", 70 | "label": " 1 ", 71 | "arrowTo": true, 72 | "arrowFrom": false 73 | }, 74 | { 75 | "id": 21, 76 | "from": "10", 77 | "to": "8", 78 | "label": " 5 ", 79 | "arrowTo": true, 80 | "arrowFrom": false 81 | }, 82 | { 83 | "id": 23, 84 | "from": "10", 85 | "to": "4", 86 | "label": " 2 ", 87 | "arrowTo": true, 88 | "arrowFrom": false 89 | }, 90 | { 91 | "id": 24, 92 | "from": "12", 93 | "to": "2", 94 | "label": " 4 ", 95 | "arrowTo": true, 96 | "arrowFrom": false 97 | }, 98 | { 99 | "id": 27, 100 | "from": "11", 101 | "to": "12", 102 | "label": " 2 ", 103 | "arrowTo": true, 104 | "arrowFrom": false 105 | }, 106 | { 107 | "id": 28, 108 | "from": "14", 109 | "to": "10", 110 | "label": " 1 ", 111 | "arrowTo": true, 112 | "arrowFrom": false 113 | }, 114 | { 115 | "id": 29, 116 | "from": "14", 117 | "to": "4", 118 | "label": " 2 ", 119 | "arrowTo": true, 120 | "arrowFrom": false 121 | }, 122 | { 123 | "id": 30, 124 | "from": "14", 125 | "to": "11", 126 | "label": " 2 ", 127 | "arrowTo": true, 128 | "arrowFrom": false 129 | }, 130 | { 131 | "id": 31, 132 | "from": "11", 133 | "to": "2", 134 | "label": " 3 ", 135 | "arrowTo": true, 136 | "arrowFrom": false 137 | }, 138 | { 139 | "id": 32, 140 | "from": "2", 141 | "to": "14", 142 | "label": " 1 ", 143 | "arrowTo": true, 144 | "arrowFrom": false 145 | }, 146 | { 147 | "id": 33, 148 | "from": "12", 149 | "to": "5", 150 | "label": " 2 ", 151 | "arrowTo": false, 152 | "arrowFrom": true 153 | } 154 | ] -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/grafo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es2-10nodi1verso/grafo.png -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1", 4 | "label": " A " 5 | }, 6 | { 7 | "id": "2", 8 | "label": " B " 9 | }, 10 | { 11 | "id": "3", 12 | "label": " C " 13 | }, 14 | { 15 | "id": "4", 16 | "label": " D " 17 | }, 18 | { 19 | "id": "5", 20 | "label": " E " 21 | }, 22 | { 23 | "id": "8", 24 | "label": " H " 25 | }, 26 | { 27 | "id": "10", 28 | "label": " I " 29 | }, 30 | { 31 | "id": "11", 32 | "label": " F " 33 | }, 34 | { 35 | "id": "12", 36 | "label": " G " 37 | }, 38 | { 39 | "id": "14", 40 | "label": " J " 41 | } 42 | ] -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/soluzione1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es2-10nodi1verso/soluzione1.png -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/soluzione2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es2-10nodi1verso/soluzione2.png -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/soluzione3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es2-10nodi1verso/soluzione3.png -------------------------------------------------------------------------------- /eserciziDefault/es2-10nodi1verso/soluzione4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es2-10nodi1verso/soluzione4.png -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/edges.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "from": 1, 5 | "to": 2, 6 | "label": " 12 ", 7 | "arrowTo": true, 8 | "arrowFrom": false 9 | }, 10 | { 11 | "id": 2, 12 | "from": 2, 13 | "to": 4, 14 | "label": " 1 ", 15 | "arrowTo": true, 16 | "arrowFrom": false 17 | }, 18 | { 19 | "id": 3, 20 | "from": 3, 21 | "to": 2, 22 | "label": " 3 ", 23 | "arrowTo": false, 24 | "arrowFrom": false 25 | }, 26 | { 27 | "id": 4, 28 | "from": 4, 29 | "to": 1, 30 | "label": " 3 ", 31 | "arrowTo": false, 32 | "arrowFrom": false 33 | }, 34 | { 35 | "id": 5, 36 | "from": 1, 37 | "to": 3, 38 | "label": " 3 ", 39 | "arrowTo": false, 40 | "arrowFrom": false 41 | }, 42 | { 43 | "id": 6, 44 | "from": "7", 45 | "to": "2", 46 | "label": " 3 ", 47 | "arrowTo": false, 48 | "arrowFrom": false 49 | }, 50 | { 51 | "id": 7, 52 | "from": "4", 53 | "to": "7", 54 | "label": " 2 ", 55 | "arrowTo": true, 56 | "arrowFrom": false 57 | }, 58 | { 59 | "id": 8, 60 | "from": "5", 61 | "to": "7", 62 | "label": " 3 ", 63 | "arrowTo": true, 64 | "arrowFrom": false 65 | }, 66 | { 67 | "id": 9, 68 | "from": "6", 69 | "to": "5", 70 | "label": " 3 ", 71 | "arrowTo": false, 72 | "arrowFrom": false 73 | }, 74 | { 75 | "id": 10, 76 | "from": "3", 77 | "to": "6", 78 | "label": " 1 ", 79 | "arrowTo": false, 80 | "arrowFrom": false 81 | }, 82 | { 83 | "id": 11, 84 | "from": "6", 85 | "to": "2", 86 | "label": " 2 ", 87 | "arrowTo": true, 88 | "arrowFrom": false 89 | }, 90 | { 91 | "id": 12, 92 | "from": "5", 93 | "to": "2", 94 | "label": " 1 ", 95 | "arrowTo": true, 96 | "arrowFrom": false 97 | }, 98 | { 99 | "id": 13, 100 | "from": 1, 101 | "to": 2, 102 | "label": " 2 ", 103 | "arrowTo": false, 104 | "arrowFrom": true 105 | }, 106 | { 107 | "id": 14, 108 | "from": "5", 109 | "to": "2", 110 | "label": " 1 ", 111 | "arrowTo": false, 112 | "arrowFrom": true 113 | }, 114 | { 115 | "id": 15, 116 | "from": "6", 117 | "to": "2", 118 | "label": " 5 ", 119 | "arrowTo": false, 120 | "arrowFrom": true 121 | }, 122 | { 123 | "id": 16, 124 | "from": 2, 125 | "to": 4, 126 | "label": " 3 ", 127 | "arrowTo": false, 128 | "arrowFrom": true 129 | }, 130 | { 131 | "id": 17, 132 | "from": "8", 133 | "to": "4", 134 | "label": " 3 ", 135 | "arrowTo": true, 136 | "arrowFrom": false 137 | }, 138 | { 139 | "id": 18, 140 | "from": "8", 141 | "to": "7", 142 | "label": " 3 ", 143 | "arrowTo": false, 144 | "arrowFrom": false 145 | }, 146 | { 147 | "id": 19, 148 | "from": "7", 149 | "to": "9", 150 | "label": " 3 ", 151 | "arrowTo": false, 152 | "arrowFrom": false 153 | }, 154 | { 155 | "id": 20, 156 | "from": "9", 157 | "to": "5", 158 | "label": " 3 ", 159 | "arrowTo": false, 160 | "arrowFrom": true 161 | }, 162 | { 163 | "id": 21, 164 | "from": "3", 165 | "to": "10", 166 | "label": " 3 ", 167 | "arrowTo": false, 168 | "arrowFrom": false 169 | }, 170 | { 171 | "id": 22, 172 | "from": "6", 173 | "to": "10", 174 | "label": " 1 ", 175 | "arrowTo": true, 176 | "arrowFrom": false 177 | }, 178 | { 179 | "id": 23, 180 | "from": "11", 181 | "to": "3", 182 | "label": " 2 ", 183 | "arrowTo": true, 184 | "arrowFrom": false 185 | }, 186 | { 187 | "id": 24, 188 | "from": "11", 189 | "to": "1", 190 | "label": " 2 ", 191 | "arrowTo": false, 192 | "arrowFrom": false 193 | } 194 | ] -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/grafo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es3-grafoQualsiasi/grafo.png -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/nodes.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1", 4 | "label": " A " 5 | }, 6 | { 7 | "id": "2", 8 | "label": " B " 9 | }, 10 | { 11 | "id": "3", 12 | "label": " C " 13 | }, 14 | { 15 | "id": "4", 16 | "label": " D " 17 | }, 18 | { 19 | "id": "5", 20 | "label": " E " 21 | }, 22 | { 23 | "id": "6", 24 | "label": " F " 25 | }, 26 | { 27 | "id": "7", 28 | "label": " G " 29 | }, 30 | { 31 | "id": "8", 32 | "label": " H " 33 | }, 34 | { 35 | "id": "9", 36 | "label": " I " 37 | }, 38 | { 39 | "id": "10", 40 | "label": " J " 41 | }, 42 | { 43 | "id": "11", 44 | "label": " K " 45 | } 46 | ] -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/soluzione1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es3-grafoQualsiasi/soluzione1.png -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/soluzione2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es3-grafoQualsiasi/soluzione2.png -------------------------------------------------------------------------------- /eserciziDefault/es3-grafoQualsiasi/soluzione3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/eserciziDefault/es3-grafoQualsiasi/soluzione3.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | 13 | 27 | 28 | 29 | 30 | 31 | 32 | Dijkstra 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 |
49 |
50 |
51 |
52 |

53 | Input 54 |

55 |
56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
65 |
66 | Inizio e arrivo 67 | 69 | 71 | 72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |

80 | Output 81 |

82 |
83 |
84 |
85 |
86 |

87 | Visualizza qui la soluzione dell'esercizio 88 |

89 |
90 |
91 |
92 |
93 |
94 | 102 |
103 |
104 | 105 | 106 | 107 | Dijkstra Solver 108 |
109 |
110 |
111 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v5.3.0-alpha3 (https://getbootstrap.com/) 3 | * Copyright 2011-2023 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("@popperjs/core")):"function"==typeof define&&define.amd?define(["@popperjs/core"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap=e(t.Popper)}(this,(function(t){"use strict";function e(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t)for(const s in t)if("default"!==s){const i=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,i.get?i:{enumerable:!0,get:()=>t[s]})}return e.default=t,Object.freeze(e)}const s=e(t),i=new Map,n={set(t,e,s){i.has(t)||i.set(t,new Map);const n=i.get(t);n.has(e)||0===n.size?n.set(e,s):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(n.keys())[0]}.`)},get:(t,e)=>i.has(t)&&i.get(t).get(e)||null,remove(t,e){if(!i.has(t))return;const s=i.get(t);s.delete(e),0===s.size&&i.delete(t)}},o="transitionend",r=t=>(t&&window.CSS&&window.CSS.escape&&(t=t.replace(/#([^\s"#']+)/g,((t,e)=>`#${CSS.escape(e)}`))),t),a=t=>{t.dispatchEvent(new Event(o))},l=t=>!(!t||"object"!=typeof t)&&(void 0!==t.jquery&&(t=t[0]),void 0!==t.nodeType),c=t=>l(t)?t.jquery?t[0]:t:"string"==typeof t&&t.length>0?document.querySelector(r(t)):null,h=t=>{if(!l(t)||0===t.getClientRects().length)return!1;const e="visible"===getComputedStyle(t).getPropertyValue("visibility"),s=t.closest("details:not([open])");if(!s)return e;if(s!==t){const e=t.closest("summary");if(e&&e.parentNode!==s)return!1;if(null===e)return!1}return e},d=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),u=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?u(t.parentNode):null},_=()=>{},g=t=>{t.offsetHeight},f=()=>window.jQuery&&!document.body.hasAttribute("data-bs-no-jquery")?window.jQuery:null,m=[],p=()=>"rtl"===document.documentElement.dir,b=t=>{var e;e=()=>{const e=f();if(e){const s=t.NAME,i=e.fn[s];e.fn[s]=t.jQueryInterface,e.fn[s].Constructor=t,e.fn[s].noConflict=()=>(e.fn[s]=i,t.jQueryInterface)}},"loading"===document.readyState?(m.length||document.addEventListener("DOMContentLoaded",(()=>{for(const t of m)t()})),m.push(e)):e()},v=(t,e=[],s=t)=>"function"==typeof t?t(...e):s,y=(t,e,s=!0)=>{if(!s)return void v(t);const i=(t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:s}=window.getComputedStyle(t);const i=Number.parseFloat(e),n=Number.parseFloat(s);return i||n?(e=e.split(",")[0],s=s.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(s))):0})(e)+5;let n=!1;const r=({target:s})=>{s===e&&(n=!0,e.removeEventListener(o,r),v(t))};e.addEventListener(o,r),setTimeout((()=>{n||a(e)}),i)},w=(t,e,s,i)=>{const n=t.length;let o=t.indexOf(e);return-1===o?!s&&i?t[n-1]:t[0]:(o+=s?1:-1,i&&(o=(o+n)%n),t[Math.max(0,Math.min(o,n-1))])},A=/[^.]*(?=\..*)\.|.*/,E=/\..*/,C=/::\d+$/,T={};let k=1;const S={mouseenter:"mouseover",mouseleave:"mouseout"},L=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${k++}`||t.uidEvent||k++}function I(t){const e=O(t);return t.uidEvent=e,T[e]=T[e]||{},T[e]}function D(t,e,s=null){return Object.values(t).find((t=>t.callable===e&&t.delegationSelector===s))}function N(t,e,s){const i="string"==typeof e,n=i?s:e||s;let o=j(t);return L.has(o)||(o=t),[i,n,o]}function P(t,e,s,i,n){if("string"!=typeof e||!t)return;let[o,r,a]=N(e,s,i);if(e in S){const t=t=>function(e){if(!e.relatedTarget||e.relatedTarget!==e.delegateTarget&&!e.delegateTarget.contains(e.relatedTarget))return t.call(this,e)};r=t(r)}const l=I(t),c=l[a]||(l[a]={}),h=D(c,r,o?s:null);if(h)return void(h.oneOff=h.oneOff&&n);const d=O(r,e.replace(A,"")),u=o?function(t,e,s){return function i(n){const o=t.querySelectorAll(e);for(let{target:r}=n;r&&r!==this;r=r.parentNode)for(const a of o)if(a===r)return $(n,{delegateTarget:r}),i.oneOff&&F.off(t,n.type,e,s),s.apply(r,[n])}}(t,s,r):function(t,e){return function s(i){return $(i,{delegateTarget:t}),s.oneOff&&F.off(t,i.type,e),e.apply(t,[i])}}(t,r);u.delegationSelector=o?s:null,u.callable=r,u.oneOff=n,u.uidEvent=d,c[d]=u,t.addEventListener(a,u,o)}function x(t,e,s,i,n){const o=D(e[s],i,n);o&&(t.removeEventListener(s,o,Boolean(n)),delete e[s][o.uidEvent])}function M(t,e,s,i){const n=e[s]||{};for(const[o,r]of Object.entries(n))o.includes(i)&&x(t,e,s,r.callable,r.delegationSelector)}function j(t){return t=t.replace(E,""),S[t]||t}const F={on(t,e,s,i){P(t,e,s,i,!1)},one(t,e,s,i){P(t,e,s,i,!0)},off(t,e,s,i){if("string"!=typeof e||!t)return;const[n,o,r]=N(e,s,i),a=r!==e,l=I(t),c=l[r]||{},h=e.startsWith(".");if(void 0===o){if(h)for(const s of Object.keys(l))M(t,l,s,e.slice(1));for(const[s,i]of Object.entries(c)){const n=s.replace(C,"");a&&!e.includes(n)||x(t,l,r,i.callable,i.delegationSelector)}}else{if(!Object.keys(c).length)return;x(t,l,r,o,n?s:null)}},trigger(t,e,s){if("string"!=typeof e||!t)return null;const i=f();let n=null,o=!0,r=!0,a=!1;e!==j(e)&&i&&(n=i.Event(e,s),i(t).trigger(n),o=!n.isPropagationStopped(),r=!n.isImmediatePropagationStopped(),a=n.isDefaultPrevented());const l=$(new Event(e,{bubbles:o,cancelable:!0}),s);return a&&l.preventDefault(),r&&t.dispatchEvent(l),l.defaultPrevented&&n&&n.preventDefault(),l}};function $(t,e={}){for(const[s,i]of Object.entries(e))try{t[s]=i}catch(e){Object.defineProperty(t,s,{configurable:!0,get:()=>i})}return t}function z(t){if("true"===t)return!0;if("false"===t)return!1;if(t===Number(t).toString())return Number(t);if(""===t||"null"===t)return null;if("string"!=typeof t)return t;try{return JSON.parse(decodeURIComponent(t))}catch(e){return t}}function H(t){return t.replace(/[A-Z]/g,(t=>`-${t.toLowerCase()}`))}const B={setDataAttribute(t,e,s){t.setAttribute(`data-bs-${H(e)}`,s)},removeDataAttribute(t,e){t.removeAttribute(`data-bs-${H(e)}`)},getDataAttributes(t){if(!t)return{};const e={},s=Object.keys(t.dataset).filter((t=>t.startsWith("bs")&&!t.startsWith("bsConfig")));for(const i of s){let s=i.replace(/^bs/,"");s=s.charAt(0).toLowerCase()+s.slice(1,s.length),e[s]=z(t.dataset[i])}return e},getDataAttribute:(t,e)=>z(t.getAttribute(`data-bs-${H(e)}`))};class q{static get Default(){return{}}static get DefaultType(){return{}}static get NAME(){throw new Error('You have to implement the static method "NAME", for each component!')}_getConfig(t){return t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t}_mergeConfigObj(t,e){const s=l(e)?B.getDataAttribute(e,"config"):{};return{...this.constructor.Default,..."object"==typeof s?s:{},...l(e)?B.getDataAttributes(e):{},..."object"==typeof t?t:{}}}_typeCheckConfig(t,e=this.constructor.DefaultType){for(const[i,n]of Object.entries(e)){const e=t[i],o=l(e)?"element":null==(s=e)?`${s}`:Object.prototype.toString.call(s).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(n).test(o))throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${i}" provided type "${o}" but expected type "${n}".`)}var s}}class W extends q{constructor(t,e){super(),(t=c(t))&&(this._element=t,this._config=this._getConfig(e),n.set(this._element,this.constructor.DATA_KEY,this))}dispose(){n.remove(this._element,this.constructor.DATA_KEY),F.off(this._element,this.constructor.EVENT_KEY);for(const t of Object.getOwnPropertyNames(this))this[t]=null}_queueCallback(t,e,s=!0){y(t,e,s)}_getConfig(t){return t=this._mergeConfigObj(t,this._element),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}static getInstance(t){return n.get(c(t),this.DATA_KEY)}static getOrCreateInstance(t,e={}){return this.getInstance(t)||new this(t,"object"==typeof e?e:null)}static get VERSION(){return"5.3.0-alpha2"}static get DATA_KEY(){return`bs.${this.NAME}`}static get EVENT_KEY(){return`.${this.DATA_KEY}`}static eventName(t){return`${t}${this.EVENT_KEY}`}}const R=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let s=t.getAttribute("href");if(!s||!s.includes("#")&&!s.startsWith("."))return null;s.includes("#")&&!s.startsWith("#")&&(s=`#${s.split("#")[1]}`),e=s&&"#"!==s?s.trim():null}return r(e)},V={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter((t=>t.matches(e))),parents(t,e){const s=[];let i=t.parentNode.closest(e);for(;i;)s.push(i),i=i.parentNode.closest(e);return s},prev(t,e){let s=t.previousElementSibling;for(;s;){if(s.matches(e))return[s];s=s.previousElementSibling}return[]},next(t,e){let s=t.nextElementSibling;for(;s;){if(s.matches(e))return[s];s=s.nextElementSibling}return[]},focusableChildren(t){const e=["a","button","input","textarea","select","details","[tabindex]",'[contenteditable="true"]'].map((t=>`${t}:not([tabindex^="-"])`)).join(",");return this.find(e,t).filter((t=>!d(t)&&h(t)))},getSelectorFromElement(t){const e=R(t);return e&&V.findOne(e)?e:null},getElementFromSelector(t){const e=R(t);return e?V.findOne(e):null},getMultipleElementsFromSelector(t){const e=R(t);return e?V.find(e):[]}},K=(t,e="hide")=>{const s=`click.dismiss${t.EVENT_KEY}`,i=t.NAME;F.on(document,s,`[data-bs-dismiss="${i}"]`,(function(s){if(["A","AREA"].includes(this.tagName)&&s.preventDefault(),d(this))return;const n=V.getElementFromSelector(this)||this.closest(`.${i}`);t.getOrCreateInstance(n)[e]()}))};class Q extends W{static get NAME(){return"alert"}close(){if(F.trigger(this._element,"close.bs.alert").defaultPrevented)return;this._element.classList.remove("show");const t=this._element.classList.contains("fade");this._queueCallback((()=>this._destroyElement()),this._element,t)}_destroyElement(){this._element.remove(),F.trigger(this._element,"closed.bs.alert"),this.dispose()}static jQueryInterface(t){return this.each((function(){const e=Q.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}K(Q,"close"),b(Q);const X='[data-bs-toggle="button"]';class Y extends W{static get NAME(){return"button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){const e=Y.getOrCreateInstance(this);"toggle"===t&&e[t]()}))}}F.on(document,"click.bs.button.data-api",X,(t=>{t.preventDefault();const e=t.target.closest(X);Y.getOrCreateInstance(e).toggle()})),b(Y);const U={endCallback:null,leftCallback:null,rightCallback:null},G={endCallback:"(function|null)",leftCallback:"(function|null)",rightCallback:"(function|null)"};class J extends q{constructor(t,e){super(),this._element=t,t&&J.isSupported()&&(this._config=this._getConfig(e),this._deltaX=0,this._supportPointerEvents=Boolean(window.PointerEvent),this._initEvents())}static get Default(){return U}static get DefaultType(){return G}static get NAME(){return"swipe"}dispose(){F.off(this._element,".bs.swipe")}_start(t){this._supportPointerEvents?this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX):this._deltaX=t.touches[0].clientX}_end(t){this._eventIsPointerPenTouch(t)&&(this._deltaX=t.clientX-this._deltaX),this._handleSwipe(),v(this._config.endCallback)}_move(t){this._deltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this._deltaX}_handleSwipe(){const t=Math.abs(this._deltaX);if(t<=40)return;const e=t/this._deltaX;this._deltaX=0,e&&v(e>0?this._config.rightCallback:this._config.leftCallback)}_initEvents(){this._supportPointerEvents?(F.on(this._element,"pointerdown.bs.swipe",(t=>this._start(t))),F.on(this._element,"pointerup.bs.swipe",(t=>this._end(t))),this._element.classList.add("pointer-event")):(F.on(this._element,"touchstart.bs.swipe",(t=>this._start(t))),F.on(this._element,"touchmove.bs.swipe",(t=>this._move(t))),F.on(this._element,"touchend.bs.swipe",(t=>this._end(t))))}_eventIsPointerPenTouch(t){return this._supportPointerEvents&&("pen"===t.pointerType||"touch"===t.pointerType)}static isSupported(){return"ontouchstart"in document.documentElement||navigator.maxTouchPoints>0}}const Z="next",tt="prev",et="left",st="right",it="slid.bs.carousel",nt="carousel",ot="active",rt={ArrowLeft:st,ArrowRight:et},at={interval:5e3,keyboard:!0,pause:"hover",ride:!1,touch:!0,wrap:!0},lt={interval:"(number|boolean)",keyboard:"boolean",pause:"(string|boolean)",ride:"(boolean|string)",touch:"boolean",wrap:"boolean"};class ct extends W{constructor(t,e){super(t,e),this._interval=null,this._activeElement=null,this._isSliding=!1,this.touchTimeout=null,this._swipeHelper=null,this._indicatorsElement=V.findOne(".carousel-indicators",this._element),this._addEventListeners(),this._config.ride===nt&&this.cycle()}static get Default(){return at}static get DefaultType(){return lt}static get NAME(){return"carousel"}next(){this._slide(Z)}nextWhenVisible(){!document.hidden&&h(this._element)&&this.next()}prev(){this._slide(tt)}pause(){this._isSliding&&a(this._element),this._clearInterval()}cycle(){this._clearInterval(),this._updateInterval(),this._interval=setInterval((()=>this.nextWhenVisible()),this._config.interval)}_maybeEnableCycle(){this._config.ride&&(this._isSliding?F.one(this._element,it,(()=>this.cycle())):this.cycle())}to(t){const e=this._getItems();if(t>e.length-1||t<0)return;if(this._isSliding)return void F.one(this._element,it,(()=>this.to(t)));const s=this._getItemIndex(this._getActive());if(s===t)return;const i=t>s?Z:tt;this._slide(i,e[t])}dispose(){this._swipeHelper&&this._swipeHelper.dispose(),super.dispose()}_configAfterMerge(t){return t.defaultInterval=t.interval,t}_addEventListeners(){this._config.keyboard&&F.on(this._element,"keydown.bs.carousel",(t=>this._keydown(t))),"hover"===this._config.pause&&(F.on(this._element,"mouseenter.bs.carousel",(()=>this.pause())),F.on(this._element,"mouseleave.bs.carousel",(()=>this._maybeEnableCycle()))),this._config.touch&&J.isSupported()&&this._addTouchEventListeners()}_addTouchEventListeners(){for(const t of V.find(".carousel-item img",this._element))F.on(t,"dragstart.bs.carousel",(t=>t.preventDefault()));const t={leftCallback:()=>this._slide(this._directionToOrder(et)),rightCallback:()=>this._slide(this._directionToOrder(st)),endCallback:()=>{"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout((()=>this._maybeEnableCycle()),500+this._config.interval))}};this._swipeHelper=new J(this._element,t)}_keydown(t){if(/input|textarea/i.test(t.target.tagName))return;const e=rt[t.key];e&&(t.preventDefault(),this._slide(this._directionToOrder(e)))}_getItemIndex(t){return this._getItems().indexOf(t)}_setActiveIndicatorElement(t){if(!this._indicatorsElement)return;const e=V.findOne(".active",this._indicatorsElement);e.classList.remove(ot),e.removeAttribute("aria-current");const s=V.findOne(`[data-bs-slide-to="${t}"]`,this._indicatorsElement);s&&(s.classList.add(ot),s.setAttribute("aria-current","true"))}_updateInterval(){const t=this._activeElement||this._getActive();if(!t)return;const e=Number.parseInt(t.getAttribute("data-bs-interval"),10);this._config.interval=e||this._config.defaultInterval}_slide(t,e=null){if(this._isSliding)return;const s=this._getActive(),i=t===Z,n=e||w(this._getItems(),s,i,this._config.wrap);if(n===s)return;const o=this._getItemIndex(n),r=e=>F.trigger(this._element,e,{relatedTarget:n,direction:this._orderToDirection(t),from:this._getItemIndex(s),to:o});if(r("slide.bs.carousel").defaultPrevented)return;if(!s||!n)return;const a=Boolean(this._interval);this.pause(),this._isSliding=!0,this._setActiveIndicatorElement(o),this._activeElement=n;const l=i?"carousel-item-start":"carousel-item-end",c=i?"carousel-item-next":"carousel-item-prev";n.classList.add(c),g(n),s.classList.add(l),n.classList.add(l),this._queueCallback((()=>{n.classList.remove(l,c),n.classList.add(ot),s.classList.remove(ot,c,l),this._isSliding=!1,r(it)}),s,this._isAnimated()),a&&this.cycle()}_isAnimated(){return this._element.classList.contains("slide")}_getActive(){return V.findOne(".active.carousel-item",this._element)}_getItems(){return V.find(".carousel-item",this._element)}_clearInterval(){this._interval&&(clearInterval(this._interval),this._interval=null)}_directionToOrder(t){return p()?t===et?tt:Z:t===et?Z:tt}_orderToDirection(t){return p()?t===tt?et:st:t===tt?st:et}static jQueryInterface(t){return this.each((function(){const e=ct.getOrCreateInstance(this,t);if("number"!=typeof t){if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}else e.to(t)}))}}F.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",(function(t){const e=V.getElementFromSelector(this);if(!e||!e.classList.contains(nt))return;t.preventDefault();const s=ct.getOrCreateInstance(e),i=this.getAttribute("data-bs-slide-to");return i?(s.to(i),void s._maybeEnableCycle()):"next"===B.getDataAttribute(this,"slide")?(s.next(),void s._maybeEnableCycle()):(s.prev(),void s._maybeEnableCycle())})),F.on(window,"load.bs.carousel.data-api",(()=>{const t=V.find('[data-bs-ride="carousel"]');for(const e of t)ct.getOrCreateInstance(e)})),b(ct);const ht="show",dt="collapse",ut="collapsing",_t='[data-bs-toggle="collapse"]',gt={parent:null,toggle:!0},ft={parent:"(null|element)",toggle:"boolean"};class mt extends W{constructor(t,e){super(t,e),this._isTransitioning=!1,this._triggerArray=[];const s=V.find(_t);for(const t of s){const e=V.getSelectorFromElement(t),s=V.find(e).filter((t=>t===this._element));null!==e&&s.length&&this._triggerArray.push(t)}this._initializeChildren(),this._config.parent||this._addAriaAndCollapsedClass(this._triggerArray,this._isShown()),this._config.toggle&&this.toggle()}static get Default(){return gt}static get DefaultType(){return ft}static get NAME(){return"collapse"}toggle(){this._isShown()?this.hide():this.show()}show(){if(this._isTransitioning||this._isShown())return;let t=[];if(this._config.parent&&(t=this._getFirstLevelChildren(".collapse.show, .collapse.collapsing").filter((t=>t!==this._element)).map((t=>mt.getOrCreateInstance(t,{toggle:!1})))),t.length&&t[0]._isTransitioning)return;if(F.trigger(this._element,"show.bs.collapse").defaultPrevented)return;for(const e of t)e.hide();const e=this._getDimension();this._element.classList.remove(dt),this._element.classList.add(ut),this._element.style[e]=0,this._addAriaAndCollapsedClass(this._triggerArray,!0),this._isTransitioning=!0;const s=`scroll${e[0].toUpperCase()+e.slice(1)}`;this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ut),this._element.classList.add(dt,ht),this._element.style[e]="",F.trigger(this._element,"shown.bs.collapse")}),this._element,!0),this._element.style[e]=`${this._element[s]}px`}hide(){if(this._isTransitioning||!this._isShown())return;if(F.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=`${this._element.getBoundingClientRect()[t]}px`,g(this._element),this._element.classList.add(ut),this._element.classList.remove(dt,ht);for(const t of this._triggerArray){const e=V.getElementFromSelector(t);e&&!this._isShown(e)&&this._addAriaAndCollapsedClass([t],!1)}this._isTransitioning=!0,this._element.style[t]="",this._queueCallback((()=>{this._isTransitioning=!1,this._element.classList.remove(ut),this._element.classList.add(dt),F.trigger(this._element,"hidden.bs.collapse")}),this._element,!0)}_isShown(t=this._element){return t.classList.contains(ht)}_configAfterMerge(t){return t.toggle=Boolean(t.toggle),t.parent=c(t.parent),t}_getDimension(){return this._element.classList.contains("collapse-horizontal")?"width":"height"}_initializeChildren(){if(!this._config.parent)return;const t=this._getFirstLevelChildren(_t);for(const e of t){const t=V.getElementFromSelector(e);t&&this._addAriaAndCollapsedClass([e],this._isShown(t))}}_getFirstLevelChildren(t){const e=V.find(":scope .collapse .collapse",this._config.parent);return V.find(t,this._config.parent).filter((t=>!e.includes(t)))}_addAriaAndCollapsedClass(t,e){if(t.length)for(const s of t)s.classList.toggle("collapsed",!e),s.setAttribute("aria-expanded",e)}static jQueryInterface(t){const e={};return"string"==typeof t&&/show|hide/.test(t)&&(e.toggle=!1),this.each((function(){const s=mt.getOrCreateInstance(this,e);if("string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t]()}}))}}F.on(document,"click.bs.collapse.data-api",_t,(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();for(const t of V.getMultipleElementsFromSelector(this))mt.getOrCreateInstance(t,{toggle:!1}).toggle()})),b(mt);const pt="dropdown",bt="ArrowUp",vt="ArrowDown",yt="click.bs.dropdown.data-api",wt="keydown.bs.dropdown.data-api",At="show",Et='[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)',Ct=`${Et}.show`,Tt=".dropdown-menu",kt=p()?"top-end":"top-start",St=p()?"top-start":"top-end",Lt=p()?"bottom-end":"bottom-start",Ot=p()?"bottom-start":"bottom-end",It=p()?"left-start":"right-start",Dt=p()?"right-start":"left-start",Nt={autoClose:!0,boundary:"clippingParents",display:"dynamic",offset:[0,2],popperConfig:null,reference:"toggle"},Pt={autoClose:"(boolean|string)",boundary:"(string|element)",display:"string",offset:"(array|string|function)",popperConfig:"(null|object|function)",reference:"(string|element|object)"};class xt extends W{constructor(t,e){super(t,e),this._popper=null,this._parent=this._element.parentNode,this._menu=V.next(this._element,Tt)[0]||V.prev(this._element,Tt)[0]||V.findOne(Tt,this._parent),this._inNavbar=this._detectNavbar()}static get Default(){return Nt}static get DefaultType(){return Pt}static get NAME(){return pt}toggle(){return this._isShown()?this.hide():this.show()}show(){if(d(this._element)||this._isShown())return;const t={relatedTarget:this._element};if(!F.trigger(this._element,"show.bs.dropdown",t).defaultPrevented){if(this._createPopper(),"ontouchstart"in document.documentElement&&!this._parent.closest(".navbar-nav"))for(const t of[].concat(...document.body.children))F.on(t,"mouseover",_);this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.add(At),this._element.classList.add(At),F.trigger(this._element,"shown.bs.dropdown",t)}}hide(){if(d(this._element)||!this._isShown())return;const t={relatedTarget:this._element};this._completeHide(t)}dispose(){this._popper&&this._popper.destroy(),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_completeHide(t){if(!F.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented){if("ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.off(t,"mouseover",_);this._popper&&this._popper.destroy(),this._menu.classList.remove(At),this._element.classList.remove(At),this._element.setAttribute("aria-expanded","false"),B.removeDataAttribute(this._menu,"popper"),F.trigger(this._element,"hidden.bs.dropdown",t)}}_getConfig(t){if("object"==typeof(t=super._getConfig(t)).reference&&!l(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError(`${pt.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);return t}_createPopper(){if(void 0===s)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");let t=this._element;"parent"===this._config.reference?t=this._parent:l(this._config.reference)?t=c(this._config.reference):"object"==typeof this._config.reference&&(t=this._config.reference);const e=this._getPopperConfig();this._popper=s.createPopper(t,this._menu,e)}_isShown(){return this._menu.classList.contains(At)}_getPlacement(){const t=this._parent;if(t.classList.contains("dropend"))return It;if(t.classList.contains("dropstart"))return Dt;if(t.classList.contains("dropup-center"))return"top";if(t.classList.contains("dropdown-center"))return"bottom";const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?St:kt:e?Ot:Lt}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return(this._inNavbar||"static"===this._config.display)&&(B.setDataAttribute(this._menu,"popper","static"),t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,...v(this._config.popperConfig,[t])}}_selectMenuItem({key:t,target:e}){const s=V.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",this._menu).filter((t=>h(t)));s.length&&w(s,e,t===vt,!s.includes(e)).focus()}static jQueryInterface(t){return this.each((function(){const e=xt.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}static clearMenus(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;const e=V.find(Ct);for(const s of e){const e=xt.getInstance(s);if(!e||!1===e._config.autoClose)continue;const i=t.composedPath(),n=i.includes(e._menu);if(i.includes(e._element)||"inside"===e._config.autoClose&&!n||"outside"===e._config.autoClose&&n)continue;if(e._menu.contains(t.target)&&("keyup"===t.type&&"Tab"===t.key||/input|select|option|textarea|form/i.test(t.target.tagName)))continue;const o={relatedTarget:e._element};"click"===t.type&&(o.clickEvent=t),e._completeHide(o)}}static dataApiKeydownHandler(t){const e=/input|textarea/i.test(t.target.tagName),s="Escape"===t.key,i=[bt,vt].includes(t.key);if(!i&&!s)return;if(e&&!s)return;t.preventDefault();const n=this.matches(Et)?this:V.prev(this,Et)[0]||V.next(this,Et)[0]||V.findOne(Et,t.delegateTarget.parentNode),o=xt.getOrCreateInstance(n);if(i)return t.stopPropagation(),o.show(),void o._selectMenuItem(t);o._isShown()&&(t.stopPropagation(),o.hide(),n.focus())}}F.on(document,wt,Et,xt.dataApiKeydownHandler),F.on(document,wt,Tt,xt.dataApiKeydownHandler),F.on(document,yt,xt.clearMenus),F.on(document,"keyup.bs.dropdown.data-api",xt.clearMenus),F.on(document,yt,Et,(function(t){t.preventDefault(),xt.getOrCreateInstance(this).toggle()})),b(xt);const Mt="show",jt="mousedown.bs.backdrop",Ft={className:"modal-backdrop",clickCallback:null,isAnimated:!1,isVisible:!0,rootElement:"body"},$t={className:"string",clickCallback:"(function|null)",isAnimated:"boolean",isVisible:"boolean",rootElement:"(element|string)"};class zt extends q{constructor(t){super(),this._config=this._getConfig(t),this._isAppended=!1,this._element=null}static get Default(){return Ft}static get DefaultType(){return $t}static get NAME(){return"backdrop"}show(t){if(!this._config.isVisible)return void v(t);this._append();const e=this._getElement();this._config.isAnimated&&g(e),e.classList.add(Mt),this._emulateAnimation((()=>{v(t)}))}hide(t){this._config.isVisible?(this._getElement().classList.remove(Mt),this._emulateAnimation((()=>{this.dispose(),v(t)}))):v(t)}dispose(){this._isAppended&&(F.off(this._element,jt),this._element.remove(),this._isAppended=!1)}_getElement(){if(!this._element){const t=document.createElement("div");t.className=this._config.className,this._config.isAnimated&&t.classList.add("fade"),this._element=t}return this._element}_configAfterMerge(t){return t.rootElement=c(t.rootElement),t}_append(){if(this._isAppended)return;const t=this._getElement();this._config.rootElement.append(t),F.on(t,jt,(()=>{v(this._config.clickCallback)})),this._isAppended=!0}_emulateAnimation(t){y(t,this._getElement(),this._config.isAnimated)}}const Ht=".bs.focustrap",Bt="backward",qt={autofocus:!0,trapElement:null},Wt={autofocus:"boolean",trapElement:"element"};class Rt extends q{constructor(t){super(),this._config=this._getConfig(t),this._isActive=!1,this._lastTabNavDirection=null}static get Default(){return qt}static get DefaultType(){return Wt}static get NAME(){return"focustrap"}activate(){this._isActive||(this._config.autofocus&&this._config.trapElement.focus(),F.off(document,Ht),F.on(document,"focusin.bs.focustrap",(t=>this._handleFocusin(t))),F.on(document,"keydown.tab.bs.focustrap",(t=>this._handleKeydown(t))),this._isActive=!0)}deactivate(){this._isActive&&(this._isActive=!1,F.off(document,Ht))}_handleFocusin(t){const{trapElement:e}=this._config;if(t.target===document||t.target===e||e.contains(t.target))return;const s=V.focusableChildren(e);0===s.length?e.focus():this._lastTabNavDirection===Bt?s[s.length-1].focus():s[0].focus()}_handleKeydown(t){"Tab"===t.key&&(this._lastTabNavDirection=t.shiftKey?Bt:"forward")}}const Vt=".fixed-top, .fixed-bottom, .is-fixed, .sticky-top",Kt=".sticky-top",Qt="padding-right",Xt="margin-right";class Yt{constructor(){this._element=document.body}getWidth(){const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)}hide(){const t=this.getWidth();this._disableOverFlow(),this._setElementAttributes(this._element,Qt,(e=>e+t)),this._setElementAttributes(Vt,Qt,(e=>e+t)),this._setElementAttributes(Kt,Xt,(e=>e-t))}reset(){this._resetElementAttributes(this._element,"overflow"),this._resetElementAttributes(this._element,Qt),this._resetElementAttributes(Vt,Qt),this._resetElementAttributes(Kt,Xt)}isOverflowing(){return this.getWidth()>0}_disableOverFlow(){this._saveInitialAttribute(this._element,"overflow"),this._element.style.overflow="hidden"}_setElementAttributes(t,e,s){const i=this.getWidth();this._applyManipulationCallback(t,(t=>{if(t!==this._element&&window.innerWidth>t.clientWidth+i)return;this._saveInitialAttribute(t,e);const n=window.getComputedStyle(t).getPropertyValue(e);t.style.setProperty(e,`${s(Number.parseFloat(n))}px`)}))}_saveInitialAttribute(t,e){const s=t.style.getPropertyValue(e);s&&B.setDataAttribute(t,e,s)}_resetElementAttributes(t,e){this._applyManipulationCallback(t,(t=>{const s=B.getDataAttribute(t,e);null!==s?(B.removeDataAttribute(t,e),t.style.setProperty(e,s)):t.style.removeProperty(e)}))}_applyManipulationCallback(t,e){if(l(t))e(t);else for(const s of V.find(t,this._element))e(s)}}const Ut=".bs.modal",Gt="hidden.bs.modal",Jt="show.bs.modal",Zt="modal-open",te="show",ee="modal-static",se={backdrop:!0,focus:!0,keyboard:!0},ie={backdrop:"(boolean|string)",focus:"boolean",keyboard:"boolean"};class ne extends W{constructor(t,e){super(t,e),this._dialog=V.findOne(".modal-dialog",this._element),this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._isShown=!1,this._isTransitioning=!1,this._scrollBar=new Yt,this._addEventListeners()}static get Default(){return se}static get DefaultType(){return ie}static get NAME(){return"modal"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||this._isTransitioning||F.trigger(this._element,Jt,{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._isTransitioning=!0,this._scrollBar.hide(),document.body.classList.add(Zt),this._adjustDialog(),this._backdrop.show((()=>this._showElement(t))))}hide(){this._isShown&&!this._isTransitioning&&(F.trigger(this._element,"hide.bs.modal").defaultPrevented||(this._isShown=!1,this._isTransitioning=!0,this._focustrap.deactivate(),this._element.classList.remove(te),this._queueCallback((()=>this._hideModal()),this._element,this._isAnimated())))}dispose(){F.off(window,Ut),F.off(this._dialog,Ut),this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}handleUpdate(){this._adjustDialog()}_initializeBackDrop(){return new zt({isVisible:Boolean(this._config.backdrop),isAnimated:this._isAnimated()})}_initializeFocusTrap(){return new Rt({trapElement:this._element})}_showElement(t){document.body.contains(this._element)||document.body.append(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0;const e=V.findOne(".modal-body",this._dialog);e&&(e.scrollTop=0),g(this._element),this._element.classList.add(te),this._queueCallback((()=>{this._config.focus&&this._focustrap.activate(),this._isTransitioning=!1,F.trigger(this._element,"shown.bs.modal",{relatedTarget:t})}),this._dialog,this._isAnimated())}_addEventListeners(){F.on(this._element,"keydown.dismiss.bs.modal",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():this._triggerBackdropTransition())})),F.on(window,"resize.bs.modal",(()=>{this._isShown&&!this._isTransitioning&&this._adjustDialog()})),F.on(this._element,"mousedown.dismiss.bs.modal",(t=>{F.one(this._element,"click.dismiss.bs.modal",(e=>{this._element===t.target&&this._element===e.target&&("static"!==this._config.backdrop?this._config.backdrop&&this.hide():this._triggerBackdropTransition())}))}))}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._backdrop.hide((()=>{document.body.classList.remove(Zt),this._resetAdjustments(),this._scrollBar.reset(),F.trigger(this._element,Gt)}))}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(F.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._element.style.overflowY;"hidden"===e||this._element.classList.contains(ee)||(t||(this._element.style.overflowY="hidden"),this._element.classList.add(ee),this._queueCallback((()=>{this._element.classList.remove(ee),this._queueCallback((()=>{this._element.style.overflowY=e}),this._dialog)}),this._dialog),this._element.focus())}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight,e=this._scrollBar.getWidth(),s=e>0;if(s&&!t){const t=p()?"paddingLeft":"paddingRight";this._element.style[t]=`${e}px`}if(!s&&t){const t=p()?"paddingRight":"paddingLeft";this._element.style[t]=`${e}px`}}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}static jQueryInterface(t,e){return this.each((function(){const s=ne.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===s[t])throw new TypeError(`No method named "${t}"`);s[t](e)}}))}}F.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=V.getElementFromSelector(this);["A","AREA"].includes(this.tagName)&&t.preventDefault(),F.one(e,Jt,(t=>{t.defaultPrevented||F.one(e,Gt,(()=>{h(this)&&this.focus()}))}));const s=V.findOne(".modal.show");s&&ne.getInstance(s).hide(),ne.getOrCreateInstance(e).toggle(this)})),K(ne),b(ne);const oe="show",re="showing",ae="hiding",le=".offcanvas.show",ce="hidePrevented.bs.offcanvas",he="hidden.bs.offcanvas",de={backdrop:!0,keyboard:!0,scroll:!1},ue={backdrop:"(boolean|string)",keyboard:"boolean",scroll:"boolean"};class _e extends W{constructor(t,e){super(t,e),this._isShown=!1,this._backdrop=this._initializeBackDrop(),this._focustrap=this._initializeFocusTrap(),this._addEventListeners()}static get Default(){return de}static get DefaultType(){return ue}static get NAME(){return"offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||F.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._backdrop.show(),this._config.scroll||(new Yt).hide(),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add(re),this._queueCallback((()=>{this._config.scroll&&!this._config.backdrop||this._focustrap.activate(),this._element.classList.add(oe),this._element.classList.remove(re),F.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t})}),this._element,!0))}hide(){this._isShown&&(F.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._focustrap.deactivate(),this._element.blur(),this._isShown=!1,this._element.classList.add(ae),this._backdrop.hide(),this._queueCallback((()=>{this._element.classList.remove(oe,ae),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._config.scroll||(new Yt).reset(),F.trigger(this._element,he)}),this._element,!0)))}dispose(){this._backdrop.dispose(),this._focustrap.deactivate(),super.dispose()}_initializeBackDrop(){const t=Boolean(this._config.backdrop);return new zt({className:"offcanvas-backdrop",isVisible:t,isAnimated:!0,rootElement:this._element.parentNode,clickCallback:t?()=>{"static"!==this._config.backdrop?this.hide():F.trigger(this._element,ce)}:null})}_initializeFocusTrap(){return new Rt({trapElement:this._element})}_addEventListeners(){F.on(this._element,"keydown.dismiss.bs.offcanvas",(t=>{"Escape"===t.key&&(this._config.keyboard?this.hide():F.trigger(this._element,ce))}))}static jQueryInterface(t){return this.each((function(){const e=_e.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}F.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=V.getElementFromSelector(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this))return;F.one(e,he,(()=>{h(this)&&this.focus()}));const s=V.findOne(le);s&&s!==e&&_e.getInstance(s).hide(),_e.getOrCreateInstance(e).toggle(this)})),F.on(window,"load.bs.offcanvas.data-api",(()=>{for(const t of V.find(le))_e.getOrCreateInstance(t).show()})),F.on(window,"resize.bs.offcanvas",(()=>{for(const t of V.find("[aria-modal][class*=show][class*=offcanvas-]"))"fixed"!==getComputedStyle(t).position&&_e.getOrCreateInstance(t).hide()})),K(_e),b(_e);const ge=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),fe=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i,me=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,pe=(t,e)=>{const s=t.nodeName.toLowerCase();return e.includes(s)?!ge.has(s)||Boolean(fe.test(t.nodeValue)||me.test(t.nodeValue)):e.filter((t=>t instanceof RegExp)).some((t=>t.test(s)))},be={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},ve={allowList:be,content:{},extraClass:"",html:!1,sanitize:!0,sanitizeFn:null,template:"
"},ye={allowList:"object",content:"object",extraClass:"(string|function)",html:"boolean",sanitize:"boolean",sanitizeFn:"(null|function)",template:"string"},we={entry:"(string|element|function|null)",selector:"(string|element)"};class Ae extends q{constructor(t){super(),this._config=this._getConfig(t)}static get Default(){return ve}static get DefaultType(){return ye}static get NAME(){return"TemplateFactory"}getContent(){return Object.values(this._config.content).map((t=>this._resolvePossibleFunction(t))).filter(Boolean)}hasContent(){return this.getContent().length>0}changeContent(t){return this._checkContent(t),this._config.content={...this._config.content,...t},this}toHtml(){const t=document.createElement("div");t.innerHTML=this._maybeSanitize(this._config.template);for(const[e,s]of Object.entries(this._config.content))this._setContent(t,s,e);const e=t.children[0],s=this._resolvePossibleFunction(this._config.extraClass);return s&&e.classList.add(...s.split(" ")),e}_typeCheckConfig(t){super._typeCheckConfig(t),this._checkContent(t.content)}_checkContent(t){for(const[e,s]of Object.entries(t))super._typeCheckConfig({selector:e,entry:s},we)}_setContent(t,e,s){const i=V.findOne(s,t);i&&((e=this._resolvePossibleFunction(e))?l(e)?this._putElementInTemplate(c(e),i):this._config.html?i.innerHTML=this._maybeSanitize(e):i.textContent=e:i.remove())}_maybeSanitize(t){return this._config.sanitize?function(t,e,s){if(!t.length)return t;if(s&&"function"==typeof s)return s(t);const i=(new window.DOMParser).parseFromString(t,"text/html"),n=[].concat(...i.body.querySelectorAll("*"));for(const t of n){const s=t.nodeName.toLowerCase();if(!Object.keys(e).includes(s)){t.remove();continue}const i=[].concat(...t.attributes),n=[].concat(e["*"]||[],e[s]||[]);for(const e of i)pe(e,n)||t.removeAttribute(e.nodeName)}return i.body.innerHTML}(t,this._config.allowList,this._config.sanitizeFn):t}_resolvePossibleFunction(t){return v(t,[this])}_putElementInTemplate(t,e){if(this._config.html)return e.innerHTML="",void e.append(t);e.textContent=t.textContent}}const Ee=new Set(["sanitize","allowList","sanitizeFn"]),Ce="fade",Te="show",ke=".modal",Se="hide.bs.modal",Le="hover",Oe="focus",Ie={AUTO:"auto",TOP:"top",RIGHT:p()?"left":"right",BOTTOM:"bottom",LEFT:p()?"right":"left"},De={allowList:be,animation:!0,boundary:"clippingParents",container:!1,customClass:"",delay:0,fallbackPlacements:["top","right","bottom","left"],html:!1,offset:[0,6],placement:"top",popperConfig:null,sanitize:!0,sanitizeFn:null,selector:!1,template:'',title:"",trigger:"hover focus"},Ne={allowList:"object",animation:"boolean",boundary:"(string|element)",container:"(string|element|boolean)",customClass:"(string|function)",delay:"(number|object)",fallbackPlacements:"array",html:"boolean",offset:"(array|string|function)",placement:"(string|function)",popperConfig:"(null|object|function)",sanitize:"boolean",sanitizeFn:"(null|function)",selector:"(string|boolean)",template:"string",title:"(string|element|function)",trigger:"string"};class Pe extends W{constructor(t,e){if(void 0===s)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t,e),this._isEnabled=!0,this._timeout=0,this._isHovered=null,this._activeTrigger={},this._popper=null,this._templateFactory=null,this._newContent=null,this.tip=null,this._setListeners(),this._config.selector||this._fixTitle()}static get Default(){return De}static get DefaultType(){return Ne}static get NAME(){return"tooltip"}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(){this._isEnabled&&(this._activeTrigger.click=!this._activeTrigger.click,this._isShown()?this._leave():this._enter())}dispose(){clearTimeout(this._timeout),F.off(this._element.closest(ke),Se,this._hideModalHandler),this._element.getAttribute("data-bs-original-title")&&this._element.setAttribute("title",this._element.getAttribute("data-bs-original-title")),this._disposePopper(),super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this._isWithContent()||!this._isEnabled)return;const t=F.trigger(this._element,this.constructor.eventName("show")),e=(u(this._element)||this._element.ownerDocument.documentElement).contains(this._element);if(t.defaultPrevented||!e)return;this._disposePopper();const s=this._getTipElement();this._element.setAttribute("aria-describedby",s.getAttribute("id"));const{container:i}=this._config;if(this._element.ownerDocument.documentElement.contains(this.tip)||(i.append(s),F.trigger(this._element,this.constructor.eventName("inserted"))),this._popper=this._createPopper(s),s.classList.add(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.on(t,"mouseover",_);this._queueCallback((()=>{F.trigger(this._element,this.constructor.eventName("shown")),!1===this._isHovered&&this._leave(),this._isHovered=!1}),this.tip,this._isAnimated())}hide(){if(this._isShown()&&!F.trigger(this._element,this.constructor.eventName("hide")).defaultPrevented){if(this._getTipElement().classList.remove(Te),"ontouchstart"in document.documentElement)for(const t of[].concat(...document.body.children))F.off(t,"mouseover",_);this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this._isHovered=null,this._queueCallback((()=>{this._isWithActiveTrigger()||(this._isHovered||this._disposePopper(),this._element.removeAttribute("aria-describedby"),F.trigger(this._element,this.constructor.eventName("hidden")))}),this.tip,this._isAnimated())}}update(){this._popper&&this._popper.update()}_isWithContent(){return Boolean(this._getTitle())}_getTipElement(){return this.tip||(this.tip=this._createTipElement(this._newContent||this._getContentForTemplate())),this.tip}_createTipElement(t){const e=this._getTemplateFactory(t).toHtml();if(!e)return null;e.classList.remove(Ce,Te),e.classList.add(`bs-${this.constructor.NAME}-auto`);const s=(t=>{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t})(this.constructor.NAME).toString();return e.setAttribute("id",s),this._isAnimated()&&e.classList.add(Ce),e}setContent(t){this._newContent=t,this._isShown()&&(this._disposePopper(),this.show())}_getTemplateFactory(t){return this._templateFactory?this._templateFactory.changeContent(t):this._templateFactory=new Ae({...this._config,content:t,extraClass:this._resolvePossibleFunction(this._config.customClass)}),this._templateFactory}_getContentForTemplate(){return{".tooltip-inner":this._getTitle()}}_getTitle(){return this._resolvePossibleFunction(this._config.title)||this._element.getAttribute("data-bs-original-title")}_initializeOnDelegatedTarget(t){return this.constructor.getOrCreateInstance(t.delegateTarget,this._getDelegateConfig())}_isAnimated(){return this._config.animation||this.tip&&this.tip.classList.contains(Ce)}_isShown(){return this.tip&&this.tip.classList.contains(Te)}_createPopper(t){const e=v(this._config.placement,[this,t,this._element]),i=Ie[e.toUpperCase()];return s.createPopper(this._element,t,this._getPopperConfig(i))}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map((t=>Number.parseInt(t,10))):"function"==typeof t?e=>t(e,this._element):t}_resolvePossibleFunction(t){return v(t,[this._element])}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{fallbackPlacements:this._config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"preSetPlacement",enabled:!0,phase:"beforeMain",fn:t=>{this._getTipElement().setAttribute("data-popper-placement",t.state.placement)}}]};return{...e,...v(this._config.popperConfig,[e])}}_setListeners(){const t=this._config.trigger.split(" ");for(const e of t)if("click"===e)F.on(this._element,this.constructor.eventName("click"),this._config.selector,(t=>{this._initializeOnDelegatedTarget(t).toggle()}));else if("manual"!==e){const t=e===Le?this.constructor.eventName("mouseenter"):this.constructor.eventName("focusin"),s=e===Le?this.constructor.eventName("mouseleave"):this.constructor.eventName("focusout");F.on(this._element,t,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusin"===t.type?Oe:Le]=!0,e._enter()})),F.on(this._element,s,this._config.selector,(t=>{const e=this._initializeOnDelegatedTarget(t);e._activeTrigger["focusout"===t.type?Oe:Le]=e._element.contains(t.relatedTarget),e._leave()}))}this._hideModalHandler=()=>{this._element&&this.hide()},F.on(this._element.closest(ke),Se,this._hideModalHandler)}_fixTitle(){const t=this._element.getAttribute("title");t&&(this._element.getAttribute("aria-label")||this._element.textContent.trim()||this._element.setAttribute("aria-label",t),this._element.setAttribute("data-bs-original-title",t),this._element.removeAttribute("title"))}_enter(){this._isShown()||this._isHovered?this._isHovered=!0:(this._isHovered=!0,this._setTimeout((()=>{this._isHovered&&this.show()}),this._config.delay.show))}_leave(){this._isWithActiveTrigger()||(this._isHovered=!1,this._setTimeout((()=>{this._isHovered||this.hide()}),this._config.delay.hide))}_setTimeout(t,e){clearTimeout(this._timeout),this._timeout=setTimeout(t,e)}_isWithActiveTrigger(){return Object.values(this._activeTrigger).includes(!0)}_getConfig(t){const e=B.getDataAttributes(this._element);for(const t of Object.keys(e))Ee.has(t)&&delete e[t];return t={...e,..."object"==typeof t&&t?t:{}},t=this._mergeConfigObj(t),t=this._configAfterMerge(t),this._typeCheckConfig(t),t}_configAfterMerge(t){return t.container=!1===t.container?document.body:c(t.container),"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),t}_getDelegateConfig(){const t={};for(const[e,s]of Object.entries(this._config))this.constructor.Default[e]!==s&&(t[e]=s);return t.selector=!1,t.trigger="manual",t}_disposePopper(){this._popper&&(this._popper.destroy(),this._popper=null),this.tip&&(this.tip.remove(),this.tip=null)}static jQueryInterface(t){return this.each((function(){const e=Pe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(Pe);const xe={...Pe.Default,content:"",offset:[0,8],placement:"right",template:'',trigger:"click"},Me={...Pe.DefaultType,content:"(null|string|element|function)"};class je extends Pe{static get Default(){return xe}static get DefaultType(){return Me}static get NAME(){return"popover"}_isWithContent(){return this._getTitle()||this._getContent()}_getContentForTemplate(){return{".popover-header":this._getTitle(),".popover-body":this._getContent()}}_getContent(){return this._resolvePossibleFunction(this._config.content)}static jQueryInterface(t){return this.each((function(){const e=je.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}b(je);const Fe="click.bs.scrollspy",$e="active",ze="[href]",He={offset:null,rootMargin:"0px 0px -25%",smoothScroll:!1,target:null,threshold:[.1,.5,1]},Be={offset:"(number|null)",rootMargin:"string",smoothScroll:"boolean",target:"element",threshold:"array"};class qe extends W{constructor(t,e){super(t,e),this._targetLinks=new Map,this._observableSections=new Map,this._rootElement="visible"===getComputedStyle(this._element).overflowY?null:this._element,this._activeTarget=null,this._observer=null,this._previousScrollData={visibleEntryTop:0,parentScrollTop:0},this.refresh()}static get Default(){return He}static get DefaultType(){return Be}static get NAME(){return"scrollspy"}refresh(){this._initializeTargetsAndObservables(),this._maybeEnableSmoothScroll(),this._observer?this._observer.disconnect():this._observer=this._getNewObserver();for(const t of this._observableSections.values())this._observer.observe(t)}dispose(){this._observer.disconnect(),super.dispose()}_configAfterMerge(t){return t.target=c(t.target)||document.body,t.rootMargin=t.offset?`${t.offset}px 0px -30%`:t.rootMargin,"string"==typeof t.threshold&&(t.threshold=t.threshold.split(",").map((t=>Number.parseFloat(t)))),t}_maybeEnableSmoothScroll(){this._config.smoothScroll&&(F.off(this._config.target,Fe),F.on(this._config.target,Fe,ze,(t=>{const e=this._observableSections.get(t.target.hash);if(e){t.preventDefault();const s=this._rootElement||window,i=e.offsetTop-this._element.offsetTop;if(s.scrollTo)return void s.scrollTo({top:i,behavior:"smooth"});s.scrollTop=i}})))}_getNewObserver(){const t={root:this._rootElement,threshold:this._config.threshold,rootMargin:this._config.rootMargin};return new IntersectionObserver((t=>this._observerCallback(t)),t)}_observerCallback(t){const e=t=>this._targetLinks.get(`#${t.target.id}`),s=t=>{this._previousScrollData.visibleEntryTop=t.target.offsetTop,this._process(e(t))},i=(this._rootElement||document.documentElement).scrollTop,n=i>=this._previousScrollData.parentScrollTop;this._previousScrollData.parentScrollTop=i;for(const o of t){if(!o.isIntersecting){this._activeTarget=null,this._clearActiveClass(e(o));continue}const t=o.target.offsetTop>=this._previousScrollData.visibleEntryTop;if(n&&t){if(s(o),!i)return}else n||t||s(o)}}_initializeTargetsAndObservables(){this._targetLinks=new Map,this._observableSections=new Map;const t=V.find(ze,this._config.target);for(const e of t){if(!e.hash||d(e))continue;const t=V.findOne(e.hash,this._element);h(t)&&(this._targetLinks.set(e.hash,e),this._observableSections.set(e.hash,t))}}_process(t){this._activeTarget!==t&&(this._clearActiveClass(this._config.target),this._activeTarget=t,t.classList.add($e),this._activateParents(t),F.trigger(this._element,"activate.bs.scrollspy",{relatedTarget:t}))}_activateParents(t){if(t.classList.contains("dropdown-item"))V.findOne(".dropdown-toggle",t.closest(".dropdown")).classList.add($e);else for(const e of V.parents(t,".nav, .list-group"))for(const t of V.prev(e,".nav-link, .nav-item > .nav-link, .list-group-item"))t.classList.add($e)}_clearActiveClass(t){t.classList.remove($e);const e=V.find("[href].active",t);for(const t of e)t.classList.remove($e)}static jQueryInterface(t){return this.each((function(){const e=qe.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}F.on(window,"load.bs.scrollspy.data-api",(()=>{for(const t of V.find('[data-bs-spy="scroll"]'))qe.getOrCreateInstance(t)})),b(qe);const We="ArrowLeft",Re="ArrowRight",Ve="ArrowUp",Ke="ArrowDown",Qe="active",Xe="fade",Ye="show",Ue='[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',Ge=`.nav-link:not(.dropdown-toggle), .list-group-item:not(.dropdown-toggle), [role="tab"]:not(.dropdown-toggle), ${Ue}`;class Je extends W{constructor(t){super(t),this._parent=this._element.closest('.list-group, .nav, [role="tablist"]'),this._parent&&(this._setInitialAttributes(this._parent,this._getChildren()),F.on(this._element,"keydown.bs.tab",(t=>this._keydown(t))))}static get NAME(){return"tab"}show(){const t=this._element;if(this._elemIsActive(t))return;const e=this._getActiveElem(),s=e?F.trigger(e,"hide.bs.tab",{relatedTarget:t}):null;F.trigger(t,"show.bs.tab",{relatedTarget:e}).defaultPrevented||s&&s.defaultPrevented||(this._deactivate(e,t),this._activate(t,e))}_activate(t,e){t&&(t.classList.add(Qe),this._activate(V.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.removeAttribute("tabindex"),t.setAttribute("aria-selected",!0),this._toggleDropDown(t,!0),F.trigger(t,"shown.bs.tab",{relatedTarget:e})):t.classList.add(Ye)}),t,t.classList.contains(Xe)))}_deactivate(t,e){t&&(t.classList.remove(Qe),t.blur(),this._deactivate(V.getElementFromSelector(t)),this._queueCallback((()=>{"tab"===t.getAttribute("role")?(t.setAttribute("aria-selected",!1),t.setAttribute("tabindex","-1"),this._toggleDropDown(t,!1),F.trigger(t,"hidden.bs.tab",{relatedTarget:e})):t.classList.remove(Ye)}),t,t.classList.contains(Xe)))}_keydown(t){if(![We,Re,Ve,Ke].includes(t.key))return;t.stopPropagation(),t.preventDefault();const e=[Re,Ke].includes(t.key),s=w(this._getChildren().filter((t=>!d(t))),t.target,e,!0);s&&(s.focus({preventScroll:!0}),Je.getOrCreateInstance(s).show())}_getChildren(){return V.find(Ge,this._parent)}_getActiveElem(){return this._getChildren().find((t=>this._elemIsActive(t)))||null}_setInitialAttributes(t,e){this._setAttributeIfNotExists(t,"role","tablist");for(const t of e)this._setInitialAttributesOnChild(t)}_setInitialAttributesOnChild(t){t=this._getInnerElement(t);const e=this._elemIsActive(t),s=this._getOuterElement(t);t.setAttribute("aria-selected",e),s!==t&&this._setAttributeIfNotExists(s,"role","presentation"),e||t.setAttribute("tabindex","-1"),this._setAttributeIfNotExists(t,"role","tab"),this._setInitialAttributesOnTargetPanel(t)}_setInitialAttributesOnTargetPanel(t){const e=V.getElementFromSelector(t);e&&(this._setAttributeIfNotExists(e,"role","tabpanel"),t.id&&this._setAttributeIfNotExists(e,"aria-labelledby",`${t.id}`))}_toggleDropDown(t,e){const s=this._getOuterElement(t);if(!s.classList.contains("dropdown"))return;const i=(t,i)=>{const n=V.findOne(t,s);n&&n.classList.toggle(i,e)};i(".dropdown-toggle",Qe),i(".dropdown-menu",Ye),s.setAttribute("aria-expanded",e)}_setAttributeIfNotExists(t,e,s){t.hasAttribute(e)||t.setAttribute(e,s)}_elemIsActive(t){return t.classList.contains(Qe)}_getInnerElement(t){return t.matches(Ge)?t:V.findOne(Ge,t)}_getOuterElement(t){return t.closest(".nav-item, .list-group-item")||t}static jQueryInterface(t){return this.each((function(){const e=Je.getOrCreateInstance(this);if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t]()}}))}}F.on(document,"click.bs.tab",Ue,(function(t){["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this)||Je.getOrCreateInstance(this).show()})),F.on(window,"load.bs.tab",(()=>{for(const t of V.find('.active[data-bs-toggle="tab"], .active[data-bs-toggle="pill"], .active[data-bs-toggle="list"]'))Je.getOrCreateInstance(t)})),b(Je);const Ze="hide",ts="show",es="showing",ss={animation:"boolean",autohide:"boolean",delay:"number"},is={animation:!0,autohide:!0,delay:5e3};class ns extends W{constructor(t,e){super(t,e),this._timeout=null,this._hasMouseInteraction=!1,this._hasKeyboardInteraction=!1,this._setListeners()}static get Default(){return is}static get DefaultType(){return ss}static get NAME(){return"toast"}show(){F.trigger(this._element,"show.bs.toast").defaultPrevented||(this._clearTimeout(),this._config.animation&&this._element.classList.add("fade"),this._element.classList.remove(Ze),g(this._element),this._element.classList.add(ts,es),this._queueCallback((()=>{this._element.classList.remove(es),F.trigger(this._element,"shown.bs.toast"),this._maybeScheduleHide()}),this._element,this._config.animation))}hide(){this.isShown()&&(F.trigger(this._element,"hide.bs.toast").defaultPrevented||(this._element.classList.add(es),this._queueCallback((()=>{this._element.classList.add(Ze),this._element.classList.remove(es,ts),F.trigger(this._element,"hidden.bs.toast")}),this._element,this._config.animation)))}dispose(){this._clearTimeout(),this.isShown()&&this._element.classList.remove(ts),super.dispose()}isShown(){return this._element.classList.contains(ts)}_maybeScheduleHide(){this._config.autohide&&(this._hasMouseInteraction||this._hasKeyboardInteraction||(this._timeout=setTimeout((()=>{this.hide()}),this._config.delay)))}_onInteraction(t,e){switch(t.type){case"mouseover":case"mouseout":this._hasMouseInteraction=e;break;case"focusin":case"focusout":this._hasKeyboardInteraction=e}if(e)return void this._clearTimeout();const s=t.relatedTarget;this._element===s||this._element.contains(s)||this._maybeScheduleHide()}_setListeners(){F.on(this._element,"mouseover.bs.toast",(t=>this._onInteraction(t,!0))),F.on(this._element,"mouseout.bs.toast",(t=>this._onInteraction(t,!1))),F.on(this._element,"focusin.bs.toast",(t=>this._onInteraction(t,!0))),F.on(this._element,"focusout.bs.toast",(t=>this._onInteraction(t,!1)))}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){const e=ns.getOrCreateInstance(this,t);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return K(ns),b(ns),{Alert:Q,Button:Y,Carousel:ct,Collapse:mt,Dropdown:xt,Modal:ne,Offcanvas:_e,Popover:je,ScrollSpy:qe,Tab:Je,Toast:ns,Tooltip:Pe}})); 7 | //# sourceMappingURL=bootstrap.min.js.map -------------------------------------------------------------------------------- /js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Dijkstra-Bootstrap v1.0.0 (https://github.com/vittorioPiotti/Dijkstra-Bootstrap/releases/tag/v1.0.0) 3 | Copyright 2024 Vittorio Piotti 4 | Licensed under GPL-3.0 (https://github.com/vittorioPiotti/Dijkstra-Bootstrap/blob/main/LICENSE.md) 5 | */ 6 | 7 | 8 | 9 | /*! 10 | * Bootstrap v4.0.0 (https://getbootstrap.com) 11 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 12 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 13 | */ 14 | 15 | 16 | /** 17 | * vis.js 18 | * https://github.com/almende/vis 19 | * 20 | * A dynamic, browser-based visualization library. 21 | * 22 | * @version 4.21.0 23 | * @date 2017-10-12 24 | * 25 | * @license 26 | * Copyright (C) 2011-2017 Almende B.V, http://almende.com 27 | * 28 | * Vis.js is dual licensed under both 29 | * 30 | * * The Apache 2.0 License 31 | * http://www.apache.org/licenses/LICENSE-2.0 32 | * 33 | * and 34 | * 35 | * * The MIT License 36 | * http://opensource.org/licenses/MIT 37 | * 38 | * Vis.js may be distributed under either license. 39 | */ 40 | 41 | 42 | const ELIMINA = '' 43 | const CREA = ' ' 44 | const MODIFICA = '' 45 | const INFINITY = '' 46 | const ARROW_FORK = '' 47 | const ARROW_REVERSE = '' 48 | const ARROW_CHANGE = '' 49 | 50 | var nodes, edges, network, clickedNodeId = null, 51 | clickedNodeLabel = "", 52 | labels = {}; 53 | var X; 54 | var Y; 55 | var Edges; 56 | var Nodes; 57 | const nodeDefaultColor = 'rgb(0, 140, 255)' 58 | for (let i = 65; i <= 90; i++) 59 | { 60 | labels[String.fromCharCode(i)] = { 61 | used: false 62 | }; 63 | } 64 | 65 | function getNextNode() 66 | { 67 | for (const letter in labels) 68 | { 69 | if (!labels[letter].used) 70 | { 71 | return letter; 72 | } 73 | } 74 | return null; 75 | } 76 | class Node 77 | { 78 | static lastId = 0; 79 | constructor(newId, newLabel) 80 | { 81 | if (newId != null) 82 | { 83 | Node.lastId = newId; 84 | var newLabel = newLabel.replace(/\s/g, ""); 85 | labels[newLabel].used = true; 86 | return { 87 | id: newId, 88 | label: ' ' + newLabel + ' ', 89 | shape: 'circle', 90 | }; 91 | } 92 | else 93 | { 94 | Node.lastId++; 95 | const label = getNextNode(); 96 | labels[label].used = true; 97 | const id = Node.lastId.toString(); 98 | return { 99 | id: id, 100 | label: ' ' + label + ' ', 101 | shape: 'circle', 102 | }; 103 | } 104 | } 105 | } 106 | class Edge 107 | { 108 | static lastId = 0; 109 | constructor(from, to, label, newId) 110 | { 111 | if (newId != null) 112 | { 113 | Edge.lastId = newId; 114 | } 115 | else 116 | { 117 | Edge.lastId++; 118 | } 119 | const id = Edge.lastId; 120 | return { 121 | id: id, 122 | from: from, 123 | to: to, 124 | label: ' ' + label + ' ', 125 | arrows: 126 | { 127 | to: false, 128 | from: false 129 | } 130 | } 131 | } 132 | } 133 | // convenience method to stringify a JSON object 134 | function toJSON(obj) 135 | { 136 | return JSON.stringify(obj, null, 4); 137 | } 138 | 139 | function addNode() 140 | { 141 | nodes.add([ 142 | new Node(), 143 | ]); 144 | if (nodes.length >= 2) 145 | { 146 | document.getElementById("inizio").disabled = false; 147 | document.getElementById("arrivo").disabled = false; 148 | } 149 | else 150 | { 151 | document.getElementById("inizio").disabled = true; 152 | document.getElementById("arrivo").disabled = true; 153 | } 154 | newDiv.style.display = "none"; 155 | gestioneInputNodi(); 156 | } 157 | 158 | function removeNode() 159 | { 160 | newDiv.style.display = "none"; 161 | const key = clickedNodeLabel.trim().charCodeAt(0); 162 | labels[String.fromCharCode(key)].used = false; 163 | // Rimuovi tutti gli archi con from e to uguale a id 164 | edges.forEach(function(edge) 165 | { 166 | if (edge.from == clickedNodeId || edge.to == clickedNodeId) 167 | { 168 | edges.remove( 169 | { 170 | id: edge.id 171 | }) 172 | } 173 | }); 174 | // Rimuovi il nodo con id specificato 175 | nodes.remove( 176 | { 177 | id: clickedNodeId 178 | }) 179 | if (nodes.length < 2) 180 | { 181 | document.getElementById("inizio").disabled = true; 182 | document.getElementById("arrivo").disabled = true; 183 | } 184 | clickedNodeId = null; 185 | gestioneInputNodi(); 186 | } 187 | 188 | function addEdge() 189 | { 190 | try 191 | { 192 | edges.add( 193 | { 194 | id: document.getElementById('edge-id').value, 195 | from: document.getElementById('edge-from').value, 196 | to: document.getElementById('edge-to').value 197 | }); 198 | } 199 | catch (err) 200 | { 201 | alert(err); 202 | } 203 | } 204 | 205 | function updateEdge() 206 | { 207 | try 208 | { 209 | edges.update( 210 | { 211 | id: document.getElementById('edge-id').value, 212 | from: document.getElementById('edge-from').value, 213 | to: document.getElementById('edge-to').value 214 | }); 215 | } 216 | catch (err) 217 | { 218 | alert(err); 219 | } 220 | } 221 | 222 | function removeEdge() 223 | { 224 | try 225 | { 226 | edges.remove( 227 | { 228 | id: document.getElementById('edge-id').value 229 | }); 230 | } 231 | catch (err) 232 | { 233 | alert(err); 234 | } 235 | } 236 | let init = true; 237 | 238 | function draw() 239 | { 240 | for (let i = 65; i <= 90; i++) 241 | { 242 | labels[String.fromCharCode(i)] = { 243 | used: false 244 | }; 245 | } 246 | // create an array with nodes 247 | nodes = new vis.DataSet(); 248 | nodes.on('*', function() 249 | { 250 | Nodes = JSON.stringify(nodes.get().map(function(node) 251 | { 252 | return { 253 | id: node.id, 254 | label: node.label 255 | }; 256 | }), null, 4); 257 | }); 258 | if (init == true) 259 | { 260 | nodes.add([ 261 | new Node(), 262 | new Node(), 263 | new Node(), 264 | new Node(), 265 | ]); 266 | } 267 | // create an array with edges 268 | edges = new vis.DataSet(); 269 | edges.on('*', function() 270 | { 271 | Edges = JSON.stringify(edges.get().map(function(edge) 272 | { 273 | var arrows = edge.arrows ? edge.arrows : 274 | { 275 | to: false 276 | }; // Imposta le frecce a false se non sono presenti 277 | return { 278 | id: edge.id, 279 | from: edge.from, 280 | to: edge.to, 281 | label: edge.label, 282 | arrowTo: arrows.to, 283 | arrowFrom: arrows.from 284 | }; 285 | }), null, 4); 286 | }); 287 | if (init == true) 288 | { 289 | edges.add([ 290 | new Edge(1, 2, 2), 291 | new Edge(2, 4, 1), 292 | new Edge(3, 2, 1), 293 | new Edge(4, 1, 1), 294 | new Edge(1, 3, 1), 295 | ]); 296 | } 297 | // create a network 298 | var container = document.getElementById('network'); 299 | var data = { 300 | nodes: nodes, 301 | edges: edges 302 | }; 303 | var options = { 304 | nodes: 305 | { 306 | font: 307 | { 308 | color: 'rgb(255,255,255)', 309 | size: 20 310 | }, 311 | color: 312 | { 313 | background: nodeDefaultColor, 314 | border: 'rgb(0, 140, 255)' 315 | }, 316 | size: 30, 317 | chosen: true, 318 | }, 319 | edges: 320 | { 321 | selectionWidth: 4, 322 | arrowStrikethrough: false, 323 | smooth: false, 324 | font: 325 | { 326 | background: 'rgb(255,255,255)', 327 | size: 20 328 | }, 329 | width: 2, 330 | chosen: false, 331 | color: 332 | { 333 | inherit: false 334 | } 335 | }, 336 | physics: 337 | { 338 | barnesHut: 339 | { 340 | gravitationalConstant: -10000, 341 | centralGravity: 0.5, 342 | springLength: 100, 343 | damping: 0.5, 344 | avoidOverlap: 5 345 | } 346 | } 347 | }; 348 | network = new vis.Network(container, data, options); 349 | network.on('click', function(params) 350 | { 351 | if (params.nodes.length > 0) 352 | { 353 | clickedNodeId = params.nodes[0]; 354 | clickedNodeLabel = network.body.nodes[clickedNodeId].options.label; 355 | } 356 | }); 357 | if (nodes.length < 2) 358 | { 359 | document.getElementById("inizio").disabled = true; 360 | document.getElementById("arrivo").disabled = true; 361 | } 362 | network.on("doubleClick", function(params) 363 | { 364 | var x = event.clientX; 365 | var y = event.clientY; 366 | X = x; 367 | Y = y; 368 | if (document.body.contains(oneDiv)) document.body.removeChild(oneDiv); 369 | resettaColoreNodi(); 370 | let x2, y2; 371 | if (params.nodes.length > 0) 372 | { 373 | x2 = 25; 374 | y2 = 25 375 | } 376 | else if (params.edges.length > 0) 377 | { 378 | x2 = 40; 379 | y2 = 40 380 | } 381 | else 382 | { 383 | x2 = 15; 384 | y2 = 15 385 | } 386 | newDiv.style.left = (x + x2) + "px" 387 | newDiv.style.top = (y - y2) + "px" 388 | newDiv.style.display = "block"; 389 | // mostro il nuovo div 390 | if (params.nodes.length > 0) 391 | { 392 | STARTNODE = params.nodes[0] 393 | // Double click on an edge 394 | /* 395 | const nodeOptions = new bootstrap.Modal(document.getElementById("nodeOptions")); 396 | nodeOptions.show(); 397 | */ 398 | clickedNodeId = params.nodes[0]; 399 | // mostro il nuovo div 400 | newDiv.style.display = "block"; 401 | let htmlString = '' + '' 402 | newDiv.innerHTML = htmlString; 403 | } 404 | else if (params.edges.length > 0) 405 | { 406 | // Double click on an edge 407 | var arco = edges.get(idArcoSelezionato); 408 | // mostro il nuovo div 409 | newDiv.style.display = "block"; 410 | let forked = 1; 411 | edges.forEach(function(edge) 412 | { 413 | if (edge.id != idArcoSelezionato && ((arco.to == edge.to && arco.from == edge.from) || (arco.from == edge.to && arco.to == edge.from))) 414 | { 415 | forked = 0; 416 | } 417 | }) 418 | let htmlString; 419 | switch (forked) 420 | { 421 | case 0: 422 | htmlString = '
' + '' + '' + '
' + '
' + '' + '
' 423 | break; 424 | case 1: 425 | htmlString = '
' + '' + '' + '
' + '
' + '' + '' + '
' 426 | break; 427 | } 428 | newDiv.innerHTML = htmlString; 429 | /* 430 | const edgeOptions = new bootstrap.Modal(document.getElementById("edgeOptions")); 431 | edgeOptions.show(); 432 | */ 433 | } 434 | else 435 | { 436 | var x = event.clientX; 437 | newDiv.style.display = "block"; 438 | let htmlString = ''; 439 | newDiv.innerHTML = htmlString; 440 | } 441 | document.body.appendChild(newDiv); 442 | document.addEventListener("click", function(event) 443 | { 444 | if (!newDiv.contains(event.target)) 445 | { 446 | newDiv.style.display = "block"; 447 | document.addEventListener("click", function(event) 448 | { 449 | if (!newDiv.contains(event.target)) 450 | { 451 | newDiv.style.display = "none"; 452 | } 453 | }); 454 | } 455 | }); 456 | }); 457 | var close = null; 458 | network.on("select", function(params) 459 | { 460 | var selectedNodeIds = params.nodes; 461 | if (selectedNodeIds.length > 0) 462 | { 463 | // selezionato solo il nodo, deseleziona gli archi 464 | var edgeIds = edges.getIds(); 465 | for (var i = 0; i < edgeIds.length; i++) 466 | { 467 | var edge = edges.get(edgeIds[i]); 468 | edge.width = options.edges.width; 469 | edges.update(edge); 470 | if (STARTNODE == params.nodes[0] && nuovoArco == true) nuovoArco = false; 471 | } 472 | } 473 | else 474 | { 475 | // selezionato solo l'arco 476 | var selectedEdgeId = params.edges[0]; 477 | var edge = edges.get(selectedEdgeId); 478 | edge.width = options.edges.selectionWidth; 479 | edges.update(edge); 480 | } 481 | }); 482 | network.on("deselectNode", function(params) 483 | { 484 | var selectedEdgeId = params.previousSelection.edges[0]; 485 | var edge = edges.get(selectedEdgeId); 486 | edge.width = options.edges.width; 487 | edges.update(edge); 488 | }); 489 | network.on("selectEdge", function(params) 490 | { 491 | var selectedEdgeId = params.edges[0]; 492 | var edge = edges.get(selectedEdgeId); 493 | edge.width = options.edges.selectionWidth; 494 | edges.update(edge); 495 | idArcoSelezionato = selectedEdgeId; 496 | }); 497 | network.on("deselectEdge", function(params) 498 | { 499 | var selectedEdgeId = params.previousSelection.edges[0]; 500 | var edge = edges.get(selectedEdgeId); 501 | edge.width = options.edges.width; 502 | edges.update(edge); 503 | }); 504 | gestioneInputNodi(); 505 | init = false; 506 | } 507 | let versoArco = {}; 508 | 509 | function orienta() 510 | { 511 | if (versoArco[idArcoSelezionato] == null) versoArco[idArcoSelezionato] = 0; 512 | if (edges.get(idArcoSelezionato).arrows.to == true) 513 | { 514 | versoArco[idArcoSelezionato] = 2; 515 | } 516 | else if (edges.get(idArcoSelezionato).arrows.from == true) 517 | { 518 | versoArco[idArcoSelezionato] = 3; 519 | } 520 | else versoArco[idArcoSelezionato]++; 521 | switch (versoArco[idArcoSelezionato]) 522 | { 523 | case 1: 524 | edges.update( 525 | { 526 | id: idArcoSelezionato, 527 | arrows: 528 | { 529 | to: true, 530 | from: false 531 | } 532 | }) 533 | break; 534 | case 2: 535 | edges.update( 536 | { 537 | id: idArcoSelezionato, 538 | arrows: 539 | { 540 | to: false, 541 | from: true 542 | } 543 | }) 544 | break; 545 | case 3: 546 | edges.update( 547 | { 548 | id: idArcoSelezionato, 549 | arrows: 550 | { 551 | to: false, 552 | from: false 553 | } 554 | }) 555 | versoArco[idArcoSelezionato] = 0; 556 | break; 557 | } 558 | } 559 | 560 | function orientaReverse() 561 | { 562 | let id = idArcoAssociato(idArcoSelezionato); 563 | if (edges.get(idArcoSelezionato).arrows.to == true) 564 | { 565 | edges.update( 566 | { 567 | id: idArcoSelezionato, 568 | arrows: 569 | { 570 | to: false, 571 | from: true 572 | } 573 | }) 574 | edges.update( 575 | { 576 | id: id, 577 | arrows: 578 | { 579 | to: true, 580 | from: false 581 | } 582 | }) 583 | } 584 | else if (edges.get(idArcoSelezionato).arrows.from == true) 585 | { 586 | edges.update( 587 | { 588 | id: idArcoSelezionato, 589 | arrows: 590 | { 591 | to: true, 592 | from: false 593 | } 594 | }) 595 | edges.update( 596 | { 597 | id: id, 598 | arrows: 599 | { 600 | to: false, 601 | from: true 602 | } 603 | }) 604 | } 605 | } 606 | 607 | function forkArrow() 608 | { 609 | newDiv.style.display = "none"; 610 | edges.update( 611 | { 612 | id: idArcoSelezionato, 613 | smooth: true 614 | }); 615 | var arco = edges.get(idArcoSelezionato); 616 | arco.smooth = true; 617 | edges.update(arco); 618 | let label = arco.label.replace(/\s/g, ""); 619 | edges.add([ 620 | new Edge(arco.from, arco.to, label), 621 | ]) 622 | var id = idArcoAssociato(idArcoSelezionato); 623 | var arco2 = edges.get(id); 624 | arco2.smooth = true; 625 | edges.update(arco2); 626 | let verso 627 | if (edges.get(idArcoSelezionato).arrows.to == false && edges.get(idArcoSelezionato).arrows.from == false) 628 | { 629 | verso = parseInt(Math.random() * 2) 630 | if (verso == 0) 631 | { 632 | edges.update( 633 | { 634 | id: idArcoSelezionato, 635 | arrows: 636 | { 637 | to: true, 638 | from: false 639 | } 640 | }) 641 | edges.update( 642 | { 643 | id: id, 644 | arrows: 645 | { 646 | to: false, 647 | from: true 648 | } 649 | }) 650 | } 651 | else 652 | { 653 | edges.update( 654 | { 655 | id: idArcoSelezionato, 656 | arrows: 657 | { 658 | to: false, 659 | from: true 660 | } 661 | }) 662 | edges.update( 663 | { 664 | id: id, 665 | arrows: 666 | { 667 | to: true, 668 | from: false 669 | } 670 | }) 671 | } 672 | } 673 | else if (edges.get(idArcoSelezionato).arrows.to == true) 674 | { 675 | edges.update( 676 | { 677 | id: id, 678 | arrows: 679 | { 680 | to: false, 681 | from: true 682 | } 683 | }) 684 | } 685 | else 686 | { 687 | edges.update( 688 | { 689 | id: id, 690 | arrows: 691 | { 692 | to: true, 693 | from: false 694 | } 695 | }) 696 | } 697 | } 698 | 699 | function idArcoAssociato(arcoSelezionato) 700 | { 701 | var arco = edges.get(arcoSelezionato); 702 | let id = null; 703 | edges.forEach(function(edge) 704 | { 705 | if (edge.id != arcoSelezionato && ((arco.to == edge.to && arco.from == edge.from) || (arco.from == edge.to && arco.to == edge.from))) 706 | { 707 | id = edge.id; 708 | } 709 | }); 710 | return id; 711 | } 712 | var newDiv = document.createElement("div"); 713 | newDiv.style.position = "absolute" 714 | var oneDiv = document.createElement("div"); 715 | oneDiv.style.position = "absolute" 716 | let oldOptionArrivo; 717 | let newOptionArrivo; 718 | let indexArrivo; 719 | let indexInizio; 720 | let oldOptionInizio; 721 | let newOptionInizio; 722 | 723 | function gestioneInputNodi() 724 | { 725 | document.getElementById("inizio").innerHTML = initInputNodi(); 726 | document.getElementById("arrivo").innerHTML = initInputNodi(); 727 | const inputArrivo = document.getElementById('arrivo'); 728 | const valueArrivo = inputArrivo.value; 729 | const inputInizio = document.getElementById('inizio'); 730 | const valueInizio = inputInizio.value; 731 | newOptionInizio = valueInizio; 732 | newOptionArrivo = valueArrivo; 733 | if (valueInizio == valueArrivo) 734 | { 735 | inputArrivo.selectedIndex = 1; 736 | newOptionArrivo = inputArrivo.value; 737 | } 738 | indexInizio = inputInizio.selectedIndex; 739 | indexArrivo = inputArrivo.selectedIndex; 740 | start = inputInizio.value; 741 | end = inputArrivo.value 742 | inputArrivo.addEventListener("change", function() 743 | { 744 | oldOptionArrivo = newOptionArrivo; 745 | // Aggiornamento opzione selezionata attualmente 746 | newOptionArrivo = this.options[this.selectedIndex].value; 747 | if (newOptionInizio == newOptionArrivo) 748 | { 749 | inputInizio.selectedIndex = indexArrivo; 750 | newOptionInizio = inputInizio.value; 751 | } 752 | indexInizio = inputInizio.selectedIndex; 753 | indexArrivo = inputArrivo.selectedIndex; 754 | start = inputInizio.value; 755 | end = inputArrivo.value 756 | }); 757 | inputInizio.addEventListener("change", function() 758 | { 759 | oldOptionInizio = newOptionInizio; 760 | // Aggiornamento opzione selezionata attualmente 761 | newOptionInizio = this.options[this.selectedIndex].value; 762 | if (newOptionInizio == newOptionArrivo) 763 | { 764 | inputArrivo.selectedIndex = indexInizio; 765 | newOptionArrivo = inputArrivo.value; 766 | } 767 | indexInizio = inputInizio.selectedIndex; 768 | indexArrivo = inputArrivo.selectedIndex; 769 | start = inputInizio.value; 770 | end = inputArrivo.value 771 | }); 772 | } 773 | 774 | function initInputNodi() 775 | { 776 | let input = ""; 777 | let selected = "selected"; 778 | if (nodes.length >= 2) 779 | { 780 | document.getElementById("inizio").disabled = false; 781 | document.getElementById("arrivo").disabled = false; 782 | } 783 | else 784 | { 785 | document.getElementById("inizio").disabled = true; 786 | document.getElementById("arrivo").disabled = true; 787 | } 788 | nodes.forEach(function(node) 789 | { 790 | input += "" 791 | selected = ""; 792 | }) 793 | return input; 794 | } 795 | 796 | function creaEdge() 797 | { 798 | nuovoArco = true; 799 | var startNode = clickedNodeId; 800 | newDiv.style.display = 'none' 801 | var nodo = nodes.get(STARTNODE); 802 | nodo.color = "gray"; 803 | nodes.update(nodo); 804 | edges.forEach(function(edge) 805 | { 806 | var idNode = null; 807 | if (edge.from == STARTNODE) 808 | { 809 | idNode = edge.to; 810 | } 811 | else if (edge.to == STARTNODE) 812 | { 813 | idNode = edge.from; 814 | } 815 | else idNode = null; 816 | if (idNode != null) 817 | { 818 | var nodo = nodes.get(idNode); 819 | nodo.color = "gray"; 820 | nodes.update(nodo); 821 | } 822 | }) 823 | network.on("click", function(params) 824 | { 825 | var selectedNodeIds = params.nodes; 826 | if (selectedNodeIds.length > 0) 827 | { 828 | var endNode = params.nodes[0]; 829 | edges.forEach(function(edge) 830 | { 831 | if ((edge.from == STARTNODE && edge.to == endNode) || (edge.from == endNode && edge.to == STARTNODE)) 832 | { 833 | nuovoArco = false; 834 | resettaColoreNodi(); 835 | } 836 | }) 837 | if (nuovoArco == true) 838 | { 839 | var x = event.clientX; 840 | var y = event.clientY; 841 | oneDiv.style.left = (x + 25) + "px" 842 | oneDiv.style.top = (y - 25) + "px" 843 | // mostro il nuovo div 844 | oneDiv.style.display = "block"; 845 | let inputGroup = ` 846 |
847 | 848 | 849 |
850 | 851 | `; 852 | oneDiv.innerHTML = inputGroup; 853 | document.body.appendChild(oneDiv); 854 | document.addEventListener("click", function(event) 855 | { 856 | if (!oneDiv.contains(event.target)) 857 | { 858 | oneDiv.style.display = "block"; 859 | document.addEventListener("click", function(event) 860 | { 861 | if (!oneDiv.contains(event.target)) 862 | { 863 | oneDiv.style.display = "none"; 864 | } 865 | }); 866 | } 867 | }) 868 | } 869 | } 870 | else 871 | { 872 | nuovoArco = false; 873 | resettaColoreNodi(); 874 | oneDiv.style.display = "none"; 875 | }; 876 | // richiesta del valore di label per l'arco 877 | // resetta clickedNodeId 878 | ENDNODE = endNode; 879 | clickedNodeId = null; 880 | }); 881 | } 882 | var X; 883 | var Y; 884 | var nuovoArco = false; 885 | var idArcoSelezionato = 0; 886 | var STARTNODE = null; 887 | var ENDNODE = null; 888 | 889 | function edgeCost() 890 | { 891 | var inputVal = document.getElementById("edgeCost").value; 892 | if (/^[1-9]\d*$/.test(inputVal)) 893 | { 894 | nuovoArco = false; 895 | resettaColoreNodi(); 896 | edges.add(new Edge(STARTNODE, ENDNODE, " " + inputVal + " ")); 897 | oneDiv.style.display = "none"; 898 | } 899 | } 900 | 901 | function rimuoviArco() 902 | { 903 | let id = idArcoAssociato(idArcoSelezionato); 904 | edges.remove(idArcoSelezionato); 905 | if (id != null) 906 | { 907 | var arco = edges.get(id); 908 | arco.smooth = false; 909 | edges.update(arco); 910 | } 911 | newDiv.style.display = "none"; 912 | } 913 | 914 | function edgeCostModifica() 915 | { 916 | var inputVal = document.getElementById("edgeCostModifica").value; 917 | if (/^[1-9]\d*$/.test(inputVal) && edges.get(idArcoSelezionato).label.trim() != inputVal) 918 | { 919 | edges.update( 920 | { 921 | id: idArcoSelezionato, 922 | label: " " + inputVal + " " 923 | }); 924 | oneDiv.style.display = "none"; 925 | } 926 | } 927 | 928 | function modificaArco() 929 | { 930 | var x = X; 931 | var y = Y; 932 | newDiv.style.display = 'none' 933 | oneDiv.style.left = (x + 25) + "px" 934 | oneDiv.style.top = (y - 25) + "px" 935 | // mostro il nuovo div 936 | let inputGroup = ` 937 |
938 | 939 | 940 |
941 | `; 942 | if (document.body.contains(newDiv)) document.body.removeChild(newDiv); 943 | oneDiv.innerHTML = inputGroup; 944 | document.body.appendChild(oneDiv); 945 | document.addEventListener("click", function(event) 946 | { 947 | if (!oneDiv.contains(event.target)) 948 | { 949 | oneDiv.style.display = "block"; 950 | document.addEventListener("click", function(event) 951 | { 952 | if (!oneDiv.contains(event.target)) 953 | { 954 | oneDiv.style.display = "none"; 955 | } 956 | }); 957 | } 958 | }) 959 | } 960 | 961 | function resettaColoreNodi() 962 | { 963 | var coloreDesiderato = nodeDefaultColor; // Colore da assegnare ai nodi 964 | var nodi = nodes.get(); // Ottiene tutti i nodi del dataset 965 | for (var i = 0; i < nodi.length; i++) 966 | { 967 | var nodo = nodi[i]; 968 | if (nodo.color !== coloreDesiderato) 969 | { // Se il colore del nodo è diverso dal colore desiderato 970 | nodo.color = coloreDesiderato; // Cambia il colore del nodo 971 | nodes.update(nodo); // Aggiorna il dataset con il nuovo colore del nodo 972 | } 973 | } 974 | } 975 | //dijkstra 976 | //nodo di arrivo 977 | //nodo di partenza 978 | //esplora nodo meno costoso tra quelli non esplorati 979 | //arrivo al nodo di arrivo col costo minore 980 | //finito se costo minore con tutti i nodi 981 | function set() 982 | { 983 | //direzione freccia 0.entrambe 1.from 2.to 984 | while (nodes.length < 2) addNode(); 985 | var inxA = parseInt(Math.random() * nodes.length); 986 | var inxB = parseInt(Math.random() * nodes.length); 987 | while (inxB == inxA) inxB = parseInt(Math.random() * nodes.length); 988 | var nodeA = nodeInx(inxA) 989 | var nodeB = nodeInx(inxB) 990 | var idA = nodeA.id; 991 | var idB = nodeB.id; 992 | if (edges.length == 0) 993 | { 994 | var cost = parseInt(Math.random() * 99) + 1; 995 | edges.add([ 996 | new Edge(idA, idB, cost), 997 | ]) 998 | } 999 | var versoFreccia = parseInt(Math.random() * 3); 1000 | var app = JSON.parse(Edges); 1001 | var idEdge = app[0].id 1002 | var edge = edges.get(idEdge); 1003 | if (versoFreccia == 0) 1004 | { 1005 | edges.update( 1006 | { 1007 | id: idEdge, 1008 | arrows: 1009 | { 1010 | to: true 1011 | } 1012 | }) 1013 | } 1014 | else if (versoFreccia == 1) 1015 | { 1016 | edges.update( 1017 | { 1018 | id: idEdge, 1019 | arrows: 1020 | { 1021 | from: true 1022 | } 1023 | }) 1024 | } 1025 | } 1026 | 1027 | function nodeInx(idA) 1028 | { 1029 | var nodeA = {}; 1030 | var c = 0; 1031 | nodes.forEach(function(node) 1032 | { 1033 | if (c == idA) 1034 | { 1035 | nodeA = node; 1036 | } 1037 | c++; 1038 | }); 1039 | return nodeA 1040 | } 1041 | 1042 | function load() 1043 | { 1044 | 1045 | 1046 | let textError = '' 1047 | let textOne = (2 - nodes.length); 1048 | let textTwo = (1 - edges.length); 1049 | if (nodes.length < 2) textOne = 'nodes ( ' + (2 - nodes.length) + ' )'; 1050 | else textOne = ' ' 1051 | if (edges.length == 0) textTwo = 'edges ( ' + (1 - edges.length) + ' )'; 1052 | else textTwo = ' ' 1053 | textError = 'Please enter ' + textOne + ' ' + textTwo; 1054 | document.getElementById("textError").innerHTML = textError; 1055 | let button = '' + '' 1056 | document.getElementById("buttonModal").innerHTML = button; 1057 | const modalError = new bootstrap.Modal(document.getElementById("errore")); 1058 | if (nodes.length < 2 || edges.length == 0) modalError.show() 1059 | else 1060 | { 1061 | flagEdges = false; 1062 | flagNodes = false; 1063 | tabellaAppoggio = {}; 1064 | nodiCollegati = {} 1065 | nodes.forEach(function(node) 1066 | { 1067 | tabellaAppoggio[node.id] = { 1068 | cost: Infinity, 1069 | prec: null, 1070 | used: false 1071 | } 1072 | }) 1073 | tabellaAppoggio[start].cost = 0; 1074 | nodes.forEach(function(node) 1075 | { 1076 | nodiCollegati[node.id] = {}; 1077 | }); 1078 | edges.forEach(function(edge) 1079 | { 1080 | let flag = false; 1081 | label = parseInt(edge.label.replace(/\s/g, '')) 1082 | if (edge.arrows.from == false && edge.arrows.to == false) 1083 | { 1084 | nodiCollegati[edge.to][edge.from] = label; 1085 | nodiCollegati[edge.from][edge.to] = label; 1086 | } 1087 | else if (edge.arrows.from == true) 1088 | { 1089 | nodiCollegati[edge.to][edge.from] = label; 1090 | } 1091 | else 1092 | { 1093 | nodiCollegati[edge.from][edge.to] = label; 1094 | } 1095 | }); 1096 | // dijkstra(); 1097 | Dijkstra(); 1098 | choice = percorsi - 1; 1099 | document.getElementById("output").innerHTML = risultato(); 1100 | } 1101 | } 1102 | //nodo di partenza e nodo di arrivo 1103 | //smette di iterare quando raggiunto nodo di arrivo ed esplorati nodi adiacenti 1104 | //ricerca nodo costo minore non esplorato 1105 | // setta come nodo esplorato 1106 | // aggiorna tabellaAppoggio con 1107 | // for nodicollegati[nodoA] 1108 | // if ( nodicollegati[nodoA][nodoB] + tabellaAppoggio[nodoA].cost < tabellaAppoggio[nodoB].cost) 1109 | // => tabellaAppoggio[nodoB].cost = nodicollegati[nodoA][nodoB] + tabellaAppoggio[nodoA].cost; 1110 | // tabellaAppoggio[nodoB].prec = nodoA; 1111 | // 1112 | // 1113 | function eliminaDoppi() 1114 | { 1115 | let c = 0; 1116 | if (percorsi > 1) 1117 | { 1118 | for (let i = 0; i < percorsi; i++) 1119 | { 1120 | for (let j = 0; j < percorsi; j++) 1121 | { 1122 | if (i != j && percorso[i].length == percorso[j].length) 1123 | { 1124 | c = 0; 1125 | for (let k = 0; k < percorso[i].length; k++) 1126 | { 1127 | if (percorso[i][k] == percorso[j][k]) c++; 1128 | } 1129 | if (c == percorso[i].length) 1130 | { 1131 | percorso.splice(j, 1); 1132 | tab.splice(j, 1); 1133 | percorsi--; 1134 | } 1135 | } 1136 | } 1137 | } 1138 | } 1139 | } 1140 | let flagNodes = false; 1141 | let flagEdges = false; 1142 | let choice = 0; 1143 | function risultato() 1144 | { 1145 | 1146 | 1147 | eliminaDoppi(); 1148 | eliminaDoppi(); 1149 | if (choice >= percorsi) choice = percorsi - 1; 1150 | var risultatoTot = ""; 1151 | var risultato = ""; 1152 | var risultatoDue = ""; 1153 | risultato += '
' 1154 | risultato += 'Routing Table' 1155 | risultato += '
' 1156 | risultato += '
' 1157 | if (percorso[choice].length == 1) 1158 | { 1159 | nodes.forEach(function(node) 1160 | { 1161 | if (node.id == start) 1162 | { 1163 | risultato += '
' 1164 | risultato += node.label; 1165 | risultato += '
' 1166 | } 1167 | }) 1168 | nodes.forEach(function(node) 1169 | { 1170 | if (node.id == end) 1171 | { 1172 | risultato += '
' 1173 | risultato += node.label; 1174 | risultato += '
' 1175 | } 1176 | }) 1177 | } 1178 | else 1179 | { 1180 | for (let i = percorso[choice].length; i >= 0; i--) 1181 | { 1182 | nodes.forEach(function(node) 1183 | { 1184 | if (node.id == percorso[choice][i]) 1185 | { 1186 | risultato += '
' 1187 | risultato += node.label; 1188 | risultato += '
' 1189 | } 1190 | }); 1191 | } 1192 | } 1193 | risultato += '
' 1194 | risultato += '
' 1195 | let spesa = 0; 1196 | let width = 40 1197 | for (let i = percorso[choice].length - 1; i >= 0; i--) 1198 | { 1199 | if (percorso[choice].length == 1) width = 80; 1200 | risultato += '
' 1201 | if (percorso[choice].length == 1) risultato += INFINITY 1202 | else risultato += spesa; 1203 | spesa += nodiCollegati[percorso[choice][i]][percorso[choice][i - 1]] 1204 | risultato += '
' 1205 | } 1206 | risultato += '
' 1207 | risultatoTot += risultato; 1208 | var table = '
'; 1209 | table += "" 1210 | table += "" 1211 | table += "" 1212 | table += "" 1213 | table += "" 1214 | table += " " 1215 | table += "" 1216 | table += "" 1217 | for (let idNodo in tab[choice]) 1218 | { 1219 | table += "" 1220 | table += "" 1229 | table += ""; 1238 | table += ""; 1243 | table += "" 1244 | } 1245 | let spesaTot = costoPercorso; 1246 | if (costoPercorso == 0) spesaTot = INFINITY; 1247 | table += "" 1248 | table += "" 1249 | table += "" 1250 | table += " " 1251 | table += "" 1252 | table += "
NodoPrecedenteCosto
" 1221 | nodes.forEach(function(node) 1222 | { 1223 | if (node.id == idNodo) 1224 | { 1225 | table += node.label; 1226 | } 1227 | }); 1228 | table += "" 1230 | nodes.forEach(function(node) 1231 | { 1232 | if (node.id == tab[choice][idNodo].prec) 1233 | { 1234 | table += node.label; 1235 | } 1236 | }); 1237 | table += "" 1239 | let app = INFINITY; 1240 | if (tab[choice][idNodo].cost != Infinity) app = tab[choice][idNodo].cost; 1241 | table += app; 1242 | table += "
Costo percorso" + spesaTot + "
" 1253 | risultatoDue += '
' 1254 | risultatoDue += table; 1255 | risultatoDue += '
' 1256 | risultatoTot += risultatoDue; 1257 | var risultatoTre = ""; 1258 | if (percorsi > 1 && costoPercorso != 0) 1259 | { 1260 | risultatoTre += "
" 1261 | risultatoTre += '
' 1262 | let border = " border-light border-5 border-end" 1263 | for (let i = percorsi - 1; i >= 0; i--) 1264 | { 1265 | if (i == 0) border = ""; 1266 | if (i == choice) risultatoTre += '
' 1267 | else risultatoTre += '
' 1268 | } 1269 | risultatoTre += '
' 1270 | risultatoTre += '
' 1271 | } 1272 | risultatoTot += risultatoTre 1273 | return risultatoTot; 1274 | } 1275 | let scelta = 0; 1276 | 1277 | function changeChoice(newChoice) 1278 | { 1279 | 1280 | choice = newChoice; 1281 | 1282 | let appNodes = nodes; 1283 | let appEdges = edges; 1284 | if(flagNodes == true){ 1285 | nodes = JSON.parse(NodesApp); 1286 | } 1287 | if(flagEdges == true){ 1288 | edges = JSON.parse(EdgesApp) 1289 | 1290 | } 1291 | 1292 | document.getElementById("output").innerHTML = risultato(); 1293 | if(flagNodes == true){ 1294 | 1295 | nodes = appNodes; 1296 | } 1297 | if(flagEdges == true){ 1298 | 1299 | edges = appEdges; 1300 | } 1301 | } 1302 | 1303 | function ritornaEdge(idNodoA, idNodoB) 1304 | { 1305 | let flag = false; 1306 | edges.forEach(function(edge) 1307 | { 1308 | if (((edge.arrows.to == true || (edge.arrows.to == false && edge.arrows.from == false)) && edge.from == idNodoA && edge.to == idNodoB) || ((edge.arrows.from == true || (edge.arrows.to == false && edge.arrows.from == false)) && edge.from == idNodoB && edge.to == idNodoA)) flag = true; 1309 | }) 1310 | return flag; 1311 | } 1312 | var costoPercorso = 0; 1313 | let cost = []; 1314 | let app = []; 1315 | let prec = []; 1316 | let tab = []; 1317 | let percorsi = 0; 1318 | 1319 | function Dijkstra() 1320 | { 1321 | cost = []; 1322 | app = []; 1323 | prec = []; 1324 | tab = []; 1325 | var flag = false; 1326 | do { 1327 | if (tuttiEsplorati() == true) flag = true; 1328 | else 1329 | { 1330 | var idNodoA = ricercaCostoMinoreTraNonEsplorati(); 1331 | tabellaAppoggio[idNodoA].used = true; 1332 | for (let idNodoB in nodiCollegati[idNodoA]) 1333 | { 1334 | if (nodiCollegati[idNodoA][idNodoB] + tabellaAppoggio[idNodoA].cost < tabellaAppoggio[idNodoB].cost) 1335 | { 1336 | tabellaAppoggio[idNodoB].cost = nodiCollegati[idNodoA][idNodoB] + tabellaAppoggio[idNodoA].cost; 1337 | tabellaAppoggio[idNodoB].prec = idNodoA; 1338 | } 1339 | else if (nodiCollegati[idNodoA][idNodoB] + tabellaAppoggio[idNodoA].cost == tabellaAppoggio[idNodoB].cost) 1340 | { 1341 | cost.push(nodiCollegati[idNodoA][idNodoB] + tabellaAppoggio[idNodoA].cost) 1342 | prec.push(idNodoA) 1343 | app.push(idNodoB) 1344 | } 1345 | } 1346 | } 1347 | } while (flag == false); 1348 | tab[app.length] = {} 1349 | nodes.forEach(function(node) 1350 | { 1351 | tab[app.length][node.id] = { 1352 | cost: tabellaAppoggio[node.id].cost, 1353 | prec: tabellaAppoggio[node.id].prec, 1354 | used: tabellaAppoggio[node.id].used 1355 | } 1356 | }) 1357 | percorsi = app.length + 1; 1358 | for (let i = 0; i < app.length; i++) 1359 | { 1360 | tab[i] = {} 1361 | nodes.forEach(function(node) 1362 | { 1363 | if (node.id == app[i]) 1364 | { 1365 | tab[i][node.id] = { 1366 | cost: cost[i], 1367 | prec: prec[i], 1368 | used: true 1369 | } 1370 | } 1371 | else 1372 | { 1373 | tab[i][node.id] = { 1374 | cost: tabellaAppoggio[node.id].cost, 1375 | prec: tabellaAppoggio[node.id].prec, 1376 | used: tabellaAppoggio[node.id].used 1377 | } 1378 | } 1379 | }) 1380 | } 1381 | initPercorso(percorsi - 1); 1382 | } 1383 | 1384 | function initPercorso() 1385 | { 1386 | var flag = false; 1387 | var idNodo = end; 1388 | percorso = []; 1389 | for (let i = 0; i < percorsi; i++) 1390 | { 1391 | percorso[i] = [] 1392 | costoPercorso = 0; 1393 | flag = false; 1394 | idNodo = end; 1395 | do { 1396 | percorso[i].push(idNodo) 1397 | edges.forEach(function(edge) 1398 | { 1399 | if (((edge.from == idNodo && edge.to == tab[i][idNodo].prec && (edge.arrows.from == true || (edge.arrows.to == false && edge.arrows.from == false))) || (edge.to == idNodo && edge.from == tab[i][idNodo].prec && (edge.arrows.to == true || (edge.arrows.to == false && edge.arrows.from == false))))) 1400 | { 1401 | edge.label = edge.label.trim(); 1402 | edge.label = Number(edge.label); 1403 | costoPercorso += edge.label; 1404 | } 1405 | }) 1406 | idNodo = tab[i][idNodo].prec 1407 | if (idNodo == null) flag = true 1408 | } while (flag == false); 1409 | } 1410 | if (costoPercorso == 0) 1411 | { 1412 | tab.splice(0, percorsi - 1) 1413 | percorso.splice(0, percorso.length - 1) 1414 | tab[0] = {} 1415 | nodes.forEach(function(node) 1416 | { 1417 | tab[0][node.id] = { 1418 | cost: tabellaAppoggio[node.id].cost, 1419 | prec: tabellaAppoggio[node.id].prec, 1420 | used: tabellaAppoggio[node.id].used 1421 | } 1422 | }) 1423 | percorsi = 1; 1424 | } 1425 | } 1426 | 1427 | function tuttiEsplorati() 1428 | { 1429 | var visitati = 0; 1430 | var nodi = Object.keys(tabellaAppoggio) 1431 | var numeroNodi = nodi.length 1432 | for (let key in tabellaAppoggio) 1433 | { 1434 | if (tabellaAppoggio[key].used == true) visitati++; 1435 | } 1436 | if (visitati == numeroNodi) return true; 1437 | return false; 1438 | } 1439 | 1440 | function ricercaCostoMinoreTraNonEsplorati() 1441 | { 1442 | var min = Infinity; 1443 | var keyMin = null; //se tutti esplorati 1444 | for (let key in tabellaAppoggio) 1445 | { 1446 | if (tabellaAppoggio[key].used == false && tabellaAppoggio[key].cost <= min) 1447 | { 1448 | min = tabellaAppoggio[key].cost; 1449 | keyMin = key 1450 | } 1451 | } 1452 | return keyMin; 1453 | } 1454 | var tabellaAppoggio = {}; 1455 | var nodiCollegati = {} 1456 | var spesa = 0; 1457 | var start = null; 1458 | var end = null; 1459 | var percorso = []; 1460 | let fJson = []; 1461 | let EdgesApp; 1462 | let NodesApp; 1463 | function resetta(){ 1464 | if(flagNodes == false && flagEdges == false){ 1465 | flagEdges = true; 1466 | flagNodes = true; 1467 | EdgesApp = Edges; 1468 | NodesApp = Nodes; 1469 | } 1470 | var currentNodes = nodes.get({returnType:"Object"}); 1471 | var currentEdges = edges.get({returnType:"Object"}); 1472 | nodes.forEach(function(node){ 1473 | edges.forEach(function(edge) 1474 | { 1475 | if (edge.from == node.id || edge.to == node.id) 1476 | { 1477 | edges.remove( 1478 | { 1479 | id: edge.id 1480 | }) 1481 | } 1482 | }); 1483 | nodes.remove( 1484 | { 1485 | id: node.id 1486 | }) 1487 | }) 1488 | 1489 | for (let i = 65; i <= 90; i++) 1490 | { 1491 | labels[String.fromCharCode(i)] = { 1492 | used: false 1493 | }; 1494 | } 1495 | 1496 | Nodes = NodesApp; 1497 | Edges = EdgesApp 1498 | 1499 | 1500 | nodes.update(currentNodes); 1501 | edges.update(currentEdges); 1502 | nodes.forEach(function(node){ 1503 | nodes.remove( 1504 | { 1505 | id: node.id 1506 | }) 1507 | }) 1508 | edges.forEach(function(edge){ 1509 | edges.remove( 1510 | { 1511 | id: edge.id 1512 | }) 1513 | }) 1514 | 1515 | gestioneInputNodi() 1516 | 1517 | } 1518 | function aggiornaNetwork() 1519 | { 1520 | 1521 | if (data.length < 2) 1522 | { 1523 | const modalError = new bootstrap.Modal(document.getElementById("errore")); 1524 | textError = 'Please enter (nodes - edges).json'; 1525 | document.getElementById("textError").innerHTML = textError; 1526 | let button = '' + '' 1527 | document.getElementById("buttonModal").innerHTML = button; 1528 | modalError.show() 1529 | 1530 | } 1531 | else 1532 | { 1533 | draw(); 1534 | let inxNodes = 0 1535 | let inxEdges = 0; 1536 | for (let j = 0; j < data.length; j++) 1537 | { 1538 | for (let i = 0; i < data[j].length; i++) 1539 | { 1540 | if (data[j][i].from !== undefined) inxEdges = j; 1541 | else inxNodes = j; 1542 | break; 1543 | } 1544 | } 1545 | for (let i = 0; i < data[inxEdges].length; i++) 1546 | { 1547 | edges.add(new Edge(data[inxEdges][i].from, data[inxEdges][i].to, data[inxEdges][i].label, data[inxEdges][i].id)) 1548 | if (data[inxEdges][i].arrowFrom == true && data[inxEdges][i].arrowTo == true) 1549 | { 1550 | data[inxEdges][i].arrowTo = false; 1551 | data[inxEdges][i].arrowFrom = false; 1552 | } 1553 | edges.update( 1554 | { 1555 | id: data[inxEdges][i].id, 1556 | arrows: 1557 | { 1558 | to: data[inxEdges][i].arrowTo, 1559 | from: data[inxEdges][i].arrowFrom 1560 | } 1561 | }); 1562 | } 1563 | edges.forEach(function(edge) 1564 | { 1565 | if (idArcoAssociato(edge.id) != null) 1566 | { 1567 | var edge1 = edges.get(edge.id); 1568 | edge1.smooth = true; 1569 | edges.update(edge1); 1570 | var edge2 = edges.get(idArcoAssociato(edge.id)); 1571 | edge2.smooth = true; 1572 | edges.update(edge2); 1573 | } 1574 | }) 1575 | for (let i = 0; i < data[inxNodes].length; i++) 1576 | { 1577 | nodes.add(new Node(data[inxNodes][i].id, data[inxNodes][i].label)); 1578 | } 1579 | gestioneInputNodi() 1580 | } 1581 | } 1582 | let data = []; 1583 | let files; 1584 | 1585 | function handleFiles(event) 1586 | { 1587 | data = [] 1588 | files = Array.from(event.target.files); 1589 | files.forEach(file => 1590 | { 1591 | if (file.name.endsWith('.json')) 1592 | { 1593 | const reader = new FileReader(); 1594 | reader.onload = function(event) 1595 | { 1596 | const fileContent = event.target.result; 1597 | try 1598 | { 1599 | data.push(JSON.parse(fileContent)); 1600 | } 1601 | catch (error) 1602 | { 1603 | console.error("Errore durante il parsing della stringa JSON: ", error); 1604 | } 1605 | } 1606 | reader.readAsText(file); 1607 | } 1608 | else 1609 | { 1610 | console.warn(`Il file ${file.name} non è un file JSON e verrà ignorato.`); 1611 | } 1612 | }); 1613 | } 1614 | 1615 | 1616 | 1617 | const output = document.getElementById("output"); 1618 | let puntoPressione = null; 1619 | let puntoRilascio = null; 1620 | 1621 | 1622 | output.addEventListener("mousedown", function(evento) { 1623 | puntoPressione = { x: evento.clientX, y: evento.clientY }; 1624 | }); 1625 | output.addEventListener("touchstart", function(evento) { 1626 | puntoPressione = { x: evento.touches[0].pageX, y: evento.touches[0].pageY }; 1627 | }); 1628 | 1629 | output.addEventListener("touchmove", function(evento) { 1630 | evento.preventDefault(); 1631 | }); 1632 | 1633 | output.addEventListener("touchend", function(evento) { 1634 | puntoRilascio = { x: evento.changedTouches[0].pageX, y: evento.changedTouches[0].pageY }; 1635 | const distanza = Math.sqrt(Math.pow((puntoRilascio.x - puntoPressione.x), 2) + Math.pow((puntoRilascio.y - puntoPressione.y), 2)); 1636 | 1637 | const sogliaVerticale = 50; 1638 | let newChoice = choice; 1639 | if (distanza >= 150 && percorsi && percorsi > 1 && choice >= 0 && choice < percorsi) { 1640 | if (Math.abs(puntoRilascio.y - puntoPressione.y) < sogliaVerticale) { 1641 | if (puntoRilascio.x > puntoPressione.x) { 1642 | spostamentoDestra = true; 1643 | if (choice == 0) { 1644 | newChoice = percorsi - 1; 1645 | } else { 1646 | newChoice--; 1647 | } 1648 | } else if (puntoRilascio.x < puntoPressione.x) { 1649 | spostamentoDestra = false; 1650 | if (choice == percorsi - 1) { 1651 | newChoice = 0; 1652 | } else { 1653 | newChoice++; 1654 | } 1655 | } 1656 | } 1657 | changeChoice(newChoice) 1658 | 1659 | } 1660 | }); 1661 | 1662 | 1663 | output.addEventListener("mouseup", function(evento) { 1664 | puntoRilascio = { x: evento.clientX, y: evento.clientY }; 1665 | const distanza = Math.sqrt(Math.pow((puntoRilascio.x - puntoPressione.x), 2) + Math.pow((puntoRilascio.y - puntoPressione.y), 2)); 1666 | 1667 | const sogliaVerticale = 50; 1668 | let newChoice = choice; 1669 | if (distanza >= 150 && percorsi > 1) { 1670 | 1671 | if (Math.abs(puntoRilascio.y - puntoPressione.y) < sogliaVerticale) { 1672 | if (puntoRilascio.x > puntoPressione.x) { 1673 | spostamentoDestra = true; 1674 | if(choice == 0)newChoice = percorsi-1; 1675 | else newChoice--; 1676 | 1677 | } else if (puntoRilascio.x < puntoPressione.x) { 1678 | spostamentoDestra = false; 1679 | if(choice == percorsi-1)newChoice = 0; 1680 | else newChoice++; 1681 | } 1682 | } 1683 | 1684 | changeChoice(newChoice) 1685 | 1686 | 1687 | } 1688 | }); 1689 | -------------------------------------------------------------------------------- /preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/preview.gif -------------------------------------------------------------------------------- /socialpreview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vittorioPiotti/DijkstraSolver-Bootstrap-Vis/3068c8d818e511c4fd5f8a29c37bcc7819a7347a/socialpreview.png --------------------------------------------------------------------------------