├── .gitignore ├── LICENSE ├── README.md ├── build.sbt ├── downloads ├── LICENSE.md ├── README.md ├── cite-1.15.0.html ├── citeApp-js │ ├── Control.FullScreen.css │ ├── Control.FullScreen.js │ ├── citeImage.js │ ├── images │ │ ├── 161728.png │ │ ├── button_grouphover.png │ │ ├── button_hover.png │ │ ├── button_pressed.png │ │ ├── button_rest.png │ │ ├── fullpage_grouphover.png │ │ ├── fullpage_hover.png │ │ ├── fullpage_pressed.png │ │ ├── fullpage_rest.png │ │ ├── guidehorizontal_grouphover.png │ │ ├── guidehorizontal_hover.png │ │ ├── guidehorizontal_pressed.png │ │ ├── guidehorizontal_rest.png │ │ ├── guidevertical_grouphover.png │ │ ├── guidevertical_hover.png │ │ ├── guidevertical_pressed.png │ │ ├── guidevertical_rest.png │ │ ├── home_grouphover.png │ │ ├── home_hover.png │ │ ├── home_pressed.png │ │ ├── home_rest.png │ │ ├── icon-fullscreen-2x.png │ │ ├── icon-fullscreen.png │ │ ├── img_254851.png │ │ ├── next_grouphover.png │ │ ├── next_hover.png │ │ ├── next_pressed.png │ │ ├── next_rest.png │ │ ├── previous_grouphover.png │ │ ├── previous_hover.png │ │ ├── previous_pressed.png │ │ ├── previous_rest.png │ │ ├── rotateleft_grouphover.png │ │ ├── rotateleft_hover.png │ │ ├── rotateleft_pressed.png │ │ ├── rotateleft_rest.png │ │ ├── rotateright_grouphover.png │ │ ├── rotateright_hover.png │ │ ├── rotateright_pressed.png │ │ ├── rotateright_rest.png │ │ ├── selection_cancel_grouphover.png │ │ ├── selection_cancel_hover.png │ │ ├── selection_cancel_pressed.png │ │ ├── selection_cancel_rest.png │ │ ├── selection_confirm_grouphover.png │ │ ├── selection_confirm_hover.png │ │ ├── selection_confirm_pressed.png │ │ ├── selection_confirm_rest.png │ │ ├── selection_grouphover.png │ │ ├── selection_hover.png │ │ ├── selection_pressed.png │ │ ├── selection_rest.png │ │ ├── zoomin_grouphover.png │ │ ├── zoomin_hover.png │ │ ├── zoomin_pressed.png │ │ ├── zoomin_rest.png │ │ ├── zoomout_grouphover.png │ │ ├── zoomout_hover.png │ │ ├── zoomout_pressed.png │ │ └── zoomout_rest.png │ ├── marked.min.js │ ├── openseadragon-guides.js │ ├── openseadragon-guides.js.map │ ├── openseadragon.js │ ├── openseadragon.js.map │ ├── openseadragon.min.js │ ├── openseadragon.min.js.map │ └── textExtensions.js └── image_archive │ └── fufolio │ └── papyri │ └── 2018a │ ├── POxy0017n2099a01.dzi │ ├── POxy0017n2099a01.jpg │ └── POxy0017n2099a01_files │ ├── 0 │ └── 0_0.jpeg │ ├── 1 │ └── 0_0.jpeg │ ├── 2 │ └── 0_0.jpeg │ ├── 3 │ └── 0_0.jpeg │ ├── 4 │ └── 0_0.jpeg │ ├── 5 │ └── 0_0.jpeg │ ├── 6 │ └── 0_0.jpeg │ ├── 7 │ └── 0_0.jpeg │ ├── 8 │ └── 0_0.jpeg │ ├── 9 │ ├── 0_0.jpeg │ ├── 0_1.jpeg │ ├── 1_0.jpeg │ └── 1_1.jpeg │ ├── 10 │ ├── 0_0.jpeg │ ├── 0_1.jpeg │ ├── 0_2.jpeg │ ├── 1_0.jpeg │ ├── 1_1.jpeg │ ├── 1_2.jpeg │ ├── 2_0.jpeg │ ├── 2_1.jpeg │ └── 2_2.jpeg │ └── 11 │ ├── 0_0.jpeg │ ├── 0_1.jpeg │ ├── 0_2.jpeg │ ├── 0_3.jpeg │ ├── 0_4.jpeg │ ├── 1_0.jpeg │ ├── 1_1.jpeg │ ├── 1_2.jpeg │ ├── 1_3.jpeg │ ├── 1_4.jpeg │ ├── 2_0.jpeg │ ├── 2_1.jpeg │ ├── 2_2.jpeg │ ├── 2_3.jpeg │ ├── 2_4.jpeg │ ├── 3_0.jpeg │ ├── 3_1.jpeg │ ├── 3_2.jpeg │ ├── 3_3.jpeg │ ├── 3_4.jpeg │ ├── 4_0.jpeg │ ├── 4_1.jpeg │ ├── 4_2.jpeg │ ├── 4_3.jpeg │ └── 4_4.jpeg ├── project ├── build.properties ├── build.sbt └── buildinfo.sbt ├── releases.md ├── scripts ├── InsecureChrome.lnk ├── dz2.sh ├── macOS_insecure_chrome.sh └── make_ptiff_3.sh └── src └── main ├── resources ├── LICENSE.txt ├── application.css ├── cite-TEMPLATE1.html ├── cite-TEMPLATE2.html ├── citeApp-js │ ├── Control.FullScreen.css │ ├── Control.FullScreen.js │ ├── citeImage.js │ ├── images │ │ ├── 161728.png │ │ ├── button_grouphover.png │ │ ├── button_hover.png │ │ ├── button_pressed.png │ │ ├── button_rest.png │ │ ├── fullpage_grouphover.png │ │ ├── fullpage_hover.png │ │ ├── fullpage_pressed.png │ │ ├── fullpage_rest.png │ │ ├── guidehorizontal_grouphover.png │ │ ├── guidehorizontal_hover.png │ │ ├── guidehorizontal_pressed.png │ │ ├── guidehorizontal_rest.png │ │ ├── guidevertical_grouphover.png │ │ ├── guidevertical_hover.png │ │ ├── guidevertical_pressed.png │ │ ├── guidevertical_rest.png │ │ ├── home_grouphover.png │ │ ├── home_hover.png │ │ ├── home_pressed.png │ │ ├── home_rest.png │ │ ├── icon-fullscreen-2x.png │ │ ├── icon-fullscreen.png │ │ ├── img_254851.png │ │ ├── next_grouphover.png │ │ ├── next_hover.png │ │ ├── next_pressed.png │ │ ├── next_rest.png │ │ ├── previous_grouphover.png │ │ ├── previous_hover.png │ │ ├── previous_pressed.png │ │ ├── previous_rest.png │ │ ├── rotateleft_grouphover.png │ │ ├── rotateleft_hover.png │ │ ├── rotateleft_pressed.png │ │ ├── rotateleft_rest.png │ │ ├── rotateright_grouphover.png │ │ ├── rotateright_hover.png │ │ ├── rotateright_pressed.png │ │ ├── rotateright_rest.png │ │ ├── selection_cancel_grouphover.png │ │ ├── selection_cancel_hover.png │ │ ├── selection_cancel_pressed.png │ │ ├── selection_cancel_rest.png │ │ ├── selection_confirm_grouphover.png │ │ ├── selection_confirm_hover.png │ │ ├── selection_confirm_pressed.png │ │ ├── selection_confirm_rest.png │ │ ├── selection_grouphover.png │ │ ├── selection_hover.png │ │ ├── selection_pressed.png │ │ ├── selection_rest.png │ │ ├── zoomin_grouphover.png │ │ ├── zoomin_hover.png │ │ ├── zoomin_pressed.png │ │ ├── zoomin_rest.png │ │ ├── zoomout_grouphover.png │ │ ├── zoomout_hover.png │ │ ├── zoomout_pressed.png │ │ └── zoomout_rest.png │ ├── marked.min.js │ ├── openseadragon-guides.js │ ├── openseadragon-guides.js.map │ ├── openseadragon.js │ ├── openseadragon.js.map │ ├── openseadragon.min.js │ ├── openseadragon.min.js.map │ └── textExtensions.js ├── index-dev.html ├── index-opt.html └── million.cex └── scala └── citeappscalajs ├── CitableImageModel.scala ├── CiteBinaryImageController.scala ├── CiteBinaryImageModel.scala ├── CiteBinaryImageView.scala ├── CiteMain.scala ├── CiteMainController.scala ├── CiteMainModel.scala ├── CiteMainView.scala ├── CommentaryModel.scala ├── DSEModel.scala ├── DataModelController.scala ├── DataModelModel.scala ├── DataModelView.scala ├── ExtendedTextPropertyView.scala ├── ImageRoiModel.scala ├── NGController.scala ├── NGModel.scala ├── NGView.scala ├── O2Controller.scala ├── O2Model.scala ├── O2View.scala ├── ObjectController.scala ├── ObjectModel.scala ├── ObjectView.scala ├── QueryObjectController.scala ├── QueryObjectModel.scala ├── QueryObjectView.scala ├── RelationsController.scala ├── RelationsModel.scala └── RelationsView.scala /.gitignore: -------------------------------------------------------------------------------- 1 | ### SBT template 2 | # Simple Build Tool 3 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control 4 | 5 | target/ 6 | lib_managed/ 7 | src_managed/ 8 | project/boot/ 9 | .history 10 | .cache 11 | local.sbt 12 | 13 | *.DS_Store 14 | 15 | # sbteclipse plugin 16 | .target 17 | 18 | # TeXlipse plugin 19 | .texlipse 20 | ### Vim template 21 | [._]*.s[a-w][a-z] 22 | [._]s[a-w][a-z] 23 | *.un~ 24 | Session.vim 25 | .netrwhist 26 | *~ 27 | ### Scala template 28 | *.class 29 | *.log 30 | 31 | # sbt specific 32 | .cache 33 | .history 34 | .lib/ 35 | dist/* 36 | target/ 37 | lib_managed/ 38 | src_managed/ 39 | project/boot/ 40 | project/plugins/project/ 41 | 42 | 43 | *.iml 44 | 45 | ## Directory-based project format: 46 | .idea/ 47 | # if you remove the above rule, at least ignore the following: 48 | 49 | # User-specific stuff: 50 | # .idea/workspace.xml 51 | # .idea/tasks.xml 52 | # .idea/dictionaries 53 | 54 | # Sensitive or high-churn files: 55 | # .idea/dataSources.ids 56 | # .idea/dataSources.xml 57 | # .idea/sqlDataSources.xml 58 | # .idea/dynamic.xml 59 | # .idea/uiDesigner.xml 60 | 61 | # Gradle: 62 | # .idea/gradle.xml 63 | # .idea/libraries 64 | 65 | # Mongo Explorer plugin: 66 | # .idea/mongoSettings.xml 67 | 68 | ## File-based project format: 69 | *.ipr 70 | *.iws 71 | 72 | ## Plugin-specific files: 73 | 74 | # IntelliJ 75 | /out/ 76 | 77 | # mpeltonen/sbt-idea plugin 78 | .idea_modules/ 79 | 80 | # JIRA plugin 81 | atlassian-ide-plugin.xml 82 | 83 | # Crashlytics plugin (for Android Studio and IntelliJ) 84 | com_crashlytics_export_strings.xml 85 | crashlytics.properties 86 | crashlytics-build.properties 87 | .cache-main 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ![CiteApp 1.16.0](https://img.shields.io/badge/CiteApp-1.16.0-blue.svg) ![Scala 2.12.8](https://img.shields.io/badge/scala-2.12.8-brightgreen.svg) ![ScalaJS 0.6.29](https://img.shields.io/badge/scala%20js-0.6.29-brightgreen.svg) ![xCite 4.2.0](https://img.shields.io/badge/xcite-4.2.0-green.svg) ![OHCO2 10.18.2](https://img.shields.io/badge/ohco2-10.18.2-green.svg) ![SCM 7.2.0](https://img.shields.io/badge/scm-7.2.0-green.svg) ![CiteObj 7.4.0](https://img.shields.io/badge/citeobj-7.4.0-green.svg) ![CiteRelations 2.6.0](https://img.shields.io/badge/citerelations-2.6.0-green.svg) ![CiteBinaryImage 3.1.1](https://img.shields.io/badge/citebinaryimage-3.1.1-green.svg) ![Harvard CHS, Cite Architecture](https://img.shields.io/badge/harvard%20chs-cite--architecture-A51C30.svg) ![Furman Classics](https://img.shields.io/badge/furman-classics-582C83.svg) ![Holy Cross Classics](https://img.shields.io/badge/holy%20cross-classics-602d89.svg) 4 | 5 | # CITE Application 6 | 7 | A single-page browser application for exploring citable resources, written in [Scala.js](http://www.scala-js.org/). 8 | 9 | ## Current version: 1.16.0 10 | 11 | See [release notes](releases.md). 12 | 13 | ## License 14 | 15 | [GPL 3.0](https://opensource.org/licenses/gpl-3.0.html) 16 | 17 | CITE Application, by default, downloads a sample corpus of texts. Licensing and attribution for those texts is available in the [downloads directory](downloads). 18 | 19 | ## Using 20 | 21 | CITE Application is a single web page you can open in a browser. Precompiled versions are available in the [downloads directory](downloads), and named `cite-VERSION.html`. 22 | 23 | **N.b.** In the `downloads` directory there is a `js` directory that CiteApp uses for providing zooming views of binary images, using [OpenSeadragon](https://openseadragon.github.io). 24 | 25 | **Images not working?** You probably need to deal with browser restrictions. See the [Wiki page on this topic](https://github.com/cite-architecture/CITE-App/wiki/Local-File-and-Cross-Domain-Restrictions). 26 | 27 | ## Building 28 | 29 | CITE Application is targetted for Scala 2.12.You can use normal `sbt` using normal tasks for [ScalaJS projects](https://www.scala-js.org/doc/project/building.html) such as `sbt fastOptJS` or `sbt fullOptJS`. 30 | 31 | If `sbt fastOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-dev.html` in your browser. 32 | 33 | If `sbt fullOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-opt.html` in your browser. 34 | 35 | In addition, the project defines a custom `spa` task that builds a single-page application named `cite-VERSION.html` (where `VERSION` is the current version defined in `build.sbt`), in the `downloads` directory. 36 | 37 | If `sbt fastOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-dev.html` in your browser. 38 | 39 | If `sbt fullOptJS` completes successfully, run the app by opening `CITE-App/target/scala-2.12/classes/index-opt.html` in your browser. 40 | 41 | ## Images for CiteApp 42 | 43 | Documentation for configuring collections of images for CiteApp is underway at . 44 | 45 | The `downloads/image_archive` directory contains a one-image sample setup showing how to implement URN-aware DeepZoom images. 46 | 47 | ## Python SimpleServer 48 | 49 | Running CiteApp locally, and attempting to access images, can run afoul of the Cross-Origin-Restrictions (CORS). It may be possible to tell your browser to ignore that security precaution. Or, a safer alternative, is to serve CiteApp locally. If Python is installed, navigate to the directory that contains `cite-VERSION.html`, and execute: 50 | 51 | `python -m SimpleHTTPServer` 52 | 53 | ## Credits 54 | 55 | CITEApplication, © 2017, 2018, 2019: Neel Smith and Christopher Blackwell. Available for use, modification, and distribution under the terms of the [GPL 3.0](https://opensource.org/licenses/gpl-3.0.html) license. Based on the [CITE and CTS protocols](http://cite-architecture.github.io), by Neel Smith and Christopher Blackwell. 56 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | enablePlugins(ScalaJSPlugin, BuildInfoPlugin) 2 | 3 | name := "citeapp" 4 | 5 | version := "1.16.0" 6 | 7 | scalaVersion := "2.12.8" 8 | 9 | resolvers += Resolver.jcenterRepo 10 | resolvers += Resolver.bintrayRepo("neelsmith", "maven") 11 | resolvers += sbt.Resolver.bintrayRepo("denigma", "denigma-releases") 12 | 13 | libraryDependencies ++= Seq( 14 | "org.scala-js" %% "scalajs-stubs" % scalaJSVersion % "provided", 15 | "org.scala-js" %%% "scalajs-dom" % "0.9.7", 16 | "io.monix" %%% "monix" % "2.3.3", 17 | "edu.holycross.shot.cite" %%% "xcite" % "4.2.0", 18 | "edu.holycross.shot" %%% "ohco2" % "10.18.2", 19 | "edu.holycross.shot" %%% "scm" % "7.2.0", 20 | "edu.holycross.shot" %%% "citeobj" % "7.4.0", 21 | "edu.holycross.shot" %%% "citerelations" % "2.6.0", 22 | "edu.holycross.shot" %%% "citebinaryimage" % "3.1.1", 23 | "edu.holycross.shot" %%% "dse" % "7.0.0", 24 | "com.github.karasiq" %%% "scalajs-marked" % "1.0.2", 25 | "com.thoughtworks.binding" %%% "dom" % "11.9.0+3-cadac35f" 26 | ) 27 | 28 | addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full) 29 | 30 | //scalacOptions += "-P:scalajs:suppressExportDeprecations" 31 | //scalacOptions += "-P:scalajs:suppressMissingJSGlobalDeprecations" 32 | scalacOptions += "-unchecked" 33 | scalacOptions += "-deprecation" 34 | 35 | lazy val spa = taskKey[Unit]("Assemble single-page app from html templates and generated CSS and JS output") 36 | 37 | import scala.io.Source 38 | import java.io.PrintWriter 39 | spa := { 40 | 41 | // val defaultLibraryUrl = "https://raw.githubusercontent.com/cite-architecture/citedx/master/libraries/millionplus.cex" 42 | val defaultLibraryUrl = "https://raw.githubusercontent.com/Eumaeus/fuCiteDX/master/CEX_Tutorial/6_DataModel_DSE.cex" 43 | //val defaultLibraryUrl = "https://raw.githubusercontent.com/Eumaeus/fuCiteDX/master/fu-spring2018.cex" 44 | val serverMode = false 45 | val defaultLibraryDelimiter = "#" 46 | val defaultImagePath = "" // Path prefixed to the named directories for local images 47 | 48 | val compileFirst = (fullOptJS in Compile).value 49 | 50 | val junk = "//# sourceMappingURL=citeapp-opt.js.map" 51 | val js = Source.fromFile("target/scala-2.12/citeapp-opt.js").getLines.mkString("\n").replaceAll(junk,"") 52 | 53 | val css = Source.fromFile("target/scala-2.12/classes/application.css").getLines.mkString("\n") 54 | 55 | val template1 = "src/main/resources/cite-TEMPLATE1.html" 56 | val template1Text = Source.fromFile(template1).getLines.mkString("\n").replaceAll("ACTUALVERSION", version.value).replaceAll("ACTUALCSS",css) 57 | 58 | 59 | val urlPlaceholder = "DEFAULTLIBRARYURL" 60 | val delimiterPlaceholder = "DEFAULTLIBRARYDELIMITER" 61 | val imagePathPlaceholder = "DEFAULTIMAGEPATH" 62 | val serverModePlaceholder = "SERVERMODE" 63 | 64 | val template2Text = Source.fromFile("src/main/resources/cite-TEMPLATE2.html").getLines.mkString("\n").replaceAll(urlPlaceholder,defaultLibraryUrl).replaceAll(delimiterPlaceholder,defaultLibraryDelimiter).replaceAll(imagePathPlaceholder,defaultImagePath).replaceAll(serverModePlaceholder,serverMode.toString) 65 | val newFile = "downloads/cite-" + version.value + ".html" 66 | new PrintWriter(newFile) { write(template1Text + js + template2Text); close } 67 | println("Runnable single-page app is in " + newFile) 68 | } 69 | 70 | buildInfoKeys := Seq[BuildInfoKey](name, version, scalaVersion, sbtVersion) 71 | buildInfoPackage := "citeapp" 72 | -------------------------------------------------------------------------------- /downloads/LICENSE.md: -------------------------------------------------------------------------------- 1 | # Licensing on Works 2 | 3 | ## Below is detailed licensing for the works included in the file `million.cex`. 4 | 5 | ## Quran 6 | 7 | The text of the Quran is version 1.0.2 from , distributed under the terms of a Creative Commons Attribution 3.0 License. To quote their terms of use: 8 | 9 | Permission is granted to copy and distribute verbatim copies 10 | of this text, but CHANGING IT IS NOT ALLOWED. 11 | 12 | This copyright notice shall be included in all verbatim copies 13 | of the text, and shall be reproduced appropriately in all files 14 | derived from or containing substantial portion of this text. 15 | 16 | ## Herodotus (English and Greek) 17 | 18 | The texts of Herodotus are from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License. 19 | 20 | ## Hafez 21 | 22 | The poetry of Hafez is from the Open Persian Project of Leipzig University, , Gregory Crane, Saeed Majidi, and Maryam Foradi, edd. Distributed under the terms of a Creative Commons 3.0 Attribution License. 23 | 24 | ## Plutarch (Greek) 25 | 26 | The Greek text of Plutarch is from the edition of Ziegler, published on Archive.org and released into the Public Domain. Preparation of this digital edition was funded by a grant from the Andrew W. Mellon Foundation. 27 | 28 | ## Plutarch (English) 29 | 30 | The English text of Plutarch is from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License. 31 | 32 | ## Latin Texts 33 | 34 | The Latin Texts are from Holy Cross Free Latin and Greek editions, distributed under the terms of the Creative Commons 3 Attribution-Share-Alike License, derived from Tesserae project edition (http://tesserae.caset.buffalo.edu/sources.php) derived from Perseus project edition (http://www.perseus.tufts.edu/hopper/collection?collection=Perseus%3Acollection%3AGreco-Roman) 35 | 36 | ## Licensing on Latin texts from CroALa 37 | 38 | All Latin texts from CroALa, the Croatiae auctores Latini bibliotheca electronica, Neven Jovanović, editor, are reproduced here in derivative versions, according to the terms of the Creative Commons Attribution 4.0 International License 39 | 40 | ## Licensing on Homer Multitext texts 41 | 42 | All texts from the Homer Multitext, Casey Dué and Mary Ebbott, edd., , are redistributed according to the terms of the Creative Commons Attribution, Non-Commercial 4.0 License . 43 | -------------------------------------------------------------------------------- /downloads/README.md: -------------------------------------------------------------------------------- 1 | # CITEApp Download 2 | 3 | This directory includes compiled, optimized versions of the CITEApp, including all necessary CSS and javascript in a single `.html` file. 4 | 5 | ## Running 6 | 7 | - Double-click on `cite-VERSION.html` to open it in a browser. 8 | - If there is an active internet connection, the app will automatically fetch a digital library in `.cex` form. 9 | 10 | ## Running (Offline) 11 | 12 | - Prepare a `.cex` file to load, or get sample `.cex` libraries from [here](https://github.com/Eumaeus/cts-demo-corpus/tree/master/CEX-Files). 13 | - Double-click on `cite-VERSION.html` to open it in a browser. 14 | - Use the `Choose File` button at the to select and open a `.cex` file. 15 | 16 | ## Reference 17 | 18 | This app is based on the [CITE Architecture](http://cite-architecture.github.io), a protocol for identification and retrieval of data via machine-actional canonical citations in URN format. 19 | 20 | CITE/CTS is ©2002–2017 Neel Smith and Christopher Blackwell. This implementation of the CITE data models was written by Neel Smith and Christopher Blackwell using Scala, Scala-JS, and Binding.scala. Licensed under the GPL 3.0. Sourcecode on GitHub. 21 | -------------------------------------------------------------------------------- /downloads/citeApp-js/Control.FullScreen.css: -------------------------------------------------------------------------------- 1 | .fullscreen-icon { background-image: url(images/icon-fullscreen.png); } 2 | .leaflet-retina .fullscreen-icon { background-image: url(images/icon-fullscreen-2x.png); background-size: 26px 26px; } 3 | /* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */ 4 | .leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; } 5 | .leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; } 6 | .leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; } 7 | .leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; } 8 | .leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; } 9 | -------------------------------------------------------------------------------- /downloads/citeApp-js/Control.FullScreen.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | L.Control.FullScreen = L.Control.extend({ 4 | options: { 5 | position: 'topleft', 6 | title: 'Full Screen', 7 | titleCancel: 'Exit Full Screen', 8 | forceSeparateButton: false, 9 | forcePseudoFullscreen: false, 10 | fullscreenElement: false 11 | }, 12 | 13 | onAdd: function (map) { 14 | var className = 'leaflet-control-zoom-fullscreen', container, content = ''; 15 | 16 | if (map.zoomControl && !this.options.forceSeparateButton) { 17 | container = map.zoomControl._container; 18 | } else { 19 | container = L.DomUtil.create('div', 'leaflet-bar'); 20 | } 21 | 22 | if (this.options.content) { 23 | content = this.options.content; 24 | } else { 25 | className += ' fullscreen-icon'; 26 | } 27 | 28 | this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this); 29 | 30 | this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this); 31 | 32 | return container; 33 | }, 34 | 35 | _createButton: function (title, className, content, container, fn, context) { 36 | this.link = L.DomUtil.create('a', className, container); 37 | this.link.href = '#'; 38 | this.link.title = title; 39 | this.link.innerHTML = content; 40 | 41 | L.DomEvent 42 | .addListener(this.link, 'click', L.DomEvent.stopPropagation) 43 | .addListener(this.link, 'click', L.DomEvent.preventDefault) 44 | .addListener(this.link, 'click', fn, context); 45 | 46 | L.DomEvent 47 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation) 48 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault) 49 | .addListener(container, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context); 50 | 51 | L.DomEvent 52 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation) 53 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault) 54 | .addListener(document, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context); 55 | 56 | return this.link; 57 | }, 58 | 59 | toggleFullScreen: function () { 60 | var map = this._map; 61 | map._exitFired = false; 62 | if (map._isFullscreen) { 63 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) { 64 | fullScreenApi.cancelFullScreen(); 65 | } else { 66 | L.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen'); 67 | } 68 | map.fire('exitFullscreen'); 69 | map._exitFired = true; 70 | map._isFullscreen = false; 71 | } 72 | else { 73 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) { 74 | fullScreenApi.requestFullScreen(this.options.fullscreenElement ? this.options.fullscreenElement : map._container); 75 | } else { 76 | L.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen'); 77 | } 78 | map.fire('enterFullscreen'); 79 | map._isFullscreen = true; 80 | } 81 | }, 82 | 83 | _toggleTitle: function () { 84 | this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel; 85 | }, 86 | 87 | _handleFullscreenChange: function () { 88 | var map = this._map; 89 | map.invalidateSize(); 90 | if (!fullScreenApi.isFullScreen() && !map._exitFired) { 91 | map.fire('exitFullscreen'); 92 | map._exitFired = true; 93 | map._isFullscreen = false; 94 | } 95 | } 96 | }); 97 | 98 | L.Map.addInitHook(function () { 99 | if (this.options.fullscreenControl) { 100 | this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions); 101 | this.addControl(this.fullscreenControl); 102 | } 103 | }); 104 | 105 | L.control.fullscreen = function (options) { 106 | return new L.Control.FullScreen(options); 107 | }; 108 | 109 | /* 110 | Native FullScreen JavaScript API 111 | ------------- 112 | Assumes Mozilla naming conventions instead of W3C for now 113 | 114 | source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/ 115 | 116 | */ 117 | 118 | var 119 | fullScreenApi = { 120 | supportsFullScreen: false, 121 | isFullScreen: function () { return false; }, 122 | requestFullScreen: function () {}, 123 | cancelFullScreen: function () {}, 124 | fullScreenEventName: '', 125 | prefix: '' 126 | }, 127 | browserPrefixes = 'webkit moz o ms khtml'.split(' '); 128 | 129 | // check for native support 130 | if (typeof document.exitFullscreen !== 'undefined') { 131 | fullScreenApi.supportsFullScreen = true; 132 | } else { 133 | // check for fullscreen support by vendor prefix 134 | for (var i = 0, il = browserPrefixes.length; i < il; i++) { 135 | fullScreenApi.prefix = browserPrefixes[i]; 136 | if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') { 137 | fullScreenApi.supportsFullScreen = true; 138 | break; 139 | } 140 | } 141 | if (typeof document['msExitFullscreen'] !== 'undefined') { 142 | fullScreenApi.prefix = 'ms'; 143 | fullScreenApi.supportsFullScreen = true; 144 | } 145 | } 146 | 147 | // update methods to do something useful 148 | if (fullScreenApi.supportsFullScreen) { 149 | if (fullScreenApi.prefix === 'ms') { 150 | fullScreenApi.fullScreenEventName = 'MSFullscreenChange'; 151 | } else { 152 | fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 153 | } 154 | fullScreenApi.isFullScreen = function () { 155 | switch (this.prefix) { 156 | case '': 157 | return document.fullscreen; 158 | case 'webkit': 159 | return document.webkitIsFullScreen; 160 | case 'ms': 161 | return document.msFullscreenElement; 162 | default: 163 | return document[this.prefix + 'FullScreen']; 164 | } 165 | }; 166 | fullScreenApi.requestFullScreen = function (el) { 167 | switch (this.prefix) { 168 | case '': 169 | return el.requestFullscreen(); 170 | case 'ms': 171 | return el.msRequestFullscreen(); 172 | default: 173 | return el[this.prefix + 'RequestFullScreen'](); 174 | } 175 | }; 176 | fullScreenApi.cancelFullScreen = function () { 177 | switch (this.prefix) { 178 | case '': 179 | return document.exitFullscreen(); 180 | case 'ms': 181 | return document.msExitFullscreen(); 182 | default: 183 | return document[this.prefix + 'CancelFullScreen'](); 184 | } 185 | }; 186 | } 187 | 188 | // jQuery plugin 189 | if (typeof jQuery !== 'undefined') { 190 | jQuery.fn.requestFullScreen = function () { 191 | return this.each(function () { 192 | var el = jQuery(this); 193 | if (fullScreenApi.supportsFullScreen) { 194 | fullScreenApi.requestFullScreen(el); 195 | } 196 | }); 197 | }; 198 | } 199 | 200 | // export api 201 | window.fullScreenApi = fullScreenApi; 202 | })(); 203 | -------------------------------------------------------------------------------- /downloads/citeApp-js/citeImage.js: -------------------------------------------------------------------------------- 1 | // Variables to hold the current image URN and an array of ROIs 2 | 3 | 4 | var viewer = null 5 | var roiArray =[] 6 | 7 | /* 8 | classes: 9 | 10 | image_mappedUrn 11 | image_mappedROI 12 | image_roiGroup_1 13 | image_roi_selected 14 | 15 | */ 16 | 17 | /* 18 | function imageInNewWindow(c) { 19 | console.log("Got here… opening " ) 20 | var w = c.width; 21 | console.log(w); 22 | var h = c.height; 23 | console.log(h); 24 | var u = c.toDataURL(); 25 | window.open(u, "Image", "width=200, height=200"); 26 | } 27 | */ 28 | 29 | function idForMappedUrn(i) { 30 | var s = "image_mappedUrn_" + (i) 31 | return s 32 | } 33 | 34 | function idForMappedROI(i) { 35 | var s = "image_mappedROI_" + (i) 36 | return s 37 | } 38 | 39 | function roiToUrnId(id) { 40 | var s = id.replace("image_mappedROI_","image_mappedUrn_") 41 | return s 42 | } 43 | 44 | 45 | function clearJsRoiArray(r) { 46 | roiArray = [] 47 | } 48 | 49 | function addToJsRoiArray(i,r,u,g){ 50 | tempMap = {index: i, roi: r, mappedUrn: u, group: g} 51 | roiArray.push(tempMap) 52 | } 53 | 54 | function clearSelectedROIs(){ 55 | for (n = 0; n < (roiArray.length - 1); n++){ 56 | var roiId = idForMappedROI(n+1) 57 | var urnId = idForMappedUrn(n+1) 58 | var thisROI = document.getElementById(roiId) 59 | var thisURN = document.getElementById(urnId) 60 | thisROI.classList.remove("image_roi_selected") 61 | thisURN.classList.remove("image_roi_selected") 62 | } 63 | } 64 | 65 | function updateImageJS(collection, imageObject, path ){ 66 | //var collDirectory = collection.replace(new RegExp(':', 'g'), '_'); 67 | //var imagePath = "../../../image_archive/" + collDirectory + "/" + imageObject + ".dzi" 68 | initOpenSeadragon(path) 69 | } 70 | 71 | /** 72 | * Normalizes the index of the ROI to a number within the given amount of 73 | * colors. E.g. If there were only two colors, an index of 4 would return group 74 | * number 0 => (index % colorLength) 75 | * @param {int} i index number 76 | * @return {int} normalized group number 77 | */ 78 | function getGroup(i){ 79 | var colorArray = ["#f23568", "#6d38ff", "#38ffd7", "#fff238", "#661641", "#275fb3", "#24a669", "#a67b24", "#ff38a2", "#194973", "#35f268", "#7f441c", "#801c79", "#2a8ebf", "#216616", "#d97330", "#da32e6", "#196d73", "#bdff38", "#bf3e2a", "#3d1973", "#30cdd9", "#858c1f", "#661616" ]; 80 | var limit = colorArray.length 81 | var rv = i % limit; 82 | return rv; 83 | } 84 | 85 | function initOpenSeadragon(imagePath) { 86 | //console.log(imagePath) 87 | 88 | if (viewer != null){ 89 | viewer.destroy(); 90 | viewer = null 91 | } 92 | 93 | viewer = OpenSeadragon({ 94 | id: 'image_zoomContainer', 95 | prefixUrl: 'citeApp-js/images/', 96 | crossOriginPolicy: "Anonymous", 97 | ajaxWithCredentials: false, 98 | defaultZoomLevel: 1, 99 | tileSources: imagePath, 100 | //tileSources: 'http://www.homermultitext.org/iipsrv?DeepZoom=/project/homer/pyramidal/deepzoom/hmt/vaimg/2017a/VA024RN_0025.tif.dzi', 101 | minZoomImageRatio: 0.25, // of viewer size 102 | immediateRender: true 103 | }); 104 | 105 | viewer.guides({ 106 | allowRotation: false, // Make it possible to rotate the guidelines (by double clicking them) 107 | horizontalGuideButton: null, // Element for horizontal guideline button 108 | verticalGuideButton: null, // Element for vertical guideline button 109 | prefixUrl: "citeApp-js/images/", // Images folder 110 | removeOnClose: false, // Remove guidelines when viewer closes 111 | useSessionStorage: false, // Save guidelines in sessionStorage 112 | navImages: { 113 | guideHorizontal: { 114 | REST: 'guidehorizontal_rest.png', 115 | GROUP: 'guidehorizontal_grouphover.png', 116 | HOVER: 'guidehorizontal_hover.png', 117 | DOWN: 'guidehorizontal_pressed.png' 118 | }, 119 | guideVertical: { 120 | REST: 'guidevertical_rest.png', 121 | GROUP: 'guidevertical_grouphover.png', 122 | HOVER: 'guidevertical_hover.png', 123 | DOWN: 'guidevertical_pressed.png' 124 | } 125 | } 126 | }); 127 | 128 | 129 | // Add overlays 130 | setTimeout(function(){ 131 | if (viewer.world.getItemAt(0)){ 132 | //console.log("defined"); 133 | } else { 134 | //console.log("undefined"); 135 | } 136 | var baseTimer = 0; 137 | while( !(viewer.world.getItemAt(0))){ 138 | baseTimer = baseTimer + 1; 139 | } 140 | //console.log(baseTimer); 141 | var normH = viewer.world.getItemAt(0).getBounds().height; 142 | var normW = viewer.world.getItemAt(0).getBounds().width; 143 | if (roiArray.length > 0){ 144 | for (ol = 0; ol < roiArray.length; ol++){ 145 | var roi = roiArray[ol].roi 146 | var rl = +roi.split(",")[0] 147 | var rt = +roi.split(",")[1] 148 | var rw = +roi.split(",")[2] 149 | var rh = +roi.split(",")[3] 150 | var tl = rl * normW 151 | var tt = rt * normH 152 | var tw = rw * normW 153 | var th = rh * normH 154 | var osdRect = new OpenSeadragon.Rect(tl,tt,tw,th) 155 | var elt = document.createElement("a") 156 | elt.id = idForMappedROI(roiArray[ol].index) 157 | elt.className = "image_mappedROI" + " image_roiGroup_" + roiArray[ol].group + " " + idForMappedUrn(roiArray[ol].index) 158 | elt.dataset.urn = roiArray[ol].mappedUrn 159 | 160 | viewer.addOverlay(elt,osdRect) 161 | } 162 | } 163 | 164 | // Go through and attach events to each overlay 165 | for (n = 0; n < roiArray.length; n++){ 166 | var captureN = n // because N keeps moving 167 | var thisId = idForMappedROI(roiArray[n].index) 168 | var thisElement = document.getElementById(thisId) 169 | thisElement.addEventListener("click", function(e) { 170 | clearSelectedROIs() 171 | var roiId = e.target.id 172 | var targetId = roiToUrnId(roiId) 173 | var targetSpan = document.getElementById(targetId) 174 | targetSpan.classList.add("image_roi_selected") 175 | e.target.classList.add("image_roi_selected") 176 | }, false); 177 | } 178 | },6000); 179 | 180 | } 181 | -------------------------------------------------------------------------------- /downloads/citeApp-js/images/161728.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/161728.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/button_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/button_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/button_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/button_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/button_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/fullpage_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/fullpage_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/fullpage_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/fullpage_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/fullpage_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidehorizontal_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidehorizontal_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidehorizontal_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidehorizontal_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidehorizontal_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidevertical_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidevertical_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidevertical_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/guidevertical_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/guidevertical_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/home_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/home_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/home_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/home_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/home_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/icon-fullscreen-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/icon-fullscreen-2x.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/icon-fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/icon-fullscreen.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/img_254851.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/img_254851.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/next_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/next_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/next_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/next_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/previous_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/previous_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/previous_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/previous_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateleft_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateleft_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateleft_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateleft_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateleft_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateright_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateright_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateright_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/rotateright_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/rotateright_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_cancel_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_cancel_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_cancel_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_cancel_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_cancel_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_confirm_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_confirm_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_confirm_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_confirm_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_confirm_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/selection_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/selection_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomin_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomin_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomin_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomin_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomin_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomout_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_grouphover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomout_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_hover.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomout_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_pressed.png -------------------------------------------------------------------------------- /downloads/citeApp-js/images/zoomout_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/citeApp-js/images/zoomout_rest.png -------------------------------------------------------------------------------- /downloads/citeApp-js/openseadragon-guides.js: -------------------------------------------------------------------------------- 1 | !function(e){function t(n){if(i[n])return i[n].exports;var s=i[n]={i:n,l:!1,exports:{}};return e[n].call(s.exports,s,s.exports,t),s.l=!0,s.exports}var i={};return t.m=e,t.c=i,t.i=function(e){return e},t.d=function(e,t,i){Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},t.n=function(e){var i=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(i,"a",i),i},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="/dist/",t(t.s=3)}([function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.$=OpenSeadragon,t.DIRECTION_HORIZONTAL=Symbol("horizontal"),t.DIRECTION_VERTICAL=Symbol("vertical")},function(e,t,i){"use strict";function n(e,t,i,n,s){var d=n===a.DIRECTION_HORIZONTAL?"horizontal":"vertical",l=o(),u=l.find(function(t){return t.id===e});u?(u.x=t,u.y=i,u.rotation=s):l.push({id:e,x:t,y:i,direction:d,rotation:s}),r(l)}function s(e){var t=o();r(t.filter(function(t){return t.id!==e}))}function o(){var e=window.sessionStorage.getItem(l);return e?JSON.parse(e):[]}function r(e){window.sessionStorage.setItem(l,JSON.stringify(e))}Object.defineProperty(t,"__esModule",{value:!0});var a=i(0),d=!1,l="openseadragon-guides";t.default={addGuide:n,deleteGuide:s,getGuides:o,useStorage:d}},function(e,t,i){"use strict";function n(e){return e&&e.__esModule?e:{default:e}}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){var i=document.createElement("div");switch(i.id="osd-guide-"+t,i.classList.add("osd-guide"),e){case d.DIRECTION_HORIZONTAL:i.classList.add("osd-guide-horizontal");break;case d.DIRECTION_VERTICAL:i.classList.add("osd-guide-vertical");break;default:throw new Error("Invalid guide direction")}return i}function r(){var e=document.createElement("div");return e.classList.add("osd-guide-line"),e}Object.defineProperty(t,"__esModule",{value:!0}),t.Guide=void 0;var a=function(){function e(e,t){for(var i=0;i","").replace("

","") 6 | document.getElementById(elementId).innerHTML = parsedMarkdown; 7 | },1000); 8 | } 9 | 10 | function initiateLeafletWithLatLong(lat, long, elementId) { 11 | setTimeout(function(){ 12 | var latitude = parseFloat(lat); 13 | var longitude = parseFloat(long); 14 | var mymap = L.map(elementId).setView([latitude, longitude], 13); 15 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { 16 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', 17 | maxZoom: 18, 18 | id: 'mapbox.satellite', 19 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ' 20 | }).addTo(mymap); 21 | var marker = L.marker([latitude, longitude]).addTo(mymap); 22 | },1000); 23 | } 24 | 25 | function initiateLeafletWithGeoJson(geojson, elementId) { 26 | setTimeout(function(){ 27 | var myFeature = JSON.parse(geojson); 28 | var mymap = L.map(elementId).setView([0, 0], 20); 29 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { 30 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', 31 | maxZoom: 18, 32 | id: 'mapbox.satellite', 33 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ' 34 | }).addTo(mymap); 35 | var gjFeature = L.geoJSON(myFeature) 36 | gjFeature.addTo(mymap); 37 | mymap.fitBounds(gjFeature.getBounds()); 38 | mymap.zoomOut(3); 39 | 40 | // create a fullscreen button and add it to the map 41 | L.control.fullscreen({ 42 | position: 'topleft', // change the position of the button can be topleft, topright, bottomright or bottomleft, defaut topleft 43 | title: 'Show me the fullscreen !', // change the title of the button, default Full Screen 44 | titleCancel: 'Exit fullscreen mode', // change the title of the button when fullscreen is on, default Exit Full Screen 45 | content: null, // change the content of the button, can be HTML, default null 46 | forceSeparateButton: true, // force seperate button to detach from zoom buttons, default false 47 | forcePseudoFullscreen: true, // force use of pseudo full screen even if full screen API is available, default false 48 | fullscreenElement: false // Dom element to render in full screen, false by default, fallback to map._container 49 | }).addTo(mymap); 50 | 51 | // events are fired when entering or exiting fullscreen. 52 | mymap.on('enterFullscreen', function(){ 53 | console.log('entered fullscreen'); 54 | }); 55 | 56 | mymap.on('exitFullscreen', function(){ 57 | console.log('exited fullscreen'); 58 | }); 59 | 60 | },1000); 61 | 62 | 63 | } 64 | 65 | // mapbox token pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.dzi: -------------------------------------------------------------------------------- 1 | 2 | 7 | 11 | 12 | -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01.jpg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/0/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/0/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/1/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/1/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/0_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/1_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/10/2_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_3.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/0_4.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_3.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/1_4.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_3.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/2_4.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_3.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/3_4.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_2.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_2.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_3.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_3.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_4.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/11/4_4.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/2/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/2/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/3/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/3/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/4/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/4/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/5/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/5/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/6/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/6/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/7/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/7/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/8/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/8/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/0_1.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_0.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_0.jpeg -------------------------------------------------------------------------------- /downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/downloads/image_archive/fufolio/papyri/2018a/POxy0017n2099a01_files/9/1_1.jpeg -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.2 2 | -------------------------------------------------------------------------------- /project/build.sbt: -------------------------------------------------------------------------------- 1 | //addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.15") 2 | //addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.20") 3 | addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.29") 4 | //addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.4.0") 5 | -------------------------------------------------------------------------------- /project/buildinfo.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.7.0") -------------------------------------------------------------------------------- /releases.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | **1.16.0**: Handling of the Commentary Data Model will no longer try to be clever. It will literally use the CiteRelations present in the data, and only those. 4 | 5 | **1.15.0**: Updated DSE Library dependency, and re-wrote code to take advantage of it. 6 | 7 | **1.14.0**: Implemented Leaflet functionality, for geo-spatial data, and Marked.js, for markdown string properties. Now using discoverable data models for extended string property types. 8 | 9 | **1.13.3**: Using OHCO2 10.12.3, for improved performance. 10 | 11 | **1.13.2**: Updated CITE libraries. 12 | 13 | **1.13.1**: Improved handling of commenting for notional URNs. 14 | 15 | **1.13.0**: Implementing ExtendedStringPropertyTypes: markdown, geojson, Pleiades-URI, lat/long, tei-xml. 16 | 17 | **1.12.0**: Commentaries now point two ways, and are more clearly identified. 18 | 19 | **1.11.0**: Implemented Alt-click on Text and Object links to open a new instance of the browser, with the selected URN displayed. 20 | 21 | **1.10.0**: Adding link to look up any object, or Cite2Urn propert-value in Relations. 22 | 23 | **1.9.8**: Accurately reporting the presence of a given text in the repository. 24 | 25 | **1.9.7**: Sped up text retrieval when there are thousands of commentary relations. 26 | 27 | **1.9.6**: Replaced indicator for DSE records attached to a text passage. 28 | 29 | **1.9.5**: Fixed bug in NGram URN reporting; sped it up. 30 | 31 | **1.9.4**: Added "server mode" option, which removes the "local/remote" switch for images (using only "remote"). 32 | 33 | **1.9.3**: Resolved all deprecation warnings from Binding.scala; improved display of text-nodes. 34 | 35 | **1.9.2**: Search history menu for relations tab. 36 | 37 | **1.9.1**: Using CiteRelations 2.0.4. 38 | 39 | **1.9.0**: Relations tab. 40 | 41 | **1.8.1**: Replace list of cited works with dropdown menu, for O2 view and NGram view. 42 | 43 | **1.8.0**: Implemented CiteRelations and the Commentary Datamodel for texts. 44 | 45 | **1.7.3**: Using scala-js-dom 0.9.5. 46 | 47 | **1.7.2**: Fixed a terrible bug where exemplar text nodes would show out of order. 48 | Accepting CtsUrn or Cite2Urn request-parameters for auto-loading (and sharing views). 49 | 50 | **1.7.1**: Even more rigorous checking for `Option[T]` throughout. Fixed a loophole where bad Cite2Urn values cased a `.get` operation on a `None` value when doing DSE records. Improved CSS for object views. 51 | 52 | **1.7.0**: Rebuilt text-display code following more sound binding principles, giving more flexibility to expand text presentation with datamodels. Better integration of text-view with DSE models. More rigorous checking for `Option[T]` throughout. 53 | 54 | **1.6.1**: Update OHCO2 library to 10.7.0, xCite library to 3.3.0; links to rull-rez image-downloads when viewing remote images. 55 | 56 | **1.6.0**: Fully implemented CiteBinaryImageModel and DSEModel. 57 | 58 | **1.5.4**: Added DSE Mappings to Text View. Fixed Issue #128: . 59 | 60 | **1.5.3**: Fixed Issue #133: . 61 | 62 | **1.5.2**: Fixed Issue #131: . 63 | 64 | **1.5.1**: Fixed Issue #132: . 65 | 66 | **1.5.0**: Implemented the DSE datamodel for data mapped to images. 67 | 68 | **1.4.4**: Increased selection menu for NGram size up to 15. Now showing property labels (not property URNs) in object-view. 69 | 70 | **1.4.3**: Added a working history menu for object browsing and querying. 71 | 72 | **1.4.2**: Significant refactoring of text display. Improved display of citations for Exemplars. 73 | 74 | **1.4.1**: Fixed bug where collection-level URNs in object property values would cause browsing to fail silently. 75 | 76 | **1.4.0**: Added Objects Tab for viewing and querying CITE Collections. Added Images tab, taking advantage of the `CiteBinaryImage` datamodel in CEX, to show binary image data. 77 | 78 | **1.3.10**: Updated dependencies. 79 | 80 | **1.3.9**: Fixed bug that prevented previous-search menu from activating on the "Explore Texts" tab. 81 | 82 | **1.3.8**: Improved UI for NGram threshold. Fixed bug where NGram URNs would get returned for every exemplar of an edition, and they should not have been. 83 | 84 | **1.3.7**: Improved UI for Exploring. Using OHCO2 Library 10.4.2, which fixes bugs in labelling works in Catalogs, and in delivering first-node URNs for corpora. 85 | 86 | **1.3.6**: Fixed bug that prevented NGrams from showing up. Also fixed a bug where URNs for NGrams were not being labelled correctly. 87 | 88 | **1.3.5**: Fixed bug that caused erroneous information in the "Works in this Corpus" sidebar. Added sorting of works in listing so all versions and exemplars are together (as opposed to appearing in whatever order their `#!ctsdata` appears in the CEX). 89 | 90 | **1.3.4**: Fixed bug that prevented searching for strings in a single work as opposed to the whole corpus. 91 | 92 | **1.3.3**: Moved a few blocking UI actions to use `Future[T]` to improve perceived responsiveness. 93 | 94 | **1.3.2**: Using updated version of the `ohco2` and `scm` libraries. Improvements to prev and next, and to NGram searching. 95 | 96 | **1.3.1**: Using updated version of the `ohco2` and `scm` libraries. Adjustments to take advantage of citation- and corpus-algebra. 97 | 98 | **1.3.0**: Using updated version of `.cex`. Added support for CITE Collections and Image Extensions. 99 | 100 | - Collections, Images, and Texts are integrated. 101 | - Refactoring toward a future microservice-based app. 102 | - Querying on CITE Properties with the latest version of the `citeobj` library. 103 | 104 | **1.2.1**: Improved import of `.cex` files, using the Scala SCM library and enforcing validity. Numerous bug-fixes in searching texts, finding ngrams, and displaying results. New functionality: 105 | 106 | - A UI way to see multiple versions of a passage of text. 107 | - New, more sensible navigation when viewing multiple versions of a text. 108 | - Links to online help 109 | - A left-to-right text that quotes a right-to-left language will display as generally expected. 110 | 111 | **1.1.0**: Import of repositories in `.cex` format, combining text-data and catalog-data. New functionality: 112 | 113 | - String- and Token-searching 114 | - Search history 115 | - Improved UI 116 | - Various internal refactorings and improvements 117 | 118 | **1.0**: initial release. Import of corpora in 2-column, `.tsv` format. Text browsing and querying for NGrams. 119 | -------------------------------------------------------------------------------- /scripts/InsecureChrome.lnk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/scripts/InsecureChrome.lnk -------------------------------------------------------------------------------- /scripts/dz2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "Making Deep Zoom Files." 3 | echo "Usage:" 4 | echo "1. Navigate to a directory of images." 5 | echo "2. 'mkdir ../new_image_archive'" 6 | echo "3. './dz2.sh *.jpg'" 7 | PYRAMID_DIR=../new_image_archive/ 8 | SRC_EXTENSION=jpg 9 | # Script doing the work: 10 | VIPS=`which vips` 11 | MV=`which mv` 12 | for f in $* 13 | do 14 | echo "------------------" 15 | baseName=$(echo $f | sed -e "s/.$SRC_EXTENSION//") 16 | newF=${PYRAMID_DIR}/${baseName} 17 | echo "copying " $f " to " $PYRAMID_DIR " ..." 18 | cp $f $PYRAMID_DIR 19 | echo "converting " $f " to " $newF " ..." 20 | echo 21 | $VIPS dzsave $f $newF 22 | done; 23 | -------------------------------------------------------------------------------- /scripts/macOS_insecure_chrome.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | open -a Google\ Chrome --args --disable-web-security --user-data-dir="" 4 | -------------------------------------------------------------------------------- /scripts/make_ptiff_3.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo "works" 3 | PYRAMID_DIR=../tiff 4 | 5 | # 6 | # SRC_EXTENSION is the dot-extension on the SOURCE files: if you're 7 | # converting .tif files, change this value to "tif" for example 8 | SRC_EXTENSION=jpg 9 | 10 | echo $PYRAMID_DIR 11 | 12 | # Script doing the work: 13 | VIPS=`which vips` 14 | echo $VIPS 15 | MV=`which mv` 16 | echo $MV 17 | for f in $* 18 | do 19 | echo "------------------" 20 | baseName=$(echo $f | sed -e "s/.$SRC_EXTENSION//") 21 | newF=${PYRAMID_DIR}/${baseName} 22 | echo "converting " $f " to " $newF " ..." 23 | echo 24 | $VIPS dzsave $f $newF 25 | done; 26 | 27 | -------------------------------------------------------------------------------- /src/main/resources/LICENSE.txt: -------------------------------------------------------------------------------- 1 | # Licensing on Works 2 | 3 | Below is detailed licensing for the works included in the file `million.cex`. 4 | 5 | ## Quran 6 | 7 | The text of the Quran is version 1.0.2 from , distributed under the terms of a Creative Commons Attribution 3.0 License. 8 | To quote their terms of use: 9 | 10 | Permission is granted to copy and distribute verbatim copies 11 | of this text, but CHANGING IT IS NOT ALLOWED. 12 | 13 | This copyright notice shall be included in all verbatim copies 14 | of the text, and shall be reproduced appropriately in all files 15 | derived from or containing substantial portion of this text. 16 | 17 | ## Herodotus (English and Greek) 18 | 19 | The texts of Herodotus are from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License. 20 | 21 | ## Hafez 22 | 23 | The poetry of Hafez is from the Open Persian Project of Leipzig University, , Gregory Crane, Saeed Majidi, and Maryam Foradi, edd. Distributed under the terms of a Creative Commons 3.0 Attribution License. 24 | 25 | ## Plutarch (Greek) 26 | 27 | The Greek text of Plutarch is from the edition of Ziegler, published on Archive.org and released into the Public Domain. Preparation of this digital edition was funded by a grant from the Andrew W. Mellon Foundation. 28 | 29 | ## Plutarch (English) 30 | 31 | The English text of Plutarch is from the Perseus Digital Library, , distributed under the terms of a Creative Commons Attribution 3.0 License. 32 | 33 | ## Latin Texts 34 | 35 | The Latin Texts are from Holy Cross Free Latin and Greek editions, distributed under the terms of the Creative Commons 3 Attribution-Share-Alike License, derived from Tesserae project edition (http://tesserae.caset.buffalo.edu/sources.php) derived from Perseus project edition (http://www.perseus.tufts.edu/hopper/collection?collection=Perseus%3Acollection%3AGreco-Roman) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/resources/cite-TEMPLATE1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cite Environment: version ACTUALVERSION 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 21 | 22 | 3 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/Control.FullScreen.css: -------------------------------------------------------------------------------- 1 | .fullscreen-icon { background-image: url(images/icon-fullscreen.png); } 2 | .leaflet-retina .fullscreen-icon { background-image: url(images/icon-fullscreen-2x.png); background-size: 26px 26px; } 3 | /* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */ 4 | .leaflet-container:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; } 5 | .leaflet-container:-ms-fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; } 6 | .leaflet-container:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; } 7 | .leaflet-container:fullscreen { width: 100% !important; height: 100% !important; z-index: 99999; } 8 | .leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; } 9 | -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/Control.FullScreen.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | L.Control.FullScreen = L.Control.extend({ 4 | options: { 5 | position: 'topleft', 6 | title: 'Full Screen', 7 | titleCancel: 'Exit Full Screen', 8 | forceSeparateButton: false, 9 | forcePseudoFullscreen: false, 10 | fullscreenElement: false 11 | }, 12 | 13 | onAdd: function (map) { 14 | var className = 'leaflet-control-zoom-fullscreen', container, content = ''; 15 | 16 | if (map.zoomControl && !this.options.forceSeparateButton) { 17 | container = map.zoomControl._container; 18 | } else { 19 | container = L.DomUtil.create('div', 'leaflet-bar'); 20 | } 21 | 22 | if (this.options.content) { 23 | content = this.options.content; 24 | } else { 25 | className += ' fullscreen-icon'; 26 | } 27 | 28 | this._createButton(this.options.title, className, content, container, this.toggleFullScreen, this); 29 | 30 | this._map.on('enterFullscreen exitFullscreen', this._toggleTitle, this); 31 | 32 | return container; 33 | }, 34 | 35 | _createButton: function (title, className, content, container, fn, context) { 36 | this.link = L.DomUtil.create('a', className, container); 37 | this.link.href = '#'; 38 | this.link.title = title; 39 | this.link.innerHTML = content; 40 | 41 | L.DomEvent 42 | .addListener(this.link, 'click', L.DomEvent.stopPropagation) 43 | .addListener(this.link, 'click', L.DomEvent.preventDefault) 44 | .addListener(this.link, 'click', fn, context); 45 | 46 | L.DomEvent 47 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation) 48 | .addListener(container, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault) 49 | .addListener(container, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context); 50 | 51 | L.DomEvent 52 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.stopPropagation) 53 | .addListener(document, fullScreenApi.fullScreenEventName, L.DomEvent.preventDefault) 54 | .addListener(document, fullScreenApi.fullScreenEventName, this._handleFullscreenChange, context); 55 | 56 | return this.link; 57 | }, 58 | 59 | toggleFullScreen: function () { 60 | var map = this._map; 61 | map._exitFired = false; 62 | if (map._isFullscreen) { 63 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) { 64 | fullScreenApi.cancelFullScreen(); 65 | } else { 66 | L.DomUtil.removeClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen'); 67 | } 68 | map.fire('exitFullscreen'); 69 | map._exitFired = true; 70 | map._isFullscreen = false; 71 | } 72 | else { 73 | if (fullScreenApi.supportsFullScreen && !this.options.forcePseudoFullscreen) { 74 | fullScreenApi.requestFullScreen(this.options.fullscreenElement ? this.options.fullscreenElement : map._container); 75 | } else { 76 | L.DomUtil.addClass(this.options.fullscreenElement ? this.options.fullscreenElement : map._container, 'leaflet-pseudo-fullscreen'); 77 | } 78 | map.fire('enterFullscreen'); 79 | map._isFullscreen = true; 80 | } 81 | }, 82 | 83 | _toggleTitle: function () { 84 | this.link.title = this._map._isFullscreen ? this.options.title : this.options.titleCancel; 85 | }, 86 | 87 | _handleFullscreenChange: function () { 88 | var map = this._map; 89 | map.invalidateSize(); 90 | if (!fullScreenApi.isFullScreen() && !map._exitFired) { 91 | map.fire('exitFullscreen'); 92 | map._exitFired = true; 93 | map._isFullscreen = false; 94 | } 95 | } 96 | }); 97 | 98 | L.Map.addInitHook(function () { 99 | if (this.options.fullscreenControl) { 100 | this.fullscreenControl = L.control.fullscreen(this.options.fullscreenControlOptions); 101 | this.addControl(this.fullscreenControl); 102 | } 103 | }); 104 | 105 | L.control.fullscreen = function (options) { 106 | return new L.Control.FullScreen(options); 107 | }; 108 | 109 | /* 110 | Native FullScreen JavaScript API 111 | ------------- 112 | Assumes Mozilla naming conventions instead of W3C for now 113 | 114 | source : http://johndyer.name/native-fullscreen-javascript-api-plus-jquery-plugin/ 115 | 116 | */ 117 | 118 | var 119 | fullScreenApi = { 120 | supportsFullScreen: false, 121 | isFullScreen: function () { return false; }, 122 | requestFullScreen: function () {}, 123 | cancelFullScreen: function () {}, 124 | fullScreenEventName: '', 125 | prefix: '' 126 | }, 127 | browserPrefixes = 'webkit moz o ms khtml'.split(' '); 128 | 129 | // check for native support 130 | if (typeof document.exitFullscreen !== 'undefined') { 131 | fullScreenApi.supportsFullScreen = true; 132 | } else { 133 | // check for fullscreen support by vendor prefix 134 | for (var i = 0, il = browserPrefixes.length; i < il; i++) { 135 | fullScreenApi.prefix = browserPrefixes[i]; 136 | if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] !== 'undefined') { 137 | fullScreenApi.supportsFullScreen = true; 138 | break; 139 | } 140 | } 141 | if (typeof document['msExitFullscreen'] !== 'undefined') { 142 | fullScreenApi.prefix = 'ms'; 143 | fullScreenApi.supportsFullScreen = true; 144 | } 145 | } 146 | 147 | // update methods to do something useful 148 | if (fullScreenApi.supportsFullScreen) { 149 | if (fullScreenApi.prefix === 'ms') { 150 | fullScreenApi.fullScreenEventName = 'MSFullscreenChange'; 151 | } else { 152 | fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; 153 | } 154 | fullScreenApi.isFullScreen = function () { 155 | switch (this.prefix) { 156 | case '': 157 | return document.fullscreen; 158 | case 'webkit': 159 | return document.webkitIsFullScreen; 160 | case 'ms': 161 | return document.msFullscreenElement; 162 | default: 163 | return document[this.prefix + 'FullScreen']; 164 | } 165 | }; 166 | fullScreenApi.requestFullScreen = function (el) { 167 | switch (this.prefix) { 168 | case '': 169 | return el.requestFullscreen(); 170 | case 'ms': 171 | return el.msRequestFullscreen(); 172 | default: 173 | return el[this.prefix + 'RequestFullScreen'](); 174 | } 175 | }; 176 | fullScreenApi.cancelFullScreen = function () { 177 | switch (this.prefix) { 178 | case '': 179 | return document.exitFullscreen(); 180 | case 'ms': 181 | return document.msExitFullscreen(); 182 | default: 183 | return document[this.prefix + 'CancelFullScreen'](); 184 | } 185 | }; 186 | } 187 | 188 | // jQuery plugin 189 | if (typeof jQuery !== 'undefined') { 190 | jQuery.fn.requestFullScreen = function () { 191 | return this.each(function () { 192 | var el = jQuery(this); 193 | if (fullScreenApi.supportsFullScreen) { 194 | fullScreenApi.requestFullScreen(el); 195 | } 196 | }); 197 | }; 198 | } 199 | 200 | // export api 201 | window.fullScreenApi = fullScreenApi; 202 | })(); 203 | -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/citeImage.js: -------------------------------------------------------------------------------- 1 | // Variables to hold the current image URN and an array of ROIs 2 | 3 | 4 | var viewer = null 5 | var roiArray =[] 6 | 7 | /* 8 | classes: 9 | 10 | image_mappedUrn 11 | image_mappedROI 12 | image_roiGroup_1 13 | image_roi_selected 14 | 15 | */ 16 | 17 | /* 18 | function imageInNewWindow(c) { 19 | console.log("Got here… opening " ) 20 | var w = c.width; 21 | console.log(w); 22 | var h = c.height; 23 | console.log(h); 24 | var u = c.toDataURL(); 25 | window.open(u, "Image", "width=200, height=200"); 26 | } 27 | */ 28 | 29 | function idForMappedUrn(i) { 30 | var s = "image_mappedUrn_" + (i) 31 | return s 32 | } 33 | 34 | function idForMappedROI(i) { 35 | var s = "image_mappedROI_" + (i) 36 | return s 37 | } 38 | 39 | function roiToUrnId(id) { 40 | var s = id.replace("image_mappedROI_","image_mappedUrn_") 41 | return s 42 | } 43 | 44 | 45 | function clearJsRoiArray(r) { 46 | roiArray = [] 47 | } 48 | 49 | function addToJsRoiArray(i,r,u,g){ 50 | tempMap = {index: i, roi: r, mappedUrn: u, group: g} 51 | roiArray.push(tempMap) 52 | } 53 | 54 | function clearSelectedROIs(){ 55 | for (n = 0; n < (roiArray.length - 1); n++){ 56 | var roiId = idForMappedROI(n+1) 57 | var urnId = idForMappedUrn(n+1) 58 | var thisROI = document.getElementById(roiId) 59 | var thisURN = document.getElementById(urnId) 60 | thisROI.classList.remove("image_roi_selected") 61 | thisURN.classList.remove("image_roi_selected") 62 | } 63 | } 64 | 65 | function updateImageJS(collection, imageObject, path ){ 66 | //var collDirectory = collection.replace(new RegExp(':', 'g'), '_'); 67 | //var imagePath = "../../../image_archive/" + collDirectory + "/" + imageObject + ".dzi" 68 | initOpenSeadragon(path) 69 | } 70 | 71 | /** 72 | * Normalizes the index of the ROI to a number within the given amount of 73 | * colors. E.g. If there were only two colors, an index of 4 would return group 74 | * number 0 => (index % colorLength) 75 | * @param {int} i index number 76 | * @return {int} normalized group number 77 | */ 78 | function getGroup(i){ 79 | var colorArray = ["#f23568", "#6d38ff", "#38ffd7", "#fff238", "#661641", "#275fb3", "#24a669", "#a67b24", "#ff38a2", "#194973", "#35f268", "#7f441c", "#801c79", "#2a8ebf", "#216616", "#d97330", "#da32e6", "#196d73", "#bdff38", "#bf3e2a", "#3d1973", "#30cdd9", "#858c1f", "#661616" ]; 80 | var limit = colorArray.length 81 | var rv = i % limit; 82 | return rv; 83 | } 84 | 85 | function initOpenSeadragon(imagePath) { 86 | //console.log(imagePath) 87 | 88 | if (viewer != null){ 89 | viewer.destroy(); 90 | viewer = null 91 | } 92 | 93 | viewer = OpenSeadragon({ 94 | id: 'image_zoomContainer', 95 | prefixUrl: 'citeApp-js/images/', 96 | crossOriginPolicy: "Anonymous", 97 | ajaxWithCredentials: false, 98 | defaultZoomLevel: 1, 99 | tileSources: imagePath, 100 | //tileSources: 'http://www.homermultitext.org/iipsrv?DeepZoom=/project/homer/pyramidal/deepzoom/hmt/vaimg/2017a/VA024RN_0025.tif.dzi', 101 | minZoomImageRatio: 0.25, // of viewer size 102 | immediateRender: true 103 | }); 104 | 105 | viewer.guides({ 106 | allowRotation: false, // Make it possible to rotate the guidelines (by double clicking them) 107 | horizontalGuideButton: null, // Element for horizontal guideline button 108 | verticalGuideButton: null, // Element for vertical guideline button 109 | prefixUrl: "citeApp-js/images/", // Images folder 110 | removeOnClose: false, // Remove guidelines when viewer closes 111 | useSessionStorage: false, // Save guidelines in sessionStorage 112 | navImages: { 113 | guideHorizontal: { 114 | REST: 'guidehorizontal_rest.png', 115 | GROUP: 'guidehorizontal_grouphover.png', 116 | HOVER: 'guidehorizontal_hover.png', 117 | DOWN: 'guidehorizontal_pressed.png' 118 | }, 119 | guideVertical: { 120 | REST: 'guidevertical_rest.png', 121 | GROUP: 'guidevertical_grouphover.png', 122 | HOVER: 'guidevertical_hover.png', 123 | DOWN: 'guidevertical_pressed.png' 124 | } 125 | } 126 | }); 127 | 128 | 129 | // Add overlays 130 | setTimeout(function(){ 131 | if (viewer.world.getItemAt(0)){ 132 | //console.log("defined"); 133 | } else { 134 | //console.log("undefined"); 135 | } 136 | var baseTimer = 0; 137 | while( !(viewer.world.getItemAt(0))){ 138 | baseTimer = baseTimer + 1; 139 | } 140 | //console.log(baseTimer); 141 | var normH = viewer.world.getItemAt(0).getBounds().height; 142 | var normW = viewer.world.getItemAt(0).getBounds().width; 143 | if (roiArray.length > 0){ 144 | for (ol = 0; ol < roiArray.length; ol++){ 145 | var roi = roiArray[ol].roi 146 | var rl = +roi.split(",")[0] 147 | var rt = +roi.split(",")[1] 148 | var rw = +roi.split(",")[2] 149 | var rh = +roi.split(",")[3] 150 | var tl = rl * normW 151 | var tt = rt * normH 152 | var tw = rw * normW 153 | var th = rh * normH 154 | var osdRect = new OpenSeadragon.Rect(tl,tt,tw,th) 155 | var elt = document.createElement("a") 156 | elt.id = idForMappedROI(roiArray[ol].index) 157 | elt.className = "image_mappedROI" + " image_roiGroup_" + roiArray[ol].group + " " + idForMappedUrn(roiArray[ol].index) 158 | elt.dataset.urn = roiArray[ol].mappedUrn 159 | 160 | viewer.addOverlay(elt,osdRect) 161 | } 162 | } 163 | 164 | // Go through and attach events to each overlay 165 | for (n = 0; n < roiArray.length; n++){ 166 | var captureN = n // because N keeps moving 167 | var thisId = idForMappedROI(roiArray[n].index) 168 | var thisElement = document.getElementById(thisId) 169 | thisElement.addEventListener("click", function(e) { 170 | clearSelectedROIs() 171 | var roiId = e.target.id 172 | var targetId = roiToUrnId(roiId) 173 | var targetSpan = document.getElementById(targetId) 174 | targetSpan.classList.add("image_roi_selected") 175 | e.target.classList.add("image_roi_selected") 176 | }, false); 177 | } 178 | },6000); 179 | 180 | } 181 | -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/161728.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/161728.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/button_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/button_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/button_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/button_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/button_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/fullpage_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/fullpage_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/fullpage_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/fullpage_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/fullpage_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidehorizontal_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidehorizontal_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidehorizontal_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidehorizontal_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidehorizontal_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidevertical_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidevertical_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidevertical_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/guidevertical_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/guidevertical_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/home_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/home_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/home_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/home_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/home_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/icon-fullscreen-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/icon-fullscreen-2x.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/icon-fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/icon-fullscreen.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/img_254851.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/img_254851.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/next_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/next_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/next_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/next_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/next_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/previous_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/previous_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/previous_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/previous_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/previous_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateleft_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateleft_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateleft_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateleft_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateleft_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateright_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateright_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateright_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/rotateright_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/rotateright_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_cancel_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_cancel_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_cancel_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_cancel_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_cancel_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_confirm_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_confirm_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_confirm_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_confirm_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_confirm_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/selection_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/selection_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomin_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomin_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomin_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomin_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomin_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomout_grouphover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_grouphover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomout_hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_hover.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomout_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_pressed.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/images/zoomout_rest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cite-architecture/CITE-App/62da849dd4389c68c7083a943ebadf21d999bbb8/src/main/resources/citeApp-js/images/zoomout_rest.png -------------------------------------------------------------------------------- /src/main/resources/citeApp-js/textExtensions.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function initiateMarked(markdownString, elementId) { 4 | setTimeout(function(){ 5 | var parsedMarkdown = marked(markdownString).replace("

","").replace("

","") 6 | document.getElementById(elementId).innerHTML = parsedMarkdown; 7 | },1000); 8 | } 9 | 10 | function initiateLeafletWithLatLong(lat, long, elementId) { 11 | setTimeout(function(){ 12 | var latitude = parseFloat(lat); 13 | var longitude = parseFloat(long); 14 | var mymap = L.map(elementId).setView([latitude, longitude], 13); 15 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { 16 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', 17 | maxZoom: 18, 18 | id: 'mapbox.satellite', 19 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ' 20 | }).addTo(mymap); 21 | var marker = L.marker([latitude, longitude]).addTo(mymap); 22 | },1000); 23 | } 24 | 25 | function initiateLeafletWithGeoJson(geojson, elementId) { 26 | setTimeout(function(){ 27 | var myFeature = JSON.parse(geojson); 28 | var mymap = L.map(elementId).setView([0, 0], 20); 29 | L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { 30 | attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox', 31 | maxZoom: 18, 32 | id: 'mapbox.satellite', 33 | accessToken: 'pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ' 34 | }).addTo(mymap); 35 | var gjFeature = L.geoJSON(myFeature) 36 | gjFeature.addTo(mymap); 37 | mymap.fitBounds(gjFeature.getBounds()); 38 | mymap.zoomOut(3); 39 | 40 | // create a fullscreen button and add it to the map 41 | L.control.fullscreen({ 42 | position: 'topleft', // change the position of the button can be topleft, topright, bottomright or bottomleft, defaut topleft 43 | title: 'Show me the fullscreen !', // change the title of the button, default Full Screen 44 | titleCancel: 'Exit fullscreen mode', // change the title of the button when fullscreen is on, default Exit Full Screen 45 | content: null, // change the content of the button, can be HTML, default null 46 | forceSeparateButton: true, // force seperate button to detach from zoom buttons, default false 47 | forcePseudoFullscreen: true, // force use of pseudo full screen even if full screen API is available, default false 48 | fullscreenElement: false // Dom element to render in full screen, false by default, fallback to map._container 49 | }).addTo(mymap); 50 | 51 | // events are fired when entering or exiting fullscreen. 52 | mymap.on('enterFullscreen', function(){ 53 | console.log('entered fullscreen'); 54 | }); 55 | 56 | mymap.on('exitFullscreen', function(){ 57 | console.log('exited fullscreen'); 58 | }); 59 | 60 | },1000); 61 | 62 | 63 | } 64 | 65 | // mapbox token pk.eyJ1IjoiY2JsYWNrMDEiLCJhIjoiN0duY2dHRSJ9.O4qgM_Pn3mftGyZk8fIhoQ -------------------------------------------------------------------------------- /src/main/resources/index-dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cite Environment (Development 1.15.0) 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/main/resources/index-opt.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Cite Environment v.1.15.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CitableImageModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import scala.scalajs.js.Dynamic.{ global => g } 8 | import js.annotation._ 9 | import collection.mutable 10 | import collection.mutable._ 11 | import org.scalajs.dom._ 12 | import org.scalajs.dom.ext._ 13 | import org.scalajs.dom.raw._ 14 | import edu.holycross.shot.cite._ 15 | import edu.holycross.shot.ohco2._ 16 | import edu.holycross.shot.citeobj._ 17 | 18 | import scala.scalajs.js.annotation.JSExport 19 | import js.annotation._ 20 | 21 | /* 22 | Defines a model for dealing with objects that implement the 23 | CiteBinaryImage datamodel. 24 | */ 25 | 26 | @JSExportTopLevel("CitableImageModel") 27 | object CitableImageModel { 28 | 29 | case class ImageObject(val urn:Cite2Urn, val caption:String, val rights:String) { 30 | override def toString = s"${urn} - ${caption}. ${rights}" 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CiteBinaryImageModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import scala.scalajs.js.Dynamic.{ global => g } 8 | import js.annotation._ 9 | import collection.mutable 10 | import collection.mutable._ 11 | import org.scalajs.dom._ 12 | import org.scalajs.dom.ext._ 13 | import org.scalajs.dom.raw._ 14 | import edu.holycross.shot.cite._ 15 | import edu.holycross.shot.ohco2._ 16 | import edu.holycross.shot.citeobj._ 17 | import edu.holycross.shot.scm._ 18 | import edu.holycross.shot.citebinaryimage._ 19 | 20 | import scala.scalajs.js.annotation.JSExport 21 | import js.annotation._ 22 | 23 | /* 24 | Defines a model for dealing with objects that implement the 25 | CiteBinaryImage datamodel. 26 | */ 27 | 28 | @JSExportTopLevel("CiteBinaryImageModel") 29 | object CiteBinaryImageModel { 30 | 31 | // URNs for implemented Image models 32 | val binaryImageModelUrn:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:binaryimg") 33 | val protocolPropertyName:String = "protocol" 34 | val iiifApiProtocolString:String = "iiifApi" 35 | val localDZProtocolString:String = "localDeepZoom" 36 | val iipDZProtocolString:String = "iipDeepZoom" 37 | val jpgProtocolString:String = "JPG" 38 | 39 | 40 | // this is changed by the user using the local/remote switch 41 | val imgUseLocal = Var[Boolean](false) 42 | 43 | // this is set at app init 44 | val imgArchivePath = Var[String]("") 45 | 46 | 47 | // To save everyone time, is *any* collection in the current CEX 48 | // supported for local viewing? 49 | val hasLocalOption = Var[Boolean](false) 50 | // To save everyone time, is *any* collection in the current CEX 51 | // supported for remote viewing? 52 | val hasRemoteOption = Var[Boolean](false) 53 | 54 | 55 | // any binary image implemented? 56 | val hasBinaryImages = Var[Boolean](false) 57 | val binaryImageCollections = Vars.empty[Cite2Urn] 58 | 59 | // which protocols are implemented in this CEX? 60 | /* 61 | val hasIiifApi = Var[Boolean](false) 62 | val hasLocalDeepZoom = Var[Boolean](false) 63 | val hasJPG = Var[Boolean](false) 64 | val hasIipDZ = Var[Boolean](false) 65 | */ 66 | 67 | // urn is what the user requested 68 | val urn = Var[Option[Cite2Urn]](None) 69 | 70 | /* If a user requests a single URN with an ROI, preview that. But if 71 | we're doing some fancy data model stuff, we might want to show 72 | the whole image in the preview. So we separate the current URN from 73 | the current Preview Urn */ 74 | val previewUrn = Var[Option[Cite2Urn]](None) 75 | 76 | // An ImageROI object associates an roi with a urn; 77 | // our image may have none, one, or many 78 | val imageRoiTuple = Vars.empty[(Int,ImageRoiModel.Roi)] 79 | // This splits imageRoiTuple up into groups 80 | val imageRoiGroups = Var[Option[Map[String,Int]]](None) 81 | // And for convenience, and making Binding happen, another view of the roiGroups… 82 | val imageRoiGroupSeq = Vars.empty[(String,Int)] 83 | 84 | val currentContextUrn = Var[Option[Urn]](None) 85 | 86 | 87 | // User Interface stuff 88 | val userMessage = Var("") 89 | val userAlert = Var("default") 90 | val userMessageVisibility = Var("app_hidden") 91 | // for displaying and hiding user messages 92 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null 93 | val thumbnailMaxWidth:Int = 400 94 | 95 | // Current info on image displayed 96 | val displayUrn = Var[Option[Cite2Urn]](None) 97 | // Do we use this? 98 | val versionsForCurrentUrn = Var(1) 99 | 100 | def clearROIs:Unit = { 101 | imageRoiTuple.value.clear 102 | imageRoiGroups.value = None 103 | imageRoiGroupSeq.value.clear 104 | } 105 | 106 | def loadROIs(rois:Vector[ImageRoiModel.Roi]):Unit = { 107 | clearROIs 108 | for ( (roi,i) <- rois.zipWithIndex){ 109 | val t:(Int,ImageRoiModel.Roi) = (i, roi) 110 | CiteBinaryImageModel.imageRoiTuple.value += t 111 | } 112 | imageRoiGroups.value = CiteBinaryImageController.groupsForROIs(rois) 113 | imageRoiGroups.value match { 114 | case Some(irg) => { 115 | irg.toVector.foreach( g => { 116 | imageRoiGroupSeq.value += g 117 | }) 118 | } 119 | case None => imageRoiGroupSeq.value.clear 120 | } 121 | 122 | } 123 | 124 | 125 | def addToROIs(roi:ImageRoiModel.Roi):Unit = { 126 | val i = imageRoiTuple.value.size 127 | val t:(Int,ImageRoiModel.Roi) = (i, roi) 128 | CiteBinaryImageModel.imageRoiTuple.value += t 129 | val roiPreVec = CiteBinaryImageModel.imageRoiTuple.value.map(_._2).toVector 130 | imageRoiGroups.value = None // Clear it out 131 | imageRoiGroups.value = CiteBinaryImageController.groupsForROIs(roiPreVec) 132 | } 133 | 134 | def imageRoisToOptionVector:Option[Vector[ImageRoiModel.Roi]] = { 135 | imageRoiTuple.value.size match { 136 | case s if (s == 1) => None 137 | case _ => { 138 | val roiVec:Vector[ImageRoiModel.Roi] = imageRoiTuple.value.map( r => r._2).toVector 139 | Some(roiVec) 140 | } 141 | } 142 | } 143 | 144 | /* This is how to pass data to the global JS scope */ 145 | /* 146 | js.Dynamic.global.currentImageUrn = "urn:cts" 147 | js.Dynamic.global.roiArray = Array("one","two","three") 148 | */ 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CiteMain.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | import com.thoughtworks.binding.{Binding, dom} 3 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 4 | import com.thoughtworks.binding.Binding.{Var, Vars} 5 | import com.thoughtworks.binding.dom 6 | import org.scalajs.dom.document 7 | import org.scalajs.dom.raw.Event 8 | import org.scalajs.dom.ext.Ajax 9 | import scala.concurrent 10 | .ExecutionContext 11 | .Implicits 12 | .global 13 | 14 | import scala.scalajs.js 15 | import scala.scalajs.js._ 16 | import js.annotation._ 17 | import scala.scalajs.js.annotation.JSExport 18 | 19 | @JSExportTopLevel("CiteMain") 20 | class CiteMain(remoteUrl:String, localImagePath:String, serverMode:String) { 21 | 22 | @JSExport 23 | def main(): Unit = { 24 | CiteMainController.main(remoteUrl: String, localImagePath:String, serverMode:String) 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CiteMainModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | import com.thoughtworks.binding.{Binding, dom} 3 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 4 | import com.thoughtworks.binding.Binding.{Var, Vars} 5 | import com.thoughtworks.binding.dom 6 | import org.scalajs.dom.document 7 | import org.scalajs.dom.raw.Event 8 | import org.scalajs.dom.ext.Ajax 9 | import scala.concurrent 10 | .ExecutionContext 11 | .Implicits 12 | .global 13 | 14 | import scala.scalajs.js 15 | import scala.scalajs.js._ 16 | import edu.holycross.shot.cite._ 17 | import js.annotation._ 18 | import edu.holycross.shot.scm._ 19 | 20 | 21 | @JSExportTopLevel("CiteMainModel") 22 | object CiteMainModel { 23 | 24 | val userMessage = Var("Main loaded.") 25 | val userAlert = Var("default") 26 | val userMessageVisibility = Var("app_hidden") 27 | 28 | val requestParameterUrn = Var[Option[Urn]](None) 29 | 30 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null 31 | 32 | val currentLibraryMetadataString = Var("No library loaded.") 33 | 34 | // These are terrible and need to be replaced with real data model stuff 35 | val textProtocol:String = "TextProtocol" 36 | val objectProtocol:String = "ObjectProtocol" 37 | val localImageProtocol:String = "LocalImageProtocol" 38 | 39 | val cexMainDelimiter:String = "#" 40 | val cexSecondaryDelimiter:String = "," 41 | 42 | 43 | val showTexts = Var(true) 44 | val showNg = Var(true) 45 | val showCollections = Var(true) 46 | val showImages = Var(true) 47 | val mainLibrary = Var[Option[CiteLibrary]](None) 48 | val showRelations = Var(true) 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CiteMainView.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import org.scalajs.dom._ 8 | import org.scalajs.dom.ext._ 9 | import scala.scalajs.js.Dynamic.{ global => g } 10 | import org.scalajs.dom.raw._ 11 | import org.scalajs.dom.document 12 | import org.scalajs.dom.raw.Event 13 | import org.scalajs.dom.ext.Ajax 14 | import edu.holycross.shot.cite._ 15 | import edu.holycross.shot.ohco2._ 16 | import edu.holycross.shot.citeobj._ 17 | import scala.scalajs.js.annotation.JSExport 18 | import js.annotation._ 19 | 20 | 21 | @JSExportTopLevel("CiteMainView") 22 | object CiteMainView { 23 | 24 | val textView = O2View.o2div 25 | val ngramView = NGView.nGdiv 26 | val objectView = ObjectView.objectDiv 27 | val imageView = CiteBinaryImageView.imageDiv 28 | val relationsView = RelationsView.relationsDiv 29 | val serverMode = Var(false) 30 | 31 | 32 | def changeTab(tab:String):Unit = { 33 | tab match { 34 | case "text" => js.Dynamic.global.document.getElementById("tab-1").checked = true 35 | case "object" => js.Dynamic.global.document.getElementById("tab-3").checked = true 36 | case "image" => js.Dynamic.global.document.getElementById("tab-4").checked = true 37 | case "relations" => js.Dynamic.global.document.getElementById("tab-5").checked = true 38 | } 39 | } 40 | 41 | // *** Apropos Microservice *** 42 | // We will want a switch here 43 | @dom 44 | def filePicker = { 45 | 46 | 47 | CiteMainController.loadLocalLibrary( event )} 51 | > 52 | { imageLocalRemoteSwitch.bind } 53 | 54 | } 55 | 56 | // *** Apropos Microservice *** 57 | @dom 58 | def imageLocalRemoteSwitch = { 59 |
{ 62 | CiteBinaryImageModel.hasBinaryImages.bind match { 63 | case true => "app_visible" 64 | case _ => "app_hidden" 65 | } 66 | } 67 | case _ => "app_hidden" 68 | } 69 | }> 70 | Image Source: 71 | "app_hidden" 74 | case false => "app_visible" 75 | } 76 | }> 77 | "app_visible" 80 | case _ => "app_hidden" 81 | } 82 | }>Using Local Images 83 | "app_visible" 86 | case _ => "app_hidden" 87 | } 88 | }>Using Remote Images 89 | 90 |
"onoffswitch app_visible" 93 | case false => "onoffswitch app_hidden" 94 | } 95 | }> 96 | "onoffswitch-checkbox app_visible" 100 | case false => "onoffswitch-checkbox app_hidden" 101 | } 102 | } id="citeMain_localImageSwitch" checked={CiteBinaryImageModel.imgUseLocal.bind} 103 | onchange={ event: Event => CiteBinaryImageController.setPreferredImageSource} 104 | /> 105 | 109 |
110 |
111 | } 112 | 113 | 114 | @dom 115 | def mainMessageDiv = { 116 |
117 |

{ CiteMainModel.userMessage.bind }

118 |
119 | } 120 | 121 | @dom 122 | def mainDiv = { 123 |
124 |
125 | 126 | { CiteMainModel.currentLibraryMetadataString.bind } 127 | 128 | { filePicker.bind } 129 | CITE Environment 130 | version { BuildInfo.version } 131 | [ Online Help ] 132 |
133 | 134 |
135 | 136 | { mainMessageDiv.bind } 137 |
138 | 139 |
"app_visible app_tab" 143 | case _ => "app_hidden app_tab" 144 | } 145 | }> 146 | 147 | 148 |
149 | { textView.bind } 150 |
151 |
152 | 153 |
"app_visible app_tab" 157 | case _ => "app_hidden app_tab" 158 | } 159 | }> 160 | 161 | 162 |
163 | { ngramView.bind } 164 |
165 |
166 | 167 |
"app_visible app_tab" 171 | case _ => "app_hidden app_tab" 172 | } 173 | }> 174 | 175 | 176 |
177 | { objectView.bind } 178 |
179 |
180 | 181 |
"app_visible app_tab" 185 | case _ => "app_hidden app_tab" 186 | } 187 | }> 188 | 189 | 190 |
191 | { imageView.bind } 192 |
193 |
194 | 195 |
"app_visible app_tab" 199 | case _ => "app_hidden app_tab" 200 | } 201 | }> 202 | 203 | 204 |
205 | { relationsView.bind } 206 |
207 |
208 | 209 |
210 |
211 |
212 |
213 | { footer.bind } 214 |
215 |
216 | } 217 | 218 | 219 | @dom 220 | def footer = { 221 |

222 | { CiteMainModel.currentLibraryMetadataString.bind } 223 |

224 |

225 | CITE/CTS is ©2002–2018 Neel Smith and Christopher Blackwell. This implementation of the CITE data models was written by Neel Smith and Christopher Blackwell using Scala, Scala-JS, and Binding.scala. Licensed under the GPL 3.0. Sourcecode on GitHub. Copyright and licensing information for the default library is available here. Report bugs by filing issues on GitHub. 226 |

227 | } 228 | 229 | } 230 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/CommentaryModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.citerelation._ 20 | import edu.holycross.shot.scm._ 21 | 22 | import monix.execution.Scheduler.Implicits.global 23 | import monix.eval._ 24 | 25 | import scala.scalajs.js.annotation.JSExport 26 | 27 | @JSExportTopLevel("CommentaryModel") 28 | object CommentaryModel { 29 | 30 | val commentaryVerb:Cite2Urn = Cite2Urn("urn:cite2:cite:verbs.v1:commentsOn") 31 | val commentaryModel:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:commentarymodel") 32 | // commentsOn not used yet… 33 | val commentsOn = Var[Boolean](true) 34 | 35 | case class CiteComment(comment:Urn, text:Urn) 36 | 37 | val commentList = Vars.empty[CiteComment] 38 | val currentCommentsAll = Vars.empty[CiteComment] 39 | val currentCommentsDistinctComments = Vars.empty[CiteComment] 40 | 41 | def ctsHasCommentary(urn:CtsUrn):Vars[Urn] = { 42 | DataModelController.hasCommentaryModel match { 43 | case false => Vars.empty[Urn] 44 | case _ => { 45 | val relevantComments:Vector[CiteComment] = currentCommentsAll.value.filter(_.text.asInstanceOf[CtsUrn] == urn).toVector 46 | val v = Vars.empty[Urn] 47 | for (c <- relevantComments) { 48 | v.value += c.comment 49 | } 50 | v 51 | } 52 | } 53 | } 54 | 55 | def clearAllComments:Unit = { 56 | commentList.value.clear 57 | currentCommentsAll.value.clear 58 | currentCommentsDistinctComments.value.clear 59 | } 60 | 61 | def clearPassageComments:Unit = { 62 | currentCommentsAll.value.clear 63 | currentCommentsDistinctComments.value.clear 64 | } 65 | 66 | def updateCurrentListOfComments(corp:Corpus):Unit = { 67 | clearPassageComments 68 | //val corpUrns:Vector[CtsUrn] = corp.urns 69 | commentList.value.size match { 70 | case s if (s > 0) => { 71 | val twiddledComments:Vector[CiteComment] = { 72 | commentList.value.filter( c => { 73 | val textMatch:Boolean = { 74 | c.text match { 75 | case CtsUrn(_) => { 76 | //((corp ~~ c.text.asInstanceOf[CtsUrn]).size > 0) 77 | //(corp.nodes.filter(_.urn == c.text.asInstanceOf[CtsUrn]).size > 0) 78 | val curn:CtsUrn = c.text.asInstanceOf[CtsUrn] 79 | /* 80 | val curn:CtsUrn = { 81 | if (tempUrn.isRange){ 82 | CtsUrn(s"${tempUrn.dropPassage}${tempUrn.rangeBegin}") 83 | } else { 84 | tempUrn 85 | } 86 | } 87 | */ 88 | (corp.nodes.view.filter(_.urn <= curn).size > 0) 89 | 90 | 91 | } 92 | case _ => false 93 | } 94 | } 95 | val commentMatch:Boolean = { 96 | c.comment match { 97 | case CtsUrn(_) => { 98 | //((corp ~~ c.text.asInstanceOf[CtsUrn]).size > 0) 99 | //(corp.nodes.filter(_.urn == c.text.asInstanceOf[CtsUrn]).size > 0) 100 | val curn:CtsUrn = c.comment.asInstanceOf[CtsUrn] 101 | /* 102 | val curn:CtsUrn = { 103 | if (tempUrn.isRange){ 104 | CtsUrn(s"${tempUrn.dropPassage}${tempUrn.rangeBegin}") 105 | } else { 106 | tempUrn 107 | } 108 | } 109 | */ 110 | (corp.nodes.view.filter(_.urn == curn).size > 0) 111 | } 112 | case _ => false 113 | } 114 | } 115 | (textMatch || commentMatch) 116 | }).toVector 117 | } 118 | // If any of the twiddledComments were ranges, let's expand those… 119 | val rangeComments:Vector[CiteComment] = { 120 | twiddledComments.filter( c => { 121 | c.text.asInstanceOf[CtsUrn].isRange 122 | }).toVector 123 | } 124 | 125 | 126 | 127 | 128 | val expandedRangeComments:Vector[CiteComment] = { 129 | ( 130 | for (rc <- rangeComments) yield { 131 | val urns:Vector[CtsUrn] = (corp ~~ rc.text.asInstanceOf[CtsUrn]).urns 132 | urns.map( u => { CiteComment(rc.comment,u)}) 133 | } 134 | ).flatten 135 | } 136 | // And then we need to ditch the range comments from the original 137 | val nonRangeComments:Vector[CiteComment] = { 138 | twiddledComments.filter( c => { 139 | c.text.asInstanceOf[CtsUrn].isRange == false 140 | }).toVector 141 | } 142 | 143 | // And we concatenate those, and eliminate dups 144 | val finalCurrentComments:Vector[CiteComment] = { 145 | (nonRangeComments ++ expandedRangeComments).distinct.toVector 146 | } 147 | 148 | 149 | // If any comment is a Cite2Urn at the notional level, get it… 150 | val notionalCollComments:Vector[CiteComment] = { 151 | finalCurrentComments.filter( c => { 152 | c.comment match { 153 | case Cite2Urn(_) => { 154 | val u:Cite2Urn = c.comment.asInstanceOf[Cite2Urn] 155 | u.versionOption match { 156 | case Some(v) => false 157 | case None => true 158 | } 159 | } 160 | case _ => false 161 | } 162 | }).distinct 163 | } 164 | 165 | // …now let's see if we can find some versions for that… 166 | val versionedNotionalCommentUrns:Vector[CiteComment] = { 167 | ObjectModel.collRep.value match { 168 | case Some(cr) => { 169 | // for each notionalCollComment, find all real urns 170 | notionalCollComments.map(ncc => { 171 | val realUrns:Vector[Cite2Urn] = cr.citableObjects.view.filter(_.urn ~~ ncc.comment).map(_.urn).toVector 172 | val newComments:Vector[CiteComment] = realUrns.map(ru => { 173 | CiteComment(ru,ncc.text) 174 | }) 175 | newComments 176 | }).flatten 177 | } 178 | case None => Vector() 179 | } 180 | } 181 | 182 | val reallyFinalCurrentComments:Vector[CiteComment] = finalCurrentComments ++ versionedNotionalCommentUrns 183 | 184 | //g.console.log(s"really final = ${reallyFinalCurrentComments}") 185 | 186 | // And we concatenate while removing unversioned comments 187 | for (c <- reallyFinalCurrentComments){ 188 | c.comment match { 189 | case CtsUrn(_) => currentCommentsAll.value += c 190 | case Cite2Urn(_) => { 191 | if (c.comment.asInstanceOf[Cite2Urn].versionOption != None) currentCommentsAll.value += c 192 | } 193 | case _ => // do nothing 194 | } 195 | } 196 | 197 | // And let's get a version that just has unique comments, for the sidebar 198 | val uniquedComments:Vector[CiteComment] = reallyFinalCurrentComments.filter(cc => { 199 | cc.comment match { 200 | case CtsUrn(_) => true 201 | case Cite2Urn(_) => { 202 | cc.comment.asInstanceOf[Cite2Urn].versionOption != None 203 | } 204 | case _ => false 205 | 206 | } 207 | }).groupBy(_.comment).map(_._2.head).toVector 208 | // And why not group by work/collection, while we're at it… the list isn't going to be long 209 | val map1:Vector[Tuple2[String,CiteComment]] = uniquedComments.map(c => { 210 | val mapString:String = { 211 | c.comment match { 212 | case CtsUrn(_) => c.comment.asInstanceOf[CtsUrn].dropPassage.toString 213 | case _ => c.comment.asInstanceOf[Cite2Urn].dropSelector.toString 214 | } 215 | } 216 | Tuple2(mapString,c) 217 | }) 218 | val map2:Vector[(String,Vector[Tuple2[String,CiteComment]])] = map1.groupBy(_._1).toVector 219 | val map3:Vector[Tuple2[String,CiteComment]] = map2.map(_._2).flatten 220 | val map4:Vector[CiteComment] = map3.map(_._2) 221 | 222 | for (c <- map4){ 223 | currentCommentsDistinctComments.value += c 224 | } 225 | 226 | } 227 | case _ => //do nothing 228 | } 229 | } 230 | 231 | def loadAllComments:Unit = { 232 | commentList.value.clear 233 | if (DataModelController.hasCommentaryModel) { 234 | val tempComments:Option[CiteRelationSet] = { 235 | RelationsModel.citeRelations.value match { 236 | case Some(cr) => { 237 | val cv:CiteRelationSet = cr.verb(commentaryVerb) 238 | cv.size match { 239 | case s if (s > 0) => Some(cv) 240 | case _ => None 241 | } 242 | } 243 | case None => None 244 | } 245 | } 246 | if (tempComments != None) { 247 | for (c <- tempComments.get.relations ){ 248 | commentList.value += CiteComment(comment = c.urn1, text = c.urn2) 249 | } 250 | } 251 | } 252 | } 253 | 254 | 255 | } 256 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/DataModelController.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.scm._ 20 | 21 | import monix.execution.Scheduler.Implicits.global 22 | import monix.eval._ 23 | 24 | import scala.scalajs.js.annotation.JSExport 25 | 26 | @JSExportTopLevel("DataModelController") 27 | object DataModelController { 28 | 29 | // Clear Data Models 30 | def clearDataModels:Unit = { 31 | DataModelModel.dataModels.value = None 32 | CiteBinaryImageModel.hasBinaryImages.value = false 33 | CiteBinaryImageModel.hasRemoteOption.value = false 34 | CiteBinaryImageModel.hasLocalOption.value = false 35 | } 36 | 37 | // Probably should be in CiteObj library? 38 | // Given a collection URN and a property name, construct a property URN 39 | def propertyUrnFromPropertyName(urn:Cite2Urn, propName:String):Cite2Urn = { 40 | val returnUrn:Cite2Urn = { 41 | urn.propertyOption match { 42 | case Some(po) => urn // just return it! 43 | case None => { 44 | val collUrn:Cite2Urn = urn.dropSelector 45 | val collUrnString:String = collUrn.toString.dropRight(1) // remove colon 46 | urn.objectComponentOption match { 47 | case Some(oc) => { 48 | Cite2Urn(s"${collUrnString}.${propName}:${oc}") 49 | } 50 | case None => { 51 | Cite2Urn(s"${collUrnString}.${propName}:") 52 | } 53 | } 54 | } 55 | } 56 | } 57 | returnUrn 58 | } 59 | 60 | // Checks to see if a text is present in the currently loaded library 61 | // Will match with ~~ similarity 62 | // *** ALERT *** for testing, I'm turning all of these into work-level URNs. 63 | def hasText(u:CtsUrn):Boolean = { 64 | O2Model.textRepo.value match { 65 | case Some(tr) => { 66 | tr.catalog.texts.filter(_.urn ~~ u.dropPassage).size match { 67 | case 0 => false 68 | case _ => true 69 | } 70 | } 71 | case None => { 72 | false 73 | } 74 | } 75 | } 76 | 77 | def hasObject(u:Cite2Urn):Boolean = { 78 | val urn:Cite2Urn = { 79 | val tempU:Cite2Urn = u.dropExtensions 80 | tempU.isRange match { 81 | case true => tempU.rangeBeginUrn 82 | case _ => tempU 83 | } 84 | } 85 | ObjectModel.collRep.value match { 86 | case Some(cr) => { 87 | cr.citableObjects.filter(_.urn == urn.dropExtensions).size match { 88 | case 1 => true 89 | case _ => false 90 | } 91 | } 92 | case None => { 93 | false 94 | } 95 | } 96 | } 97 | 98 | /* Check to see if the Citable Image datamodel is: 99 | 1. supported by this app 100 | 2. present in this library 101 | 3. implemented by the collection represented by `u` 102 | */ 103 | def isCitableImage(u:Cite2Urn):Boolean ={ 104 | val collUrn:Cite2Urn = u.dropSelector 105 | val citableImageModelUrn:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:imagemodel") 106 | 107 | DataModelModel.dataModels.value match { 108 | case None => false 109 | case Some(dms) => { 110 | val implementations:Vector[DataModel] = dms.filter(_.model == citableImageModelUrn).filter(_.collection == collUrn) 111 | implementations.size match { 112 | case 0 => false 113 | case _ => true 114 | } 115 | } 116 | } 117 | } 118 | 119 | /* 120 | Given a Cite2Urn, see if it identifies a property that is of type 'text' and is 121 | extended by a published protocol 122 | */ 123 | // Returns None, or the type of extension 124 | def textPropertyIsExtended(propUrn:Cite2Urn):Option[String] = { 125 | try { 126 | val extensionModel:Cite2Urn = Cite2Urn("urn:cite2:cite:datamodels.v1:extensions_text") 127 | if ( DataModelModel.implementedDataModels.contains(extensionModel) ) { 128 | propUrn.propertyOption match { 129 | case Some(po) => { 130 | CiteMainModel.mainLibrary.value match { 131 | case Some(dms) => { 132 | val extendedPropColls:Vector[Cite2Urn] = dms.collectionsForModel(extensionModel) 133 | /* for each in extendedPropColls 134 | filter collection for @propertyurn 135 | */ 136 | val implementingObjects:Vector[CiteObject] = { 137 | // get all objects in collection of extensions 138 | val allExtendedObjs:Vector[CiteObject] = extendedPropColls.view.map(c => ObjectModel.collRep.value.get.citableObjects.filter(_.urn ~~ c)).toVector.flatten 139 | val matchingObjs:Vector[CiteObject] = allExtendedObjs.filter( ob => { 140 | val thisPropUrn:Cite2Urn = propertyUrnFromPropertyName(ob.urn, "propertyurn") 141 | val propVal = { 142 | ob.propertyValue(thisPropUrn).asInstanceOf[Cite2Urn].objectOption match { 143 | case Some(oo) => { 144 | ob.propertyValue(thisPropUrn) == propUrn 145 | } 146 | case None => { 147 | ob.propertyValue(thisPropUrn) == propUrn.dropSelector 148 | } 149 | } 150 | } 151 | propVal 152 | }) 153 | matchingObjs 154 | } 155 | implementingObjects.size match { 156 | case n if (n > 0) => { 157 | // if there is more than one, there is bad data, but we'll just return the first one. 158 | val thisObj:CiteObject = implementingObjects(0) 159 | val thisPropUrn:Cite2Urn = propertyUrnFromPropertyName(thisObj.urn, "extendedtype") 160 | val extType:String = thisObj.propertyValue(thisPropUrn).asInstanceOf[String] 161 | Some(extType) 162 | } 163 | case _ => None 164 | } 165 | } 166 | case None => None 167 | } 168 | } 169 | case None => None 170 | } 171 | } else { 172 | None 173 | } 174 | } catch { 175 | case e:Exception => Some("") 176 | } 177 | } 178 | 179 | /* Check to see if the Commentary datamodel is present */ 180 | def hasCommentaryModel:Boolean = { 181 | val commUrn:Cite2Urn = CommentaryModel.commentaryModel 182 | DataModelModel.dataModels.value match { 183 | case None => false 184 | case Some(dms) => { 185 | val implementations:Vector[DataModel] = dms.filter(_.model == commUrn).toVector 186 | implementations.size match { 187 | case 0 => false 188 | case _ => true 189 | } 190 | } 191 | } 192 | } 193 | 194 | 195 | /* 196 | Methods for switching tabs and loading text and objects 197 | */ 198 | 199 | def retrieveUrn(u:Urn):Unit = { 200 | u match { 201 | case CtsUrn(_) => retrieveTextPassage(None, u.asInstanceOf[CtsUrn]) 202 | case Cite2Urn(_) => retrieveObject(None, u.asInstanceOf[Cite2Urn]) 203 | case _ => CiteMainController.updateUserMessage(s"Could not resolve ${u} to either CtsUrn or Cite2Urn",2) 204 | 205 | } 206 | } 207 | 208 | def retrieveTextPassage(contextUrn:Option[Cite2Urn] = None, urn:CtsUrn):Unit = { 209 | O2Controller.changeUrn(urn) 210 | CiteMainView.changeTab("text") 211 | } 212 | 213 | def retrieveObject(contextUrn:Option[Cite2Urn] = None, urn:Cite2Urn):Unit = { 214 | val tempUrn:Cite2Urn = urn.dropExtensions 215 | ObjectController.changeUrn(tempUrn) 216 | ObjectController.changeObject 217 | CiteMainView.changeTab("object") 218 | } 219 | 220 | 221 | def viewImage( 222 | contextUrn:Option[Cite2Urn], 223 | implementingObject:CiteObject, 224 | urn:Cite2Urn, 225 | roiObj:ImageRoiModel.Roi 226 | ):Unit = { 227 | viewImage(contextUrn, implementingObject, urn, Some(Vector(roiObj))) 228 | } 229 | 230 | 231 | def viewImage( 232 | contextUrn:Option[Cite2Urn], 233 | implementingObject:CiteObject, 234 | urn:Cite2Urn, 235 | roiObj:Option[Vector[ImageRoiModel.Roi]] 236 | ):Unit = { 237 | CiteBinaryImageController.changeUrn(contextUrn, urn, roiObj) 238 | CiteMainView.changeTab("image") 239 | } 240 | 241 | 242 | } 243 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/DataModelModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.scm._ 20 | 21 | import monix.execution.Scheduler.Implicits.global 22 | import monix.eval._ 23 | 24 | import scala.scalajs.js.annotation.JSExport 25 | 26 | @JSExportTopLevel("DataModelModel") 27 | object DataModelModel { 28 | 29 | var implementedDataModels:Vector[Cite2Urn] = Vector( 30 | // Defines a basic citable image model 31 | Cite2Urn("urn:cite2:cite:datamodels.v1:imagemodel"), 32 | // Defines an image that can be delivered as binary image data 33 | Cite2Urn("urn:cite2:cite:datamodels.v1:binaryimg"), 34 | // Defines a "codex model" of ordered text-bearing surfaces 35 | //Cite2Urn("urn:cite2:cite:datamodels.v1:tbsmodel"), 36 | // Defines a "documented scholarly editions" model of surface + image + text 37 | Cite2Urn("urn:cite2:cite:datamodels.v1:dsemodel"), 38 | // Defines a CITE Collection property of type `text` more precisely 39 | Cite2Urn("urn:cite2:cite:datamodels.v1:extensions_text") 40 | ) 41 | 42 | val dataModels = Var[Option[Vector[DataModel]]](None) 43 | 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/ExtendedTextPropertyView.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.scm._ 20 | 21 | import monix.execution.Scheduler.Implicits.global 22 | import monix.eval._ 23 | import com.karasiq.highlightjs.HighlightJS 24 | import com.karasiq.markedjs.{Marked, MarkedOptions, MarkedRenderer} 25 | import scala.scalajs.js.annotation.JSExport 26 | 27 | @JSExportTopLevel("ExtendedTextPropertyView") 28 | object ExtendedTextPropertyView { 29 | 30 | // Returns None, or the type of extension 31 | def textPropertyIsExtended(propUrn:Cite2Urn):Option[String] = { 32 | None 33 | } 34 | 35 | /* 36 | @dom 37 | def xxxxxxxextendedTextLinks(contextUrn:Option[Cite2Urn], p:ObjectModel.BoundCiteProperty) = { 38 | String Type:
{ 39 | val extendedOption:Option[String] = DataModelController.textPropertyIsExtended(p.urn.value) 40 | extendedOption match { 41 | case Some("markdown") => { 42 | initiateMarked(s"${p.propertyValue.bind}", s"propertyField_${p.urn.bind}") 43 | } 44 | case _ => { 45 | g.console.log(s"No extension.") 46 | } 47 | } 48 | } 49 |
50 | { s"${p.propertyValue.bind.toString}" } 51 |
52 | } 53 | */ 54 | 55 | @dom 56 | def extendedTextLinks(contextUrn:Option[Cite2Urn], p:ObjectModel.BoundCiteProperty) = { 57 | val extendedOption:Option[String] = DataModelController.textPropertyIsExtended(p.urn.value) 58 | extendedOption match { 59 | case Some("markdown") => { 60 | markdownTextContent(p).bind 61 | } 62 | case Some("teixml") => { 63 | teiTextContent(p).bind 64 | } 65 | case Some("pleiadesuri") => { 66 | pleiadesTextContent(p).bind 67 | } 68 | case Some("latlong") => { 69 | latLongTextContent(p).bind 70 | } 71 | case Some("geojson") => { 72 | geojsonTextContent(p).bind 73 | } 74 | case _ => { 75 | plainTextContent(p).bind 76 | } 77 | } 78 | } 79 | 80 | @dom 81 | def geojsonTextContent(p:ObjectModel.BoundCiteProperty) = { 82 | val geojson:String = p.propertyValue.bind.trim 83 | g.console.log(geojson) 84 | val elId:String = s"propertyField_${p.urn.bind}" 85 | initiateLeafletWithGeoJson(geojson, elId) 86 |
{ s"Leaflet.js map will be drawn here: ${p.propertyValue.bind.toString}" }
87 | } 88 | 89 | @dom 90 | def latLongTextContent(p:ObjectModel.BoundCiteProperty) = { 91 | val lat:String = p.propertyValue.bind.split(",")(0).trim 92 | val long:String = p.propertyValue.bind.split(",")(1).trim 93 | val elId:String = s"propertyField_${p.urn.bind}" 94 | initiateLeafletWithLatLong(lat, long, elId) 95 |
{ s"Leaflet.js map will be drawn here: ${p.propertyValue.bind.toString}" }
96 | } 97 | 98 | @dom 99 | def plainTextContent(p:ObjectModel.BoundCiteProperty) = { 100 | { s"${p.propertyValue.bind.toString}" } 101 | } 102 | 103 | @dom 104 | def markdownTextContent(p:ObjectModel.BoundCiteProperty) = { 105 | initiateMarked(s"${p.propertyValue.bind}", s"propertyField_${p.urn.bind}") 106 | 107 | { s"${p.propertyValue.bind.toString}" } 108 | 109 | } 110 | 111 | @dom 112 | def teiTextContent(p:ObjectModel.BoundCiteProperty) = { 113 | val thisSpan = document.createElement("span").asInstanceOf[HTMLSpanElement] 114 | thisSpan.innerHTML = p.propertyValue.bind 115 | thisSpan 116 | } 117 | 118 | @dom 119 | def pleiadesTextContent(p:ObjectModel.BoundCiteProperty) = { 120 | 121 | { "Pleiades place resource: "} 122 | 123 | { p.propertyValue.bind } 124 | 125 | 126 | } 127 | 128 | 129 | def getMarkdownProperyAndId(p:ObjectModel.BoundCiteProperty):Map[String,String] = { 130 | val propertyName:String = "" 131 | Map("id" -> "some id", "content" -> "some content.") 132 | } 133 | 134 | /* Methods for connecting out to Javascript */ 135 | @JSGlobal("initiateMarked") 136 | @js.native 137 | object initiateMarked extends js.Any { 138 | def apply(markdownString:String, elementId:String): js.Dynamic = js.native 139 | } 140 | 141 | @JSGlobal("initiateLeafletWithLatLong") 142 | @js.native 143 | object initiateLeafletWithLatLong extends js.Any { 144 | def apply(lat:String, long:String, elementId:String): js.Dynamic = js.native 145 | } 146 | 147 | @JSGlobal("initiateLeafletWithGeoJson") 148 | @js.native 149 | object initiateLeafletWithGeoJson extends js.Any { 150 | def apply(geojson:String, elementId:String): js.Dynamic = js.native 151 | } 152 | } -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/ImageRoiModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import scala.scalajs.js.Dynamic.{ global => g } 8 | import js.annotation._ 9 | import collection.mutable 10 | import collection.mutable._ 11 | import org.scalajs.dom._ 12 | import org.scalajs.dom.ext._ 13 | import org.scalajs.dom.raw._ 14 | import edu.holycross.shot.cite._ 15 | import edu.holycross.shot.ohco2._ 16 | import edu.holycross.shot.citeobj._ 17 | 18 | import scala.scalajs.js.annotation.JSExport 19 | import js.annotation._ 20 | 21 | /* 22 | Defines a model for Image ROIs, defined rectangles on citable images, associated with 23 | Cite and CTS Urns. 24 | */ 25 | 26 | @JSExportTopLevel("ImageRoiModel") 27 | object ImageRoiModel { 28 | 29 | case class ImageRoi(imageUrn:Cite2Urn, rois:Vars[Roi]) { 30 | override def toString = s"Image: ${imageUrn}. ${rois}" 31 | } 32 | 33 | case class Roi(val l:Float, t:Float, w:Float, h:Float, dataUrn:Option[Urn] = None, contextUrn:Option[Cite2Urn] = None ) { 34 | override def toString = s"left:${l}, top:${t}, width:${w}, height:${h} => ${dataUrn}" 35 | def toSubrefString:String = { 36 | s"${l},${t},${w},${h}" 37 | } 38 | } 39 | 40 | def roiFromUrn(u:Cite2Urn, data:Option[Urn] = None, context:Option[Cite2Urn] = None):Option[Roi] = { 41 | // in this case, there will be only one Roi object in the ImageRoi 42 | try { 43 | u.objectExtensionOption match { 44 | case Some(oe) => { 45 | val parts = oe.split(",") 46 | if (parts.size != 4) throw new Exception(s"${oe} did not contain four, comma-separated values.") 47 | val l:Float = parts(0).toFloat 48 | val t:Float = parts(1).toFloat 49 | val w:Float = parts(2).toFloat 50 | val h:Float = parts(3).toFloat 51 | if ( (l <0) | ( l > 1) ) throw new Exception(s"${l} must be > 0 and < 1.") 52 | if ( (t <0) | ( t > 1) ) throw new Exception(s"${t} must be > 0 and < 1.") 53 | if ( (w <0) | ( w > 1) ) throw new Exception(s"${w} must be > 0 and < 1.") 54 | if ( (h <0) | ( h > 1) ) throw new Exception(s"${h} must be > 0 and < 1.") 55 | // Got here and we're good 56 | val roi:Roi = Roi(l,t,w,h,data, context) 57 | Some(roi) 58 | } 59 | case None => None 60 | } 61 | } catch { 62 | case e:Exception => throw new Exception(s"Unable to make ROI from ${u}. ${e}") 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/NGModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import org.scalajs.dom._ 8 | import org.scalajs.dom.ext._ 9 | import org.scalajs.dom.raw._ 10 | import edu.holycross.shot.cite._ 11 | import edu.holycross.shot.ohco2._ 12 | import edu.holycross.shot.citeobj._ 13 | import scala.scalajs.js.Dynamic.{ global => g } 14 | 15 | import scala.scalajs.js.annotation.JSExport 16 | import js.annotation._ 17 | 18 | @JSExportTopLevel("NGModel") 19 | object NGModel { 20 | 21 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null 22 | 23 | var corpusOrUrn = Var[Option[CtsUrn]](None) 24 | 25 | val urn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage")) 26 | 27 | val shortWorkLabel = Var("default") 28 | 29 | val citedWorks = Vars.empty[CtsUrn] 30 | 31 | val userMessage = Var("") 32 | val userAlert = Var("default") 33 | val userMessageVisibility = Var("app_hidden") 34 | 35 | /* For recording queries */ 36 | 37 | class CtsQuery( urn:Option[CtsUrn]) { 38 | override def toString:String = { 39 | val s:String = s"Generic query on ${urn}." 40 | s 41 | } 42 | } 43 | 44 | case class NGramQuery(n:Integer, t:Integer, fs: String, ip: Boolean, urn:Option[CtsUrn] ) extends CtsQuery(urn){ 45 | // this.getClass.getName will yield 'citeapp.NGModel$NGramQuery' 46 | override def toString:String = { 47 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"} 48 | val s = s"""NGram Query: n=${n}; threshold = ${t}; ignore-punctuation=${ip}; filtered by "${fs}"; scope=${ scope }.""" 49 | s 50 | } 51 | 52 | } 53 | 54 | case class StringSearch(fs: String, urn:Option[CtsUrn] ) extends CtsQuery(urn) { 55 | override def toString:String = { 56 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"} 57 | val s = s"""String Search: "${fs}"; scope=${ scope }.""" 58 | s 59 | } 60 | 61 | } 62 | 63 | 64 | case class TokenSearch(tt: Vector[String], p:Integer, urn:Option[CtsUrn]) extends CtsQuery(urn){ 65 | override def toString:String = { 66 | val scope:String = urn match{ case Some(u) => u.toString; case _ => "whole corpus"} 67 | val s = s"""Token Search: "${tt.mkString(", ")}"; proximity=${p}; scope=${ scope }.""" 68 | s 69 | } 70 | } 71 | 72 | val pastQueries = Vars.empty[CtsQuery] 73 | 74 | /* for holding search results */ 75 | case class SearchResult(urn: Var[CtsUrn], kwic: Var[String]) 76 | val citationResults = Vars.empty[SearchResult] 77 | 78 | /* Values for NGrams */ 79 | val nGramThreshold = Var(3) 80 | 81 | val nGramResults = Vars.empty[StringCount] 82 | 83 | val nGramQueryReport = Var("") 84 | val otherQueryReport = Var("") 85 | 86 | /* Values for Search */ 87 | val tokenSearchProximity = Var(20) 88 | 89 | /* Some methods for working the model */ 90 | 91 | @dom 92 | def updateShortWorkLabel = { 93 | if ( O2Model.textRepo.value == None){ 94 | NGModel.shortWorkLabel.value = "- no selected text -" 95 | } else { 96 | val longS:String = O2Model.textRepo.value.get.catalog.label(NGModel.urn.value) 97 | if (longS.size > 50){ 98 | val shortS:String = longS.take(24) + " … " + longS.takeRight(23) 99 | NGModel.shortWorkLabel.value = shortS 100 | } else { 101 | NGModel.shortWorkLabel.value = longS 102 | } 103 | } 104 | } 105 | 106 | @dom 107 | def updateCitedWorks = { 108 | NGModel.citedWorks.value.clear 109 | NGController.clearResults 110 | NGController.clearInputs 111 | // N.b. The textRepository remains with the Ohco2 Model. 112 | for ( cw <- O2Model.textRepo.value.get.corpus.citedWorks){ 113 | NGModel.citedWorks.value += cw 114 | } 115 | } 116 | 117 | 118 | /* NGram Searching */ 119 | 120 | def getNGram(filterString: String, n: Int, occ: Int, ignorePunc: Boolean ): StringHistogram = { 121 | getNGram(O2Model.textRepo.value.get.corpus, filterString, n, occ, ignorePunc) 122 | } 123 | 124 | def getNGram(ngUrn: CtsUrn, filterString: String, n: Int, occ: Int, ignorePunc: Boolean): StringHistogram = { 125 | val newCorpus: Corpus = O2Model.textRepo.value.get.corpus ~~ ngUrn 126 | getNGram(newCorpus, filterString, n, occ, ignorePunc) 127 | } 128 | 129 | def getNGram(ngCorpus:Corpus, filterString: String, n: Int, occ: Int, ignorePunc: Boolean ): StringHistogram = { 130 | 131 | val hist:StringHistogram = { 132 | if( filterString == ""){ 133 | ngCorpus.ngramHisto(n, occ, ignorePunc) 134 | } else { 135 | ngCorpus.ngramHisto(filterString, n, occ , ignorePunc) 136 | } 137 | } 138 | hist 139 | } 140 | 141 | def getUrnsForNGram(s: String, ignorePunc: Boolean ): Vector[CtsUrn] ={ 142 | val vurn = O2Model.textRepo.value.get.corpus.urnsForNGram(s, 1, ignorePunc) 143 | vurn 144 | } 145 | 146 | def getUrnsForNGram(ngUrn: CtsUrn, s: String, ignorePunc: Boolean ): Vector[CtsUrn] ={ 147 | val newCorpus: Corpus = O2Model.textRepo.value.get.corpus >= ngUrn 148 | val vurn = newCorpus.urnsForNGram(s, 1, ignorePunc) 149 | vurn 150 | } 151 | 152 | def getUrnsForNGram(ngCorpus: Corpus, s: String, ignorePunc: Boolean ): Vector[CtsUrn] = { 153 | val vurn = ngCorpus.urnsForNGram(s, 1, ignorePunc) 154 | vurn 155 | } 156 | 157 | /* String and Token Finding */ 158 | def findString(urn:CtsUrn, s:String):Corpus = { 159 | val tempCorpus = O2Model.textRepo.value.get.corpus >= urn 160 | val foundCorpus = tempCorpus.find(s) 161 | foundCorpus 162 | } 163 | 164 | def findString(s:String):Corpus = { 165 | val foundCorpus = O2Model.textRepo.value.get.corpus.find(s) 166 | foundCorpus 167 | } 168 | 169 | 170 | 171 | 172 | } 173 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/O2Controller.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import org.scalajs.dom._ 8 | import org.scalajs.dom.ext._ 9 | import org.scalajs.dom.raw._ 10 | import edu.holycross.shot.cite._ 11 | import edu.holycross.shot.ohco2._ 12 | import edu.holycross.shot.citeobj._ 13 | import scala.concurrent._ 14 | import scala.scalajs.js.Dynamic.{ global => g } 15 | //import ExecutionContext.Implicits.global 16 | import monix.execution.Scheduler.Implicits.global 17 | import monix.eval._ 18 | 19 | import scala.scalajs.js.annotation.JSExport 20 | import js.annotation._ 21 | 22 | @JSExportTopLevel("O2Controller") 23 | object O2Controller { 24 | 25 | 26 | val validUrnInField = Var(false) 27 | 28 | 29 | /* A lot of work gets done here */ 30 | def changePassage: Unit = { 31 | val timeStart = new js.Date().getTime() 32 | val newUrn: CtsUrn = O2Model.urn.value 33 | O2Model.updateUrnHistory(newUrn) 34 | val task1 = Task{ 35 | O2Model.versionsForCurrentUrn.value = O2Model.versionsForUrn(newUrn) 36 | O2Model.displayPassage(newUrn) 37 | val timeEnd = new js.Date().getTime() 38 | O2Controller.updateUserMessage(s"Fetched ${O2Model.currentNumberOfCitableNodes.value} citation objects in ${(timeEnd - timeStart)/1000} seconds.",0) 39 | } 40 | val future1 = task1.runAsync 41 | val task2 = Task{ O2Model.getPrevNextUrn(O2Model.urn.value) } 42 | val future2 = task2.runAsync 43 | } 44 | 45 | 46 | def updateUserMessage(msg: String, alert: Int): Unit = { 47 | O2Model.userMessageVisibility.value = "app_visible" 48 | O2Model.userMessage.value = msg 49 | alert match { 50 | case 0 => O2Model.userAlert.value = "default" 51 | case 1 => O2Model.userAlert.value = "wait" 52 | case 2 => O2Model.userAlert.value = "warn" 53 | } 54 | js.timers.clearTimeout(O2Model.msgTimer) 55 | O2Model.msgTimer = js.timers.setTimeout(6000){ O2Model.userMessageVisibility.value = "app_hidden" } 56 | } 57 | 58 | 59 | def validateUrn(urnString: String): Unit = { 60 | try{ 61 | val newUrn: CtsUrn = CtsUrn(urnString) 62 | validUrnInField.value = true 63 | } catch { 64 | case e: Exception => { 65 | validUrnInField.value = false 66 | } 67 | } 68 | } 69 | 70 | def getNext:Unit = { 71 | if (O2Model.currentNext.value != None){ 72 | changeUrn(O2Model.currentNext.value.get) 73 | } 74 | } 75 | 76 | def getPrev:Unit = { 77 | if (O2Model.currentPrev.value != None){ 78 | changeUrn(O2Model.currentPrev.value.get) 79 | } 80 | } 81 | 82 | def changeUrn(urnString: String): Unit = { 83 | changeUrn(CtsUrn(urnString)) 84 | } 85 | 86 | 87 | def changeUrn(urn: CtsUrn): Unit = { 88 | try { 89 | O2Model.urn.value = urn 90 | O2Model.displayUrn.value = urn 91 | validUrnInField.value = true 92 | O2Controller.updateUserMessage("Retrieving passage…",1) 93 | val task = Task{ O2Controller.changePassage } 94 | val future = task.runAsync 95 | /* 96 | js.timers.setTimeout(200){ 97 | Future{ 98 | O2Controller.changePassage 99 | } 100 | } 101 | */ 102 | 103 | } catch { 104 | case e: Exception => { 105 | validUrnInField.value = false 106 | updateUserMessage("Invalid URN. Current URN not changed.",2) 107 | } 108 | } 109 | } 110 | 111 | 112 | def insertFirstNodeUrn(urn: CtsUrn): Unit = { 113 | val firstUrn = O2Model.textRepo.value.get.corpus.firstNode(urn).urn 114 | js.Dynamic.global.document.getElementById("o2_urnInput").value = firstUrn.toString 115 | validUrnInField.value = true 116 | } 117 | 118 | 119 | @dom 120 | def preloadUrn = { 121 | O2Model.urn.value = O2Model.textRepo.value.get.corpus.firstNode(O2Model.textRepo.value.get.corpus.citedWorks(0)).urn 122 | O2Controller.validUrnInField.value = true 123 | } 124 | 125 | 126 | } 127 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/O2Model.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import scala.scalajs.js.Dynamic.{ global => g } 8 | import scala.collection.mutable.LinkedHashMap 9 | import org.scalajs.dom._ 10 | import org.scalajs.dom.ext._ 11 | import org.scalajs.dom.raw._ 12 | import edu.holycross.shot.cite._ 13 | import edu.holycross.shot.ohco2._ 14 | import edu.holycross.shot.citeobj._ 15 | import scala.collection.immutable.SortedMap 16 | 17 | import scala.scalajs.js.annotation.JSExport 18 | import js.annotation._ 19 | 20 | @JSExportTopLevel("O2Model") 21 | object O2Model { 22 | 23 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null 24 | 25 | case class VersionNodeBlock(versionUrn:Var[CtsUrn],nodes:Vars[CitableNode]) 26 | 27 | case class BoundCorpus(versionUrn:Var[CtsUrn], versionLabel:Var[String], versionNodes:Vars[VersionNodeBlock] ) 28 | 29 | val currentCorpus = Vars.empty[BoundCorpus] 30 | 31 | val currentNumberOfCitableNodes = Var(0) 32 | val currentListOfUrns = Vars.empty[CtsUrn] 33 | val isRtlPassage = Var(false) 34 | 35 | // for navigation 36 | val urnHistory = Vars.empty[(Int,CtsUrn,String)] 37 | 38 | 39 | // Add an entry to the citation-history 40 | def updateUrnHistory(u:CtsUrn):Unit = { 41 | try { 42 | if (textRepo.value != None) { 43 | 44 | val tempList:List[Tuple2[CtsUrn,String]] = urnHistory.value.toList.reverse.map(t => { Tuple2(t._2, t._3)}) 45 | val newTempList:List[Tuple2[CtsUrn,String]] = tempList ++ List(Tuple2(u,textRepo.value.get.label(u))) 46 | val indexedTempList:List[Tuple3[Int,CtsUrn,String]] = newTempList.zipWithIndex.map( t => { 47 | Tuple3((t._2 + 1),t._1._1,t._1._2) 48 | }) 49 | val reversedList = indexedTempList.reverse 50 | urnHistory.value.clear 51 | for (t <- reversedList) { urnHistory.value += t } 52 | } 53 | } catch{ 54 | case e:Exception => O2Controller.updateUserMessage(s"Unable to make label for ${u}: ${e}",2) 55 | } 56 | } 57 | 58 | 59 | // urn is what the user requested 60 | val urn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage")) 61 | // displayUrn is what will be shown 62 | val displayUrn = Var(CtsUrn("urn:cts:ns:group.work.version.exemplar:passage")) 63 | val versionsForCurrentUrn = Var(1) 64 | 65 | val userMessage = Var("") 66 | val userAlert = Var("default") 67 | val userMessageVisibility = Var("app_hidden") 68 | 69 | val textRepo = Var[Option[TextRepository]](None) 70 | val citedWorks = Vars.empty[CtsUrn] 71 | 72 | val currentNext = Var[Option[CtsUrn]](None) 73 | val currentPrev = Var[Option[CtsUrn]](None) 74 | 75 | 76 | /* Some methods for working the model */ 77 | def versionsForUrn(urn:CtsUrn):Int = { 78 | var versions = 0 79 | if (O2Model.textRepo.value != None){ 80 | val s = s"urn:cts:${urn.namespace}:${urn.textGroup}.${urn.work}:" 81 | val versionVector = O2Model.textRepo.value.get.catalog.entriesForUrn(CtsUrn(s)) 82 | versions = versionVector.size 83 | } 84 | versions 85 | } 86 | 87 | def getPrevNextUrn(urn:CtsUrn):Unit = { 88 | O2Model.currentPrev.value = O2Model.textRepo.value.get.corpus.prevUrn(urn) 89 | O2Model.currentNext.value = O2Model.textRepo.value.get.corpus.nextUrn(urn) 90 | } 91 | 92 | def collapseToWorkUrn(urn:CtsUrn):CtsUrn = { 93 | val s = { 94 | s"urn:cts:${urn.namespace}:${urn.textGroup}.${urn.work}:${urn.passageComponent}" 95 | } 96 | val u = CtsUrn(s) 97 | u 98 | } 99 | 100 | def updateCurrentListOfUrns(c:Corpus):Unit = { 101 | O2Model.currentListOfUrns.value.clear 102 | for (n <- c.nodes){ 103 | O2Model.currentListOfUrns.value += n.urn 104 | } 105 | } 106 | 107 | 108 | // case class BoundCorpus(versionUrn:Var[CtsUrn], versionLabel:Var[String], nodes:Vars[CitableNode] ) 109 | // val currentCorpus = Vars.empty[BoundCorpus] 110 | 111 | def updateCurrentCorpus(c:Corpus, u:CtsUrn):Unit = { 112 | try { 113 | O2Model.currentCorpus.value.clear 114 | if (O2Model.textRepo.value != None) { 115 | // Since GroupBy doesn't preserve order, let's preserve our own order 116 | val versionLevelOrder:Vector[CtsUrn] = { 117 | c.urns.map(u => dropOneLevel(u)).distinct.toVector 118 | } 119 | // Get Corpus into a Vector of tuples: (version-level-urn, vector[CitableNode]) 120 | val tempCorpusVector:Vector[(CtsUrn, Vector[CitableNode])] = c.nodes.groupBy(_.urn.dropPassage).toVector 121 | // in correct order to this point 122 | for (tc <- tempCorpusVector) { 123 | val versionLabel:String = O2Model.textRepo.value.get.catalog.label(tc._1) 124 | val passageString:String = { 125 | u.passageComponent 126 | } 127 | // in correct order to this point 128 | val boundVersionLabel = Var(versionLabel) 129 | 130 | val versionUrn:CtsUrn = CtsUrn(s"${tc._1}${passageString}") 131 | val boundVersionUrn = Var(versionUrn) 132 | 133 | // Group node urns according to nodeBlocks 134 | val nodeBlocks:Vector[(CtsUrn, Vector[CitableNode])] = { 135 | tc._1.exemplarOption match { 136 | case Some(eo) => { 137 | val block:Vector[(CtsUrn,Vector[CitableNode])] = { 138 | tc._2.groupBy(n => dropOneLevel(n.urn)).toVector 139 | } 140 | val block2 = tc._2.zipWithIndex.groupBy(n => dropOneLevel(n._1.urn)) 141 | val lhm = LinkedHashMap(block2.toSeq sortBy (_._2.head._2): _*) 142 | val block3 = lhm mapValues (_ map (_._1)) 143 | val sortedBlock = block3.toVector 144 | sortedBlock 145 | } 146 | case None => { 147 | Vector( (tc._1,tc._2) ) 148 | } 149 | } 150 | } 151 | // Get this nodeBlock into a versionNodeBlock 152 | val tempNodeBlockVec = Vars.empty[VersionNodeBlock] 153 | for (b <- nodeBlocks){ 154 | val tempBlockUrn = Var(b._1) 155 | val tempNodesVec = Vars.empty[CitableNode] 156 | for (n <- b._2) tempNodesVec.value += n 157 | tempNodeBlockVec.value += VersionNodeBlock(tempBlockUrn, tempNodesVec) 158 | } 159 | 160 | /* 161 | val tempNodesBindingVector = Vars.empty[CitableNode] 162 | for (n <- tc._2) { 163 | tempNodesBindingVector.value += n 164 | } 165 | */ 166 | O2Model.currentCorpus.value += BoundCorpus(boundVersionUrn, boundVersionLabel, tempNodeBlockVec) 167 | } 168 | } 169 | 170 | } catch { 171 | case e:Exception => { 172 | O2Controller.updateUserMessage(s"O2Model Exception in 'updateCurrentCorpus': ${e}",2) 173 | } 174 | } 175 | } 176 | 177 | def dropOneLevel(u:CtsUrn):CtsUrn = { 178 | try { 179 | val passage:String = u.passageComponent 180 | val plainUrn:String = u.dropPassage.toString 181 | val newPassage:String = passage.split('.').dropRight(1).mkString(".") 182 | val droppedUrn:CtsUrn = CtsUrn(s"${plainUrn}${newPassage}") 183 | droppedUrn 184 | } catch { 185 | case e:Exception => { 186 | O2Controller.updateUserMessage(s"Error dropping one level from ${u}: ${e}",2) 187 | throw new Exception(s"${e}") 188 | } 189 | } 190 | } 191 | 192 | 193 | def displayNewPassage(urn:CtsUrn):Unit = { 194 | O2Model.displayPassage(urn) 195 | } 196 | 197 | @dom 198 | def clearPassage:Unit = { 199 | //O2Model.xmlPassage.innerHTML = "" 200 | O2Model.versionsForCurrentUrn.value = 0 201 | O2Model.currentListOfUrns.value.clear 202 | DSEModel.currentListOfDseUrns.value.clear 203 | O2Model.currentCorpus.value.clear 204 | } 205 | 206 | def passageLevel(u:CtsUrn):Int = { 207 | try { 208 | val urn = u.dropSubref 209 | if (urn.isRange) throw new Exception(s"Cannot report passage level for ${urn} becfause it is a range.") 210 | urn.passageComponent.size match { 211 | case n if (n > 0) => { 212 | urn.passageComponent.split('.').size 213 | } 214 | case _ => throw new Exception(s"Cannot report passage level for ${urn} because it does not have a passage component.") 215 | } 216 | } catch { 217 | case e:Exception => throw new Exception(s"${e}") 218 | } 219 | } 220 | 221 | def valueForLevel(u:CtsUrn,level:Int):String = { 222 | try { 223 | val urn = u.dropSubref 224 | val pl:Int = passageLevel(urn) 225 | if (pl < level) throw new Exception(s"${u} has a ${pl}-deep citation level, which is less than ${level}.") 226 | urn.passageComponent.size match { 227 | case n if (n > 0) => { 228 | urn.passageComponent.split('.')(level-1) 229 | } 230 | case _ => throw new Exception(s"Cannot report passage level for ${u} because it does not have a passage component.") 231 | } 232 | } catch { 233 | case e:Exception => throw new Exception(s"${e}") 234 | } 235 | } 236 | 237 | @dom 238 | def displayPassage(newUrn: CtsUrn):Unit = { 239 | val tempCorpus: Corpus = O2Model.textRepo.value.get.corpus >= newUrn 240 | O2Model.updateCurrentListOfUrns(tempCorpus) 241 | DSEModel.updateCurrentListOfDseUrns(tempCorpus) 242 | CommentaryModel.updateCurrentListOfComments(tempCorpus) 243 | O2Model.updateCurrentCorpus(tempCorpus, newUrn) 244 | O2Model.currentNumberOfCitableNodes.value = tempCorpus.size 245 | } 246 | 247 | 248 | 249 | def checkForRTL(s:String):Boolean = { 250 | val sStart = s.take(10) 251 | val arabicBlock = "[\u0600-\u06FF]".r 252 | val hebrewBlock = "[\u0591-\u05F4]".r 253 | var isRtl:Boolean = ((arabicBlock findAllIn sStart).nonEmpty || (hebrewBlock findAllIn sStart).nonEmpty) 254 | isRtl 255 | } 256 | 257 | 258 | 259 | @dom 260 | def updateCitedWorks = { 261 | O2Model.citedWorks.value.clear 262 | for ( cw <- O2Model.textRepo.value.get.corpus.citedWorks){ 263 | O2Model.citedWorks.value += cw 264 | } 265 | } 266 | 267 | 268 | } 269 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/QueryObjectModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import scala.scalajs.js.Dynamic.{ global => g } 8 | import js.annotation._ 9 | import collection.mutable 10 | import collection.mutable._ 11 | import org.scalajs.dom._ 12 | import org.scalajs.dom.ext._ 13 | import org.scalajs.dom.raw._ 14 | import edu.holycross.shot.cite._ 15 | import edu.holycross.shot.ohco2._ 16 | import edu.holycross.shot.citeobj._ 17 | 18 | import scala.scalajs.js.annotation.JSExport 19 | import js.annotation._ 20 | 21 | @JSExportTopLevel("QueryObjectModel") 22 | object QueryObjectModel { 23 | 24 | val pastQueries = Vars.empty[CiteCollectionQuery] 25 | val currentQuery = Var[Option[CiteCollectionQuery]](None) 26 | val isValidSearch = Var(false) 27 | 28 | val currentQueryCollection = Var[Option[Cite2Urn]](None) 29 | val currentQueryCollectionProps = Vars.empty[CitePropertyDef] 30 | val queryProperty = Var[Option[CitePropertyDef]](None) 31 | val selectedPropertyType = Var[Option[CitePropertyType]](Some(StringType)) 32 | val currentControlledVocabulary = Vars.empty[String] 33 | val currentControlledVocabItem = Var[Option[String]](None) 34 | val currentSearchString = Var[Option[String]](None) 35 | val currentRegexState = Var(false) 36 | val currentCaseSensitiveState = Var(false) 37 | 38 | val currentNumericQuery1 = Var[Option[BigDecimal]](None) 39 | val currentNumericQuery2 = Var[Option[BigDecimal]](None) 40 | val currentNumericOperator = Var("eq") 41 | 42 | val currentBooleanVal = Var(true) 43 | 44 | val currentCtsUrnQuery = Var[Option[CtsUrn]](None) 45 | val currentCite2UrnQuery = Var[Option[Cite2Urn]](None) 46 | 47 | def clearAll = { 48 | currentQuery.value = None 49 | isValidSearch.value = false 50 | currentQueryCollectionProps.value.clear 51 | queryProperty.value = None 52 | selectedPropertyType.value = Some(StringType) 53 | currentControlledVocabulary.value.clear 54 | currentControlledVocabItem.value = None 55 | currentSearchString.value = None 56 | currentRegexState.value = false 57 | currentCaseSensitiveState.value = false 58 | currentNumericQuery1.value = None 59 | currentNumericQuery2.value = None 60 | currentBooleanVal.value = true 61 | currentCtsUrnQuery.value = None 62 | currentCite2UrnQuery.value = None 63 | } 64 | 65 | case class CiteCollectionQuery( 66 | val qCollection: Option[Cite2Urn], 67 | val qProperty: Option[CitePropertyDef] = None , 68 | val qPropertyType: Option[CitePropertyType], 69 | val qControlledVocabItem: Option[String] = None, 70 | val qSearchString: Option[String] = None, 71 | val qRegex:Option[Boolean] = None, 72 | val qCaseSensitive: Option[Boolean] = None, 73 | val qNum1: Option[BigDecimal] = None, 74 | val qNum2: Option[BigDecimal] = None, 75 | val qNumOperator: Option[String] = None, 76 | val qBoolVal: Option[Boolean] = None, 77 | val qCtsUrn: Option[CtsUrn] = None, 78 | val qCite2Urn: Option[Cite2Urn] = None 79 | ) { 80 | 81 | var numResults:Int = 0 82 | 83 | override def toString:String = { 84 | var qds:String = "" 85 | qCollection match { 86 | case Some(x) => qds += s"${x.toString} :" 87 | case None => qds += s"All collections. " 88 | } 89 | qProperty match { 90 | case Some(x) => qds += s"Property: ${x.label}. " 91 | case _ => qds += s"All properties. " 92 | } 93 | qPropertyType match { 94 | case Some(x) => qds += s"${x}. " 95 | case _ => qds += s"No property type. " 96 | } 97 | qSearchString match { 98 | case Some(x) => { 99 | qds += s"Search for “${x}”. " 100 | qCaseSensitive match { 101 | case Some(true) => qds += s"Case sensitive. " 102 | case _ => qds += "" 103 | } 104 | qRegex match { 105 | case Some(true) => qds += s"With Regex. " 106 | case _ => qds += "" 107 | } 108 | } 109 | case _ => qds += "" 110 | } 111 | qControlledVocabItem match { 112 | case Some(x) => qds += s"Search for Controlled Vocabulary Item “${x}”. " 113 | case _ => qds += "" 114 | } 115 | qBoolVal match { 116 | case Some(x) => qds += s"Search for Boolean value [${x}]. " 117 | case _ => qds += "" 118 | } 119 | qCtsUrn match { 120 | case Some(x) => qds += s"Search for Cts Urn ${x}. " 121 | case _ => qds += "" 122 | } 123 | qCite2Urn match { 124 | case Some(x) => qds += s"Search for Cite2 Urn ${x}. " 125 | case _ => qds += "" 126 | } 127 | qNumOperator match { 128 | case Some(x) => { 129 | x match { 130 | case "inRange" => qds += s"Search for value in range ${qNum1.get}–${qNum2.get}. " 131 | case "eq" => qds += s"Search for value = ${qNum1.get}. " 132 | case "gt" => qds += s"Search for value > ${qNum1.get}. " 133 | case "lt" => qds += s"Search for value < ${qNum1.get}. " 134 | case "gteq" => qds += s"Search for value >= ${qNum1.get}. " 135 | case "lteq" => qds += s"Search for value <= ${qNum1.get}. " 136 | } 137 | } 138 | case _ => qds += "" 139 | } 140 | qds += s" (${numResults} Objects)" 141 | qds 142 | } 143 | } 144 | 145 | 146 | def validateNumericEntry(thisEvent: Event):Unit = { 147 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement] 148 | val testText = thisTarget.value.toString 149 | var previousEntry:Option[BigDecimal] = None 150 | thisTarget.id match { 151 | case "queryObject_numeric1" => previousEntry = currentNumericQuery1.value 152 | case "queryObject_numeric2" => previousEntry = currentNumericQuery2.value 153 | case _ => previousEntry = None 154 | } 155 | try{ 156 | val mo:BigDecimal = testText.toDouble 157 | thisTarget.id match { 158 | case "queryObject_numeric1" => currentNumericQuery1.value = Some(mo) 159 | case "queryObject_numeric2" => currentNumericQuery2.value = Some(mo) 160 | } 161 | } catch { 162 | case e: Exception => { 163 | val badMo: String = testText 164 | thisTarget.value = "" 165 | ObjectController.updateUserMessage(s""" "${badMo}" is not a numeric value.""", 2) 166 | } 167 | } 168 | } 169 | 170 | def validateCtsUrnEntry(thisEvent: Event):Unit = { 171 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement] 172 | val testText = thisTarget.value.toString 173 | try{ 174 | val testCts:CtsUrn = CtsUrn(testText) 175 | currentCtsUrnQuery.value = Some(testCts) 176 | } catch { 177 | case e: Exception => { 178 | val badMo: String = testText 179 | thisTarget.value = "" 180 | ObjectController.updateUserMessage(s"${badMo} is not a valid CTS URN.", 2) 181 | } 182 | } 183 | } 184 | 185 | def validateCite2UrnEntry(thisEvent: Event):Unit = { 186 | val thisTarget = thisEvent.target.asInstanceOf[org.scalajs.dom.raw.HTMLInputElement] 187 | val testText = thisTarget.value.toString 188 | try{ 189 | val testCite2:Cite2Urn = Cite2Urn(testText) 190 | currentCite2UrnQuery.value = Some(testCite2) 191 | } catch { 192 | case e: Exception => { 193 | val badMo: String = testText 194 | thisTarget.value = "" 195 | ObjectController.updateUserMessage(s"${badMo} is not a valid CITE2 URN.", 2) 196 | } 197 | } 198 | } 199 | 200 | /* Based on whether we're set up to query all properties or a single one, 201 | load controlled vocabulary into a binding Vars */ 202 | @dom 203 | def loadControlledVocabulary = { 204 | QueryObjectModel.currentQueryCollection.value match { 205 | case None => loadControlledVocablAll 206 | case _ => loadControlledVocablOne 207 | } 208 | } 209 | 210 | @dom 211 | def loadControlledVocablAll = { 212 | QueryObjectModel.currentControlledVocabulary.value.clear 213 | var vList = new ListBuffer[String] 214 | for (c <- ObjectModel.collections.value ){ 215 | for (p <- c.propertyDefs){ 216 | for (v <- p.vocabularyList) 217 | vList += v 218 | } 219 | } 220 | val vSet = vList.toSet 221 | for (vs <- vSet ){ 222 | QueryObjectModel.currentControlledVocabulary.value += vs 223 | } 224 | if (vSet.size > 0){ 225 | QueryObjectModel.currentControlledVocabItem.value = Some(vSet.head) 226 | } 227 | 228 | 229 | } 230 | 231 | @dom 232 | def loadControlledVocablOne = { 233 | QueryObjectModel.queryProperty.bind match { 234 | case None => { 235 | QueryObjectModel.currentControlledVocabulary.value.clear 236 | for (p <- QueryObjectModel.currentQueryCollectionProps.value){ 237 | if (p.propertyType == ControlledVocabType){ 238 | for (v <- p.vocabularyList){ 239 | QueryObjectModel.currentControlledVocabulary.value += v 240 | } 241 | } 242 | } 243 | if (QueryObjectModel.currentControlledVocabulary.value.size > 0){ 244 | QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.value.head) 245 | } 246 | } 247 | case _ => { 248 | QueryObjectModel.currentControlledVocabulary.value.clear 249 | for (v <- QueryObjectModel.queryProperty.value.get.vocabularyList){ 250 | QueryObjectModel.currentControlledVocabulary.value += v 251 | } 252 | QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.value.head) 253 | } 254 | } 255 | //QueryObjectModel.currentControlledVocabItem.value = Some(QueryObjectModel.currentControlledVocabulary.get.head) 256 | } 257 | 258 | 259 | 260 | } 261 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/RelationsController.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.citerelation._ 20 | import edu.holycross.shot.scm._ 21 | 22 | import monix.execution.Scheduler.Implicits.global 23 | import monix.eval._ 24 | 25 | import scala.scalajs.js.annotation.JSExport 26 | 27 | @JSExportTopLevel("RelationsController") 28 | object RelationsController { 29 | 30 | 31 | val validUrnInField = Var(false) 32 | 33 | def updateUserMessage(msg: String, alert: Int): Unit = { 34 | NGModel.userMessageVisibility.value = "app_visible" 35 | NGModel.userMessage.value = msg 36 | alert match { 37 | case 0 => RelationsModel.userAlert.value = "default" 38 | case 1 => RelationsModel.userAlert.value = "wait" 39 | case 2 => RelationsModel.userAlert.value = "warn" 40 | } 41 | js.timers.clearTimeout(RelationsModel.msgTimer) 42 | RelationsModel.msgTimer = js.timers.setTimeout(6000){ RelationsModel.userMessageVisibility.value = "app_hidden" } 43 | } 44 | 45 | def validateUrn(urnString: String): Unit = { 46 | try{ 47 | urnString.take(8) match { 48 | case "urn:cts:" => { 49 | val newUrn:CtsUrn = CtsUrn(urnString) 50 | validUrnInField.value = true 51 | } 52 | case _ => { 53 | urnString.take(10) match { 54 | case "urn:cite2:" => { 55 | val newUrn:Cite2Urn = Cite2Urn(urnString) 56 | validUrnInField.value = true 57 | } 58 | } 59 | } 60 | } 61 | } catch { 62 | case e: Exception => { 63 | validUrnInField.value = false 64 | } 65 | } 66 | } 67 | 68 | def changeUrn(urnString:String):Unit = { 69 | val u:Option[Urn] = { 70 | urnString.take(8) match { 71 | case "urn:cts:" => { 72 | val newUrn:CtsUrn = CtsUrn(urnString) 73 | Some(newUrn) 74 | } 75 | case _ => { 76 | urnString.take(10) match { 77 | case "urn:cite2:" => { 78 | val newUrn:Cite2Urn = Cite2Urn(urnString) 79 | Some(newUrn) 80 | } 81 | case _ => { None } 82 | } 83 | } 84 | } 85 | } 86 | RelationsModel.urn.value = u 87 | findRelations 88 | } 89 | 90 | def changeUrn(urn:Urn):Unit = { 91 | RelationsModel.urn.value = Some(urn) 92 | findRelations 93 | } 94 | 95 | def findRelations(hi:RelationsModel.HistoryItem):Unit = { 96 | RelationsModel.urn.value = Some(hi.search) 97 | RelationsModel.filterVerb.value = hi.filter 98 | RelationsController.findRelations 99 | } 100 | 101 | def findRelations:Unit = { 102 | if ((RelationsModel.urn.value != None) && (RelationsModel.citeRelations.value != None)) { 103 | 104 | val foundRelations:CiteRelationSet = { 105 | RelationsModel.filterVerb.value match { 106 | case Some(fv) => { 107 | val historyItem:RelationsModel.HistoryItem = RelationsModel.HistoryItem(RelationsModel.urn.value.get, Some(fv)) 108 | RelationsModel.updateHistory(historyItem) 109 | RelationsModel.citeRelations.value.get.verb(fv) ~~ RelationsModel.urn.value.get 110 | } 111 | case _ => { 112 | val historyItem:RelationsModel.HistoryItem = RelationsModel.HistoryItem(RelationsModel.urn.value.get, None ) 113 | RelationsModel.updateHistory(historyItem) 114 | RelationsModel.citeRelations.value.get ~~ RelationsModel.urn.value.get 115 | } 116 | } 117 | 118 | } 119 | //g.console.log(s"found: ${foundRelations.size} out of ${RelationsModel.citeRelations.value.get.size} for ${RelationsModel.urn.value}") 120 | // Let's sort by subject URN 121 | val sortedRelations:Vector[CiteTriple] = foundRelations.relations.toVector.sortBy(_.urn1.toString) 122 | RelationsModel.foundRelations.value.clear 123 | for (r <- sortedRelations) { 124 | RelationsModel.foundRelations.value += r 125 | } 126 | 127 | } 128 | } 129 | 130 | def setFilterVerb(s:String):Unit = { 131 | try { 132 | val u:Option[Cite2Urn] = { 133 | s.take(10) match { 134 | case "urn:cite2:" => Some(Cite2Urn(s)) 135 | case _ => None 136 | } 137 | } 138 | RelationsModel.filterVerb.value = u 139 | findRelations 140 | } catch { 141 | case e:Exception => { 142 | RelationsController.updateUserMessage(s"Relations-tab: Unaccountably, something went wrong with the value of the Filter by Relation popup. Could not turn ${s} into a URN: ${e}",2) 143 | } 144 | } 145 | } 146 | 147 | } 148 | -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/RelationsModel.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.citerelation._ 20 | import edu.holycross.shot.scm._ 21 | 22 | import monix.execution.Scheduler.Implicits.global 23 | import monix.eval._ 24 | 25 | import scala.scalajs.js.annotation.JSExport 26 | 27 | @JSExportTopLevel("RelationsModel") 28 | object RelationsModel { 29 | val citeRelations = Var[Option[CiteRelationSet]](None) 30 | val foundRelations = Vars.empty[CiteTriple] 31 | 32 | val allVerbs = Vars.empty[(Cite2Urn,String)] 33 | 34 | val urn = Var[Option[Urn]](None) 35 | val inputBoxUrnStr = Var("") 36 | val filterVerb = Var[Option[Cite2Urn]](None) 37 | val userMessageVisibility = Var("app_hidden") 38 | var msgTimer:scala.scalajs.js.timers.SetTimeoutHandle = null 39 | val userMessage = Var("") 40 | val userAlert = Var("default") 41 | 42 | case class HistoryItem(search:Urn, filter:Option[Cite2Urn]) { 43 | override def toString:String = { 44 | filter match { 45 | case Some(f) => s"${search} filtered by “${f.objectComponent}”." 46 | case None => s"${search}." 47 | } 48 | } 49 | } 50 | val searchHistory = Vars.empty[HistoryItem] 51 | 52 | def clearRelations:Unit = { 53 | urn.value = None 54 | filterVerb.value = None 55 | inputBoxUrnStr.value = "" 56 | foundRelations.value.clear 57 | } 58 | 59 | def updateHistory(hi:HistoryItem):Unit = { 60 | val oldHistory:Vector[HistoryItem] = { 61 | searchHistory.value.map(s => { 62 | s 63 | }).toVector 64 | 65 | } 66 | val newHistory:Vector[HistoryItem] = Vector(hi) ++ oldHistory 67 | searchHistory.value.clear 68 | for (i <- newHistory){ 69 | searchHistory.value += i 70 | } 71 | } 72 | 73 | def getVerbLabel(u:Cite2Urn):String = { 74 | val label:String = ObjectModel.collRep.value match { 75 | case None => { 76 | val label:String = { 77 | u.objectOption match { 78 | case Some(o) => o 79 | case None => "< nothing specified >" 80 | } 81 | } 82 | label 83 | } 84 | case Some(cr) => { 85 | val label:String = { 86 | (cr ~~ u) match { 87 | case objVec if (objVec.size > 0) => { 88 | objVec(0).label 89 | } 90 | case _ => { 91 | u.objectOption match { 92 | case Some(o) => o 93 | case None => "< nothing specified >" 94 | } 95 | } 96 | } 97 | } 98 | label 99 | } 100 | } 101 | label 102 | } 103 | 104 | 105 | def loadAllVerbs:Unit = { 106 | citeRelations.value match { 107 | case None => allVerbs.value.clear 108 | case Some(crs) => { 109 | val verbs:Vector[Cite2Urn] = { 110 | crs.relations.map( _.relation ).toVector.distinct 111 | } 112 | val verbPairs:Vector[(Cite2Urn, String)] = { 113 | ObjectModel.collRep.value match { 114 | case None => { 115 | verbs.map( v => { 116 | val label:String = { 117 | v.objectOption match { 118 | case Some(o) => o 119 | case None => "< nothing specified >" 120 | } 121 | } 122 | (v, label) 123 | }).toVector 124 | } 125 | case Some(cr) => { 126 | verbs.map( v => { 127 | val label:String = { 128 | (cr ~~ v) match { 129 | case objVec if (objVec.size > 0) => { 130 | objVec(0).label 131 | } 132 | case _ => { 133 | v.objectOption match { 134 | case Some(o) => o 135 | case None => "< nothing specified >" 136 | } 137 | } 138 | } 139 | } 140 | (v, label) 141 | }).toVector 142 | } 143 | } 144 | } 145 | allVerbs.value.clear 146 | for (vp <- verbPairs) { 147 | allVerbs.value += vp 148 | } 149 | } 150 | } 151 | } 152 | } -------------------------------------------------------------------------------- /src/main/scala/citeappscalajs/RelationsView.scala: -------------------------------------------------------------------------------- 1 | package citeapp 2 | 3 | import com.thoughtworks.binding.{Binding, dom} 4 | import com.thoughtworks.binding.Binding.{BindingSeq, Var, Vars} 5 | import scala.scalajs.js 6 | import scala.scalajs.js._ 7 | import js.annotation._ 8 | import scala.concurrent._ 9 | //import ExecutionContext.Implicits.global 10 | import collection.mutable 11 | import collection.mutable._ 12 | import scala.scalajs.js.Dynamic.{ global => g } 13 | import org.scalajs.dom._ 14 | import org.scalajs.dom.ext._ 15 | import org.scalajs.dom.raw._ 16 | import edu.holycross.shot.cite._ 17 | import edu.holycross.shot.ohco2._ 18 | import edu.holycross.shot.citeobj._ 19 | import edu.holycross.shot.citerelation._ 20 | import edu.holycross.shot.scm._ 21 | 22 | import monix.execution.Scheduler.Implicits.global 23 | import monix.eval._ 24 | 25 | import scala.scalajs.js.annotation.JSExport 26 | 27 | @JSExportTopLevel("RelationsView") 28 | object RelationsView { 29 | 30 | @dom 31 | def relationsMessageDiv = { 32 |
34 |

35 | { 36 | RelationsModel.userMessage.bind 37 | } 38 |

39 |
40 | } 41 | @dom 42 | def relationsDiv = { 43 | 44 | val urnValidatingKeyUpHandler = { event: KeyboardEvent => 45 | (event.currentTarget, event.keyCode) match { 46 | case (input: html.Input, KeyCode.Enter) => { 47 | event.preventDefault() 48 | RelationsController.changeUrn(s"${input.value.toString}") 49 | //input.value = "" 50 | } 51 | case(input: html.Input, _) => RelationsController.validateUrn(s"${input.value.toString}") 52 | case _ => 53 | } 54 | } 55 | 56 |
57 | 58 |
59 | { previousQueryMenu.bind } 60 |

Find URNs in Relations

61 |

62 | { RelationsView.verbFilterSelect.bind } 63 |
64 | 71 | 72 | { RelationsView.findRelationsButton.bind } 73 |
74 |

75 |
76 | 77 | { relationsMessageDiv.bind } 78 | 79 |

80 | { 81 | RelationsModel.urn.bind match { 82 | case Some(u) => s"${u}" 83 | case None => "[ no URN requested ]" 84 | } 85 | } 86 | 87 | { RelationsModel.filterVerb.bind match { 88 | case Some(u) => { 89 | { s" filtered by ${u}" } 90 | } 91 | case None => "" 92 | } 93 | } 94 | { s" (${RelationsModel.foundRelations.length.bind} relations.)" } 95 |

96 | 97 | { relationsSpace.bind } 98 | 99 |
100 | } 101 | 102 | @dom 103 | def relationsSpace = { 104 |
105 |
    106 | { relationsListItems.bind } 107 |
108 |
109 | } 110 | 111 | @dom 112 | def relationsListItems = { 113 | for ( r <- RelationsModel.foundRelations ) yield { 114 |
  • 115 |
      116 | { relationsUrnDisplay(r.urn1).bind } 117 | {
    • { RelationsModel.getVerbLabel(r.relation) }
    • } 118 | { relationsUrnDisplay(r.urn2).bind } 119 |
    120 |
  • 121 | } 122 | } 123 | 124 | @dom 125 | def relationsUrnDisplay(u:Urn) = { 126 | u match { 127 | case CtsUrn(_) => { 128 | DataModelView.textLinkItem(None,u.asInstanceOf[CtsUrn]).bind 129 | } 130 | case Cite2Urn(_) => { 131 | DataModelView.objectLinkItem(None,u.asInstanceOf[Cite2Urn],true).bind 132 | } 133 | case _ => 134 | } 135 | } 136 | 137 | @dom 138 | def findRelationsButton = { 139 | 177 | } 178 | 179 | @dom 180 | def verbFilterSelect = { 181 | 182 | 196 | } 197 | 198 | /* Previous Searches */ 199 | @dom 200 | def previousQueryMenu = { 201 |
    209 | History 210 | { RelationsView.previousQueriesMenu.bind } 211 |
    212 | } 213 | 214 | @dom 215 | def previousQueriesMenu = { 216 | 219 | } 220 | 221 | @dom 222 | def loadPreviousSearches = { 223 | for (q <- RelationsModel.searchHistory) yield { 224 | 225 |

    { 226 | RelationsController.findRelations(q) 227 | } 228 | }>{ q.toString }

    229 | } 230 | } 231 | 232 | } 233 | --------------------------------------------------------------------------------