diff --git a/README.md b/README.md index 509aed3e..b661343a 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,6 @@ # Training -Documentation and workshop materials for IIIF training +Documentation and workshop materials for IIIF training. You can see the published versions of these training sessions at the following URL: -## Current training +[https://training.iiif.io](https://training.iiif.io) -* [IIIF Online workshop](iiif-online-workshop/index.html) - This online workshops covers working with the Image and Presentation APIs and annotating images. It is designed to be followed as a self-paced open access learning tool, though we also offer regular expert-led trainings using a combination of asynchronous learning, Zoom meetings, 1-on-1 help sesions, and a dedicated Slack channel that remains active following the course. This course is updated regularly. - -* [Annotating Cultural Heritage via IIIF](annotations/index.html) - a 1.5 hour session run on the 9th of November 2021 - -* [European Time machine Training](time_machine/index.html) - a 2 hour session run on the 7th of October 2021 - -## Older training - -* [Europeana IIIF Working Group - Presentation API](presentation-api/index.html) - a hour long intro into the Presentation API given as part of the IIIF Europeana Working Meeting in September 2020 - -* [5 day workshop](iiif-5-day-workshop/index.html) - ran at the 2019 DHSI Conference - -* [1 day workshop](iiif-1-day-workshop/index.html) - ran in 2019 in South Africa - -* [Introduction to IIIF Guidebook](intro-to-iiif/index.html) - for Workshop run in 2017 +Each directory is a separate Gitbook instance. \ No newline at end of file diff --git a/australia/README.md b/australia/README.md new file mode 100644 index 00000000..7a8a249c --- /dev/null +++ b/australia/README.md @@ -0,0 +1,33 @@ +# IIIF Australia Training + +This training is part of the [IIIF events](https://iiif.io/event/2024/canberra/) around Fantastic Futures conference in Australia. + +## About the workshop +Access to image-based resources is fundamental to research, scholarship and the transmission of cultural knowledge. Digital images are a container for much of the information content in the Web-based delivery of images, books, newspapers, manuscripts, maps, scrolls, single sheet collections, and archival materials. Yet much of the Internet's image-based resources are locked up in silos, with access restricted to bespoke, locally built applications. A large community of the world's leading research libraries and image repositories have embarked on an effort to collaboratively produce an interoperable technology and community framework for image delivery. + +This workshop will introduce the basics of the International Image Interoperability Framework (IIIF) starting with demonstrating the use cases it supports; including side by side comparison, annotations and layering of images. It will then go on to look into the Image API and provide a method for participants to upload their own images to the Internet Archive so they can access the IIIF Image support the IA provides. + +The second part of the workshop will focus on linking multiple IIIF images together with metadata to provide a IIIF Presentation API manifest and look at the different tools that are available to work with these manifests. Participants will create their own manifests and look to create an exhibit showing off their work. + +## Speaker Bio: +Glen Robson works as the IIIF Technical Coordinator and runs a monthly 5 day online training course along with designing custom training for different institutions on IIIF and AV and reusing IIIF resources in various research systems like Omeka, Zooniverse and other annotation systems. Glen has been involved in the IIIF community since 2014 and previously worked at the National Library of Wales and worked on their IIIF implementation to support various crowdsourcing, maps and Newspaper projects. + +## Plan: + +### Part 1: +9:00am - 11:00am + * Introductions and intro to IIIF - 30 mins + * Introduce exercise on taking a manifest from an institution and opening it in a viewer + * Exercise time - 10mins + * Looking at the image API - 1 hour + * Introduce exercise on uploading image to the internet archive and leave as home work - 10mins + +### Part 2: +11:00am - 12:00pm + * Presentation API - 30mins + * Introduce exercise on using the Manifest Editor + * Exercise time - 15 mins + * Extras - 10mins + * Things to do with Manifests + * Create an Exhibit + * Project demos and summary - 5 mins diff --git a/australia/SUMMARY.md b/australia/SUMMARY.md new file mode 100644 index 00000000..54d0df66 --- /dev/null +++ b/australia/SUMMARY.md @@ -0,0 +1,30 @@ +# Summary + +- [Overview](README.md) +- [What is IIIF](day-one/whatisiiif.md) + - [Exercise](day-one/guides.md) + +## Image API +- [Image API](day-two/image-api.md) + - [Identifier](day-two/image-api/identifier.md) + - [Region](day-two/image-api/region.md) + - [Size](day-two/image-api/size.md) + - [Rotation](day-two/image-api/rotation.md) + - [Quality](day-two/image-api/quality.md) + - [Format](day-two/image-api/format.md) +- [File formats](day-two/fileformats.md) +- [Uses](day-two/uses.md) +- [Getting started](day-two/image-servers/README.md) + - [Hosted - Internet Archive](day-two/image-servers/iiif-hosting-ia.md) + - [Static Images - Workbench](day-two/image-servers/level0-workbench.md) + - [Cantaloupe (Advanced)](day-two/image-servers/setting-up-cantaloupe.md) +- [Scaling IIIF Images](day-two/scaling.md) + +## Presentation API +- [Presentation API](day-three/prezi-intro.md) +- [How do people create Manifests?](day-three/prezi-how.md) +- [Create a Manifest](day-three/digirati-editor/standalone.md) + - [Create a AV Manifest](day-three/digirati-editor/Add_video_manifest.md) +- [Things to do with Manifests](manifests.md) +- [Create an Exhibit](exhibit/exhibit.md) +- [Project demos and summary](demos.md) diff --git a/australia/annotation-use-cases b/australia/annotation-use-cases new file mode 120000 index 00000000..d88a93ab --- /dev/null +++ b/australia/annotation-use-cases @@ -0,0 +1 @@ +../annotations/use_cases \ No newline at end of file diff --git a/australia/book.json b/australia/book.json new file mode 100644 index 00000000..9b16a0d6 --- /dev/null +++ b/australia/book.json @@ -0,0 +1,26 @@ +{ + "title": "IIIF Australia Workshop - October 16th 2024", + "plugins": [ + "include", + "theme-default", + "toggle-chapters", + "git-author", + "-highlight", + "toggle-chapters" + ], + "gitbook": "3.2.3", + "styles": { + "website": "styles/website.css" + }, + "pluginsConfig": { + "theme-default": { + "showLevel": true + }, + "git-author": { + "position": "bottom", + "modifyTpl": "Last modified by {user} {timeStamp}", + "createTpl": "Created by {user} {timeStamp}", + "timeStampFormat": "YYYY-MM-DD HH:mm:ss" + } + } +} diff --git a/australia/day-four b/australia/day-four new file mode 120000 index 00000000..32eca9a6 --- /dev/null +++ b/australia/day-four @@ -0,0 +1 @@ +../iiif-online-workshop/day-four \ No newline at end of file diff --git a/australia/day-one b/australia/day-one new file mode 120000 index 00000000..e18512dd --- /dev/null +++ b/australia/day-one @@ -0,0 +1 @@ +../iiif-online-workshop/day-one \ No newline at end of file diff --git a/australia/day-three b/australia/day-three new file mode 120000 index 00000000..2e56e7db --- /dev/null +++ b/australia/day-three @@ -0,0 +1 @@ +../iiif-online-workshop/day-three \ No newline at end of file diff --git a/australia/day-two b/australia/day-two new file mode 120000 index 00000000..39ae73b2 --- /dev/null +++ b/australia/day-two @@ -0,0 +1 @@ +../iiif-online-workshop/day-two \ No newline at end of file diff --git a/australia/demos.md b/australia/demos.md new file mode 100644 index 00000000..4fd379b9 --- /dev/null +++ b/australia/demos.md @@ -0,0 +1,44 @@ +# Project demos + +We've now completed the course and would be interested in seeing the demos you've been working on. + +Examples from the first workshop can be found at: + +https://docs.google.com/document/d/1W6sBXJEt3Ou2zIPRQxgDQtJtaHZ7qYvCYtixTcSO1Ro/edit?usp=sharing + + +## Slack channels + +Join the [IIIF slack](http://bit.ly/iiif-slack): + + * general - general discussion and announcements + * beginner - beginner questions lots of people to help + * iiif-in-the-classroom - ideas for IIIF in the classroom + * curators_of_awesome - become a curator of awesome by helping to curate: https://github.com/IIIF/awesome-iiif + * mirador - ask questions and see the latest developments with Mirador + * technical - ask difficult technical questions :-) + +## Zoom calls +Community Calls https://iiif.io/community/call/ + +## Community groups +See all IIIF calls on the IIIF Calendar: https://iiif.io/community/ + +Community groups: + * [3D](https://iiif.io/community/groups/3d) + * [A/V](https://iiif.io/community/groups/av) + * [Design](https://iiif.io/community/groups/D4H) + * [Maps](https://iiif.io/community/groups/maps) + * [Museums](https://iiif.io/community/groups/museums) + * [Outreach](https://iiif.io/community/groups/outreach) + +Technical Groups + * [3D](https://iiif.io/community/groups/3d/tsg/) + * [Authentication](https://iiif.io/community/groups/auth-tsg) + * [Content Search](https://iiif.io/community/groups/content-search-tsg) + + +## Stay informed + + * Join the [monthly newsletter](https://iiif.io/newsletter/) + * Join the IIIF Discuss [email list](https://groups.google.com/forum/#!forum/iiif-discuss) diff --git a/australia/exhibit b/australia/exhibit new file mode 120000 index 00000000..eff5668b --- /dev/null +++ b/australia/exhibit @@ -0,0 +1 @@ +../europeana/exhibit \ No newline at end of file diff --git a/australia/manifests.md b/australia/manifests.md new file mode 100644 index 00000000..a57ff32b --- /dev/null +++ b/australia/manifests.md @@ -0,0 +1,8 @@ +# Things to do with Manifests + +Once you have a IIIF manifest hosted publicly on the web you are ready to use most IIIF tools. The following pages provide a few highlights and there are also extras in the following online training: + + * [Exhibiting content with Omeka-s](https://training.iiif.io/advanced_iiif/modules/omeka/) + * [Crowdsourcing with Zooniverse](https://training.iiif.io/advanced_iiif/modules/zooniverse/) + * [Georeferencing with allmaps](https://allmaps.org/) + * [See more tools on awesome-iiif](https://github.com/IIIF/awesome-iiif) \ No newline at end of file diff --git a/australia/styles b/australia/styles new file mode 120000 index 00000000..6692a04a --- /dev/null +++ b/australia/styles @@ -0,0 +1 @@ +../iiif-online-workshop/styles \ No newline at end of file diff --git a/dcmi-workshop/README.md b/dcmi-workshop/README.md new file mode 100644 index 00000000..0b5d9bf3 --- /dev/null +++ b/dcmi-workshop/README.md @@ -0,0 +1,37 @@ +# DCMI 2023 IIIF Workshop + +This is part the [DCMI 2023](https://www.dublincore.org/conferences/2023/) IIIF Workshop. + +## About the workshop + +Access to image-based resources is fundamental to research, scholarship and the transmission of cultural knowledge. Digital images are a container for much of the information content in the Web-based delivery of images, books, newspapers, manuscripts, maps, scrolls, single sheet collections, and archival materials. Yet much of the Internet's image-based resources are locked up in silos, with access restricted to bespoke, locally built applications. A large community of the world's leading research libraries and image repositories have embarked on an effort to collaboratively produce an interoperable technology and community framework for image delivery. + +This workshop will introduce the basics of the International Image Interoperability Framework (IIIF) starting with demonstrating the use cases it supports; including side by side comparison, annotations and layering of images. It will then go on to look into the Image API and provide a method for participants to upload their own images to the Internet Archive so they can access the IIIF Image support the IA provides. + +The second part of the workshop will focus on linking multiple IIIF images together with metadata to provide a IIIF Presentation API manifest and look at the different tools that are available to work with these manifests. Participants will create their own manifests and look to create an exhibit showing off their work. + +## Speaker Bios: + +Tom Cramer is the Chief Technology Strategist, Associate University Librarian & Director of Digital Library Systems & Services for the Stanford University Libraries. He directs the technical development and delivery of Stanford’s digital library services, including digitization, management, preservation and access of digital resources that support teaching, learning and research. He is the founder of the International Image Interoperability Framework (IIIF), a founder of the Samvera Community, the first adopter and an active contributor to Blacklight, and a member of the FOLIO Community Council. He is the President of the Open Library Foundation and co-chair of the CLOCKSS Board of Directors. He has served as a co-PI for the suite of LD4L and LD4P grants from their inception to present day. + +Simeon Warner is Associate University Librarian for IT and Open Scholarship at Cornell University Library. His responsibilities include oversight of IT operations, user experience, web programming, digital preservation, and open scholarly publishing. I have particular interest in interoperability between information systems and the development of standards and collaborations to facilitate that. Current work includes digital preservation (OCFL), evolution of the FOLIO library services platform, use of linked open data for description and discovery of library resources (LD4L/LD4P), image and A/V interoperability (IIIF), and repositories for open-access scholarly publishing (including work with Samvera and ORCID). Past projects include technical direction of the arXiv e-print archive and development of the OAI-PMH and ResourceSync standards. + +## Contributor Bio: + +Glen Robson works as the IIIF Technical Coordinator and runs a monthly 5 day online training course along with designing custom training for different institutions on IIIF and AV and reusing IIIF resources in various research systems like Omeka, Zooniverse and other annotation systems. Glen has been involved in the IIIF community since 2014 and previously worked at the National Library of Wales and worked on their IIIF implementation to support various crowdsourcing, maps and Newspaper projects. + +## Plan: + + * 2:00 - Introductions, current knowledge, hopes and computer set-up + * 2:10 - [Introduction to IIIF](part1/whatisiiif.md) + * [Exercise: Finding IIIF Manifests](part1/guides.md) and loading into Mirador and UV + * 2:45 - [Image API](part2/image-api.md) + * [Exercise: Cropping images](part2/crop-exercise.md) + * 3:30 - Break + * 4:00 - [Presentation API](part3/prezi-intro.md) + * [Exercise: Create a Manifest](part3/digirati-editor/standalone.md) with the Digirati Manifest Editor + * 4:45 - Wrap-up + * [Things to do with Manifests](manifests.md) + * [Setting up IIIF Image Servers for your institution](part2/image-servers/README.md) + * [Image Server Scalability](part2/scaling.md) + * [Project demos and summary](demos.md) diff --git a/dcmi-workshop/SUMMARY.md b/dcmi-workshop/SUMMARY.md new file mode 100644 index 00000000..0cfeb9d4 --- /dev/null +++ b/dcmi-workshop/SUMMARY.md @@ -0,0 +1,32 @@ +# Summary + +- [Overview](README.md) +- [What is IIIF](part1/whatisiiif.md) +- [Exercise: Finding IIIF Manifests](part1/guides.md) + +## Image API +- [Image API](part2/image-api.md) + - [Identifier](part2/image-api/identifier.md) + - [Region](part2/image-api/region.md) + - [Size](part2/image-api/size.md) + - [Rotation](part2/image-api/rotation.md) + - [Quality](part2/image-api/quality.md) + - [Format](part2/image-api/format.md) +- [File formats](part2/fileformats.md) +- [Uses](part2/uses.md) +- [Exercise: Cropping images](part2/crop-exercise.md) + +## Presentation API +- [Presentation API](part3/prezi-intro.md) +- [How do people create Manifests?](part3/prezi-how.md) +- [Exercise: Create a Manifest](part3/digirati-editor/standalone.md) + - [Extra: Create a Video Manifest](part3/digirati-editor/Add_video_manifest.md) + +## Wrap-up +- [Exercise: Things to do with Manifests](manifests.md) + - [Annotation Exercise with Mirador](part4/annotations-exercises.md) + - [Annotation Stores](part4/annotations-stores.md) + - [Create an Exhibit](exhibit/exhibit.md) +- [Setting up IIIF Image Servers for your institution](part2/image-servers/README.md) + - [Image Server Scalability](part2/scaling.md) +- [Project demos and summary](demos.md) diff --git a/dcmi-workshop/annotation-use-cases/AV.md b/dcmi-workshop/annotation-use-cases/AV.md new file mode 100644 index 00000000..84fc3d0d --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/AV.md @@ -0,0 +1,39 @@ +# Audio and Visual Annotations + +In the last few years there have been a number of tools developed to support Audio and Visual annotations. A/V was added in IIIF version 3 so it is a relatively recent addition and the tool support is rapidly improving. + +## Timeliner + +Timeliner is an annotation tool for music education. It allows students and educators to describe the structure of a piece of music (or any audio), creating a hierarchy of parts and visualising the parts as nested bubbles. + +https://cultural-heritage.digirati.com/our-work/timeliner/ + + + +## Europeana Video Editor + +Another powerful annotation tool for AV is the Europeana Video Player/Editor. As well as playing IIIF AV resources the EU Player also has annotation functionality that allows you to create general annotations and also video subtitles. + +https://video-editor.eu/ + +### Annotations + +![EU Player annotations](eu_player_annotations.png) + + +### Subtitle editing + +![EU Player subtitles](eu_player_subtitles.png) + + +## AudiAnnotate + +AudiAnnotate is a publication platform for audio transcriptions created by various existing audio tools like [Sonic Visualiser](https://www.sonicvisualiser.org/). The idea is that you can use your existing tool workflow to create a transcription then upload it to AudiAnnotate. AudiAnnotate will then convert the transcription into IIIF annotations and use a IIIF viewer to displayer the results. You can see a list of projects here: + +http://audiannotate.brumfieldlabs.com/ + +and one project example here: + +https://tanyaclement.github.io/sexton_sweetbriar_1966/pages/anne-sexton-class-visit-at-sweetbriar-college-1966.html#?c=&m=&s=&cv= + +AudiAnnotate uses GitHub for storage so it can be run as a free service. diff --git a/dcmi-workshop/annotation-use-cases/FromThePage.md b/dcmi-workshop/annotation-use-cases/FromThePage.md new file mode 100644 index 00000000..39aa148d --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/FromThePage.md @@ -0,0 +1,29 @@ +# Transcription for Pedagogy + +See [this article](https://content.fromthepage.com/transcription-for-pedagogy/) on using an annotation system called FromThePage for teaching. FromThePage is a transcription tool that provides a wiki like interface for transcribing IIIF Manifests. You can see a full list of features on the [about FromThePage](https://content.fromthepage.com/about/) site. It is open source but also offers a hosted transcription interface. + +For a more in depth workshop including and how to sign up for a trial membership and annotate your own manifests please see the [FromThePage guest presentation](https://training.iiif.io/iiif-online-workshop/GuestPresentations.html#crowdsourced-transcription-using-fromthepage--iiif) which is part of the 5 day IIIF online training. + +![Screenshot of FromThePage](FromThePage.png) + +The pedagogy use case mentioned in the article has the following stages: + +## Step 1: Find the Archival Collection + +In this case this is a physical challenge where students are tasked with going to the archive to find a set of letters. You could imagine this would also work in a digital only session where students are tasked with finding items in an online catalogue. + +## Step 2: Transcribe + +Once the Students have found the material the course tutor sends round a link to the students so they can start transcribing the letters. + +## Step 3: Review and Edit + +Once the students have finished their assigned transcriptions the course tutor is able to review and edit the transcriptions to provide the students with feedback. + +## Step 4: Write a Paper. + +Finally using the archival material they are now familiar with they are asked to write a report using the letters as historical sources. + +# Review + +This is a use case which could be used in a wide variety of situations particularly with the wealth of IIIF material available. With FromThePage being hosted you don't need any infrastructure to support the project as long as the material you are working with is available as IIIF. diff --git a/dcmi-workshop/annotation-use-cases/FromThePage.png b/dcmi-workshop/annotation-use-cases/FromThePage.png new file mode 100644 index 00000000..c9288999 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/FromThePage.png differ diff --git a/dcmi-workshop/annotation-use-cases/all_maps_demo.png b/dcmi-workshop/annotation-use-cases/all_maps_demo.png new file mode 100644 index 00000000..ddfa4c10 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/all_maps_demo.png differ diff --git a/dcmi-workshop/annotation-use-cases/all_maps_georeferencing.png b/dcmi-workshop/annotation-use-cases/all_maps_georeferencing.png new file mode 100644 index 00000000..2c4f6122 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/all_maps_georeferencing.png differ diff --git a/dcmi-workshop/annotation-use-cases/all_maps_masking.png b/dcmi-workshop/annotation-use-cases/all_maps_masking.png new file mode 100644 index 00000000..f9c822fe Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/all_maps_masking.png differ diff --git a/dcmi-workshop/annotation-use-cases/all_maps_menu.png b/dcmi-workshop/annotation-use-cases/all_maps_menu.png new file mode 100644 index 00000000..f5739155 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/all_maps_menu.png differ diff --git a/dcmi-workshop/annotation-use-cases/all_maps_start.png b/dcmi-workshop/annotation-use-cases/all_maps_start.png new file mode 100644 index 00000000..b013a5b8 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/all_maps_start.png differ diff --git a/dcmi-workshop/annotation-use-cases/allmaps.md b/dcmi-workshop/annotation-use-cases/allmaps.md new file mode 100644 index 00000000..d6f7a8bc --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/allmaps.md @@ -0,0 +1,41 @@ +# Annotations and Maps + +One of the nice things about IIIF is that it is constantly evolving. By allowing a standard interface to access Cultural Heritage objects it allows new tools to be developed and one of these is [AllMaps.org](https://allmaps.org/). This tool allows you to Geo-reference a IIIF Map so it can be overlaid onto a modern map. + +It starts the same way as many of the solutions discussed earlier with a IIIF Manifest. For this example I am going to use a map of Washington D.C. from the Library of Congress: + + * [https://www.loc.gov/resource/g3850.cw0678500/?r=-0.34,0,1.679,0.982,0](https://www.loc.gov/resource/g3850.cw0678500/?r=-0.34,0,1.679,0.982,0) + * [Manifest](https://www.loc.gov/item/88694013/manifest.json) + +The first stage is to navigate to [https://editor.allmaps.org](https://editor.allmaps.org) and enter the Manifest URL: + +![Enter IIIF Manifest URL into Allmaps](all_maps_start.png) + +The second stage is to navigate to Mask to start geo-referencing. + +![Select Mask on allmaps Menu](all_maps_menu.png) + +The first process of geo-referencing is to cut out the parts of the image that contain the map. This is called Masking. In this example part of the Map contains the title so is cut out of the Map that needs geo-referencing. + +![Masking with allmaps](all_maps_masking.png) + +Now the real geo-referencing can start. Select a point on the modern map and then select the corresponding location on the IIIF map. Once you have added enough points allmaps will be able to warp and fit the historical map on top of the modern map. + +![geo-referencing](all_maps_georeferencing.png) + +You can then view the resulting transformation by clicking the modern map. + +![visualising the geo-referencing with allmaps](all_maps_demo.png) + +This type of geo-referencing can be very useful if you are trying to co-locate different data for example maps from different periods or annotations from related documents. + +For example there is this [Cynefin project](https://www.library.wales/digitisation-projects/places-of-wales/about-places-of-wales) from the National Library of Wales which shows the 1800s Tithe maps of Wales linked to apportionments which detail land use at the time the maps were created: + +https://places.library.wales/browse/52.415/-4.084 + +This was a crowdsourcing project which used a similar Geo-referencing tool called [Georeferencer](https://georeferencer.com/). + +![cynefin.png](cynefin.png) + + + diff --git a/dcmi-workshop/annotation-use-cases/annotations.json b/dcmi-workshop/annotation-use-cases/annotations.json new file mode 100644 index 00000000..3b5278dc --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/annotations.json @@ -0,0 +1 @@ +{"@context":"http://iiif.io/api/presentation/2/context.json","@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line.json","@type":"sc:AnnotationList","@label":"OCR text granularity of line","resources":[{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/914,669,616,79","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"rDie ,qfiifian-flme"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=914,669,616,79"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1294,617,257,8","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"\\ ."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1294,617,257,8"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1533,670,1676,74","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"rican ‘Voice 0f9\\£ortfi Carofina State ‘élniversity"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1533,670,1676,74"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/590,1075,378,107","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Special"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=590,1075,378,107"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/535,1209,491,84","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Edition In"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=535,1209,491,84"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/467,1343,627,84","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Honor of Dr."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=467,1343,627,84"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/528,1477,505,105","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Augustus"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=528,1477,505,105"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/613,1609,343,84","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Mclver"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=613,1609,343,84"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/444,1726,669,122","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=444,1726,669,122"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/506,2565,301,94","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"News"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=506,2565,301,94"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/529,2720,598,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--The Legacy of Dr. Augustus"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=529,2720,598,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/478,2787,415,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Mclver Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=478,2787,415,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/529,2921,597,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"—-Dr. Grant Remembers Dr."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=529,2921,597,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/478,2987,650,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon: A Profound"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=478,2987,650,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/479,3054,351,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Warrior to Us All"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=479,3054,351,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/857,3187,272,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"«Cover Story"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=857,3187,272,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/530,3319,488,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--The Afrikan-American"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=530,3319,488,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/479,3385,585,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Cultural Center: A Center of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=479,3385,585,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/480,3451,516,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Awareness and Education"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=480,3451,516,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/968,3584,161,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--page 2"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=968,3584,161,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/531,3717,532,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--Recapturing the Life of a"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=531,3717,532,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/479,3783,454,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Warrior: A Time Line"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=479,3783,454,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/480,3850,582,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Reflection Representing Dr."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=480,3850,582,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/480,3917,388,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon’s Life"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=480,3917,388,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/531,4051,445,45","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--Chancellor Larry K.."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=531,4051,445,45"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/481,4116,592,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Monteith Shares With Us the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=481,4116,592,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/482,4183,641,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Impact Dr. Witherspoon Had on"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=482,4183,641,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/482,4250,87,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Him"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=482,4250,87,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/970,4384,160,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"«page 3"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=970,4384,160,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/533,4517,563,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Stephanie Cogdell Tells of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=533,4517,563,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/482,4584,610,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the Experiences She Had With"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=482,4584,610,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/482,4651,334,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=482,4651,334,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/533,4784,542,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--Dawn F. Gordon Reflects"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=533,4784,542,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/482,4850,497,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"on the Good Times , The"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=482,4850,497,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/483,4916,628,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Remembrances, and the Effects"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=483,4916,628,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/483,4983,532,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"of Dr. Witherspoon Had at"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=483,4983,532,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/483,5050,132,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"NCSU"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=483,5050,132,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/534,5183,556,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"--Chris Smith Tells Of Why"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=534,5183,556,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/483,5250,599,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon Will Always"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=483,5250,599,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/484,5317,595,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Be Remembered in the Minds"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=484,5317,595,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/484,5383,649,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"and Hearts of Everyone He Ever"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=484,5383,649,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/484,5449,446,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Came in Contact With"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=484,5449,446,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/973,5584,162,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"«page 4"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=973,5584,162,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1242,1053,3152,228","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"The Legacy of Dr. Augustus"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1242,1053,3152,228"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1695,1340,2252,222","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Mclver Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1695,1340,2252,222"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1301,1641,568,51","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"b LaTon a Dunn"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1301,1641,568,51"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1473,1720,272,39","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"News Writer"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1473,1720,272,39"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1298,1920,679,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"On Saturday, April 1, the former-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1298,1920,679,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1237,1986,741,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ly named Student Center Annex will"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1237,1986,741,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1236,2053,743,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"be renamed the Augustus Mclver"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1236,2053,743,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1237,2119,592,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon Student Center."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1237,2119,592,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1305,2185,673,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"The dedication ceremony will"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1305,2185,673,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1236,2252,743,49","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"begin at 3 pm. and will include a"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1236,2252,743,49"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1237,2320,741,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"performance by the Youth"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1237,2320,741,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1238,2387,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Community Choir from St. Luke’s"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1238,2387,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1237,2453,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan Methodist Episcopal Church"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1237,2453,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,2520,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"where Witherspoon preached. The"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,2520,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1238,2586,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"keynote speaker will be Dr. Brenda"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1238,2586,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,2651,738,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Allen, coordinator of Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,2651,738,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,2710,739,45","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American Student Services at the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,2710,739,45"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,2785,392,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"College of Textiles."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,2785,392,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1300,2852,679,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon dedicated most"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1300,2852,679,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,2919,758,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"of his life to educating future leaders ."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,2919,758,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1240,2986,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"of America. After obtaining a bach-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1240,2986,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1239,3053,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"elor’s degree from Claflin College in"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1239,3053,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3119,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Orangeburg, South Carolina,"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3119,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1240,3185,766,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon taught high school sci- -"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1240,3185,766,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3252,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ence in Lumberton and Rocky"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3252,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3317,541,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Mount, from 1953 to 1966."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3317,541,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1321,3384,691,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"He came to NCSU as a graduate ~"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1321,3384,691,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1242,3450,772,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"student and received a master’s"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1242,3450,772,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3517,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"degree in 1968. While helping to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3517,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3583,741,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"establish an Afrikan-American"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3583,741,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3649,740,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Cultural Center, he received his doc-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3649,740,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3716,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"torate in 1971. Witherspoon then"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3716,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1241,3783,740,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"went from a graduate teaching assis-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1241,3783,740,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1240,3841,741,56","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"tant to a professor, Assistant Dean to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1240,3841,741,56"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2263,3711,746,75","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Augustus Mclver"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2263,3711,746,75"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2397,3804,470,75","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2397,3804,470,75"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,1651,356,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Associate Dean"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,1651,356,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,1718,356,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"and Associate"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,1718,356,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,1785,356,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Provost of the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,1785,356,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,1851,343,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Graduate School."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,1851,343,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3215,1983,382,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":":Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3215,1983,382,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,2049,356,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"received several"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,2049,356,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3213,2115,383,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"‘ awards for out—"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3213,2115,383,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2168,355,61","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"standing teaching"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2168,355,61"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2250,356,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"and research. In"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2250,356,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3246,2317,352,41","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"1992, he received"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3246,2317,352,41"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2450,356,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"appreciation from"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2450,356,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3240,2582,357,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Trustees for lead-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3240,2582,357,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,2649,355,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ership, research,"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,2649,355,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2715,354,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"and education."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2715,354,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3172,2782,426,49","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"j 1' He was also"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3172,2782,426,49"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3181,2848,417,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"3 named to the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3181,2848,417,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3243,2916,356,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Order of The"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3243,2916,356,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2983,358,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Long Leaf Pine"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2983,358,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,3050,359,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"by Governor"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,3050,359,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,3110,359,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"James B. Hunt"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,3110,359,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3244,3183,357,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"for his service to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3244,3183,357,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3244,3249,357,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the state of North"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3244,3249,357,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3243,3315,183,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Carolina."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3243,3315,183,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3293,3381,309,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Chancellor"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3293,3381,309,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3244,3447,354,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Larry K."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3244,3447,354,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3243,3514,355,41","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Monteith stated,"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3243,3514,355,41"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3244,3581,355,35","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"“ G u s"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3244,3581,355,35"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3226,3647,373,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon was"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3226,3647,373,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3227,3713,372,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"a trailblazer. In"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3227,3713,372,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3226,3780,372,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"renaming this cen-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3226,3780,372,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3227,3854,371,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ter, we commem-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3227,3854,371,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2968,3606,246,41","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Staff Photo"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2968,3606,246,41"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3242,2383,359,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"a citation of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3242,2383,359,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3241,2516,360,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the Board of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3241,2516,360,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,1650,740,45","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"orate a man who was a leader among"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,1650,740,45"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,1709,740,55","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"faculty, a role model to students, and"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,1709,740,55"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,1783,740,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"above all else, an educator who"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,1783,740,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3665,1849,741,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"refused to settle for less than the best"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3665,1849,741,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,1916,376,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"from his students.”"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,1916,376,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3753,1981,653,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Chancellor Monteith and his"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3753,1981,653,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2047,737,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"wife will unveil a portrait of Dr."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2047,737,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2114,741,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon that will hang in the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2114,741,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2179,742,49","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon Student Center after"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2179,742,49"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3667,2248,499,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the dedication ceremony."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3667,2248,499,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3728,2315,679,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon is the first"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3728,2315,679,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2382,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan-American to have a building"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2382,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3667,2448,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"named after him on the campus of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3667,2448,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2515,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"North Carolina State University. He"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2515,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3667,2581,740,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"was the second Afrikan-American to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3667,2581,740,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2646,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"earn a doctoral degree from the uni—"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2646,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3667,2714,737,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"versity. Dr. Augustus M."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3667,2714,737,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3666,2780,745,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Witherspoon touched the lives of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3666,2780,745,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3668,2848,740,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"many students and will continue to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3668,2848,740,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3669,2915,739,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"serve as a living legend on the cam-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3669,2915,739,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3668,2981,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"pus of North Carolina State"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3668,2981,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3669,3049,219,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"University."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3669,3049,219,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3722,3177,689,41","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"*A Preacher and Teacher to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3722,3177,689,41"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3670,3243,741,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Us Al‘. The Words of Dr. Martin"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3670,3243,741,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3669,3310,338,51","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Luther King Jr."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3669,3310,338,51"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1703,3931,2342,160","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"A Profound Warrior For"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1703,3931,2342,160"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2429,4187,670,158","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"' Us All"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2429,4187,670,158"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1294,4445,638,52","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"b Rochelle Carlton"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1294,4445,638,52"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1490,4525,249,40","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Staff Writer"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1490,4525,249,40"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1294,4717,690,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Augustus M. Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1294,4717,690,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1243,4783,742,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"began his affiliation with NCSU as a"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1243,4783,742,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1243,4849,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"graduate student. As he progressed"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1243,4849,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1244,4915,740,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"from student, to professor, to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1244,4915,740,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1244,4982,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Associate Dean, and finally"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1244,4982,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1244,5049,742,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Associate Provost and Coordinator"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1244,5049,742,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1244,5115,741,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"of Afrikan-American Affairs, he left"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1244,5115,741,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1244,5183,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"behind a legacy that will continue to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1244,5183,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1245,5250,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"impact the Afrikan—American stu-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1245,5250,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1245,5317,743,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"dents at NC. State University for"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1245,5317,743,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1245,5390,287,40","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"years to come."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1245,5390,287,40"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1306,5450,679,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Provost William Grant, who has"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1306,5450,679,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1246,5516,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"accepted the challenge of following"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1246,5516,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1246,5583,740,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"in the footsteps of Dr. Witherspoon,"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1246,5583,740,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1247,5650,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"spoke at great length on the pro-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1247,5650,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1247,5717,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"found changes Dr. Witherspoon has"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1247,5717,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1246,5783,745,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"brought about on the campus of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1246,5783,745,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1247,5851,141,36","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"NCSU."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1247,5851,141,36"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/1311,5917,676,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon began, and con—"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=1311,5917,676,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2051,4449,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"tinued throughout his career, the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2051,4449,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2052,4516,738,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"long and complex process of trans-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2052,4516,738,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2052,4583,739,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"forming what was once a segregated"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2052,4583,739,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2052,4649,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"institution into a place that could"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2052,4649,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2052,4715,737,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"meet the needs of its Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2052,4715,737,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,4782,431,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American population."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,4782,431,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2114,4848,678,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"One of Dr. Witherspoon’s first"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2114,4848,678,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,4915,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"major undertakings was the creation"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,4915,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,4981,737,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"of a task force, the Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,4981,737,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,5048,739,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Amen’can Advisory Council, during"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,5048,739,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2052,5114,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the early 1970’s to determine why"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2052,5114,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2054,5181,738,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan-American enrollment at"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2054,5181,738,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,5249,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"NCSU was so low. In examining"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,5249,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2053,5316,740,42","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"this issue, the Council asked"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2053,5316,740,42"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2054,5382,738,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan-American faculty, staff,"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2054,5382,738,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2054,5449,740,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"employees, and former students to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2054,5449,740,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2055,5515,738,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"describe their experiences at the uni-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2055,5515,738,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2055,5582,145,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"versity."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2055,5582,145,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2104,5649,689,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"They also interviewed area high-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2104,5649,689,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2056,5715,738,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"school students and asked them"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2056,5715,738,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2056,5782,737,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"about their impressions of the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2056,5782,737,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2057,5849,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"school. As anyone who has ever"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2057,5849,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2056,5917,739,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"tried to bring about change may"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2056,5917,739,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2859,4447,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"know, often the first step in finding"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2859,4447,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4515,741,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"solutions to a problem is proving to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4515,741,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4582,741,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"“the powers that be” that the prob-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4582,741,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4648,442,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"lem does indeed exist."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4648,442,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2920,4714,681,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"To convey the severity of the sit-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2920,4714,681,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4781,742,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"uation, a videotape was presented to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4781,742,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4847,742,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"the administration so that they could"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4847,742,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,4913,746,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"hear firsthand the students’ and staff"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,4913,746,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2861,4980,741,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"members’ description of a campus"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2861,4980,741,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,5047,743,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"environment that was hostile to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,5047,743,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2860,5113,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan-American high school stu—"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2860,5113,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2861,5180,551,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"dents had of this university."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2861,5180,551,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2922,5247,680,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"The Afrikan-American Advisory"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2922,5247,680,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2861,5314,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Council then drew up a list of rec-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2861,5314,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2862,5381,742,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ommendations outlining how to"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2862,5381,742,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2862,5447,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"resolve the problem, some of which"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2862,5447,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5513,741,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"led to the establishment of Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5513,741,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5580,741,37","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American Coordinators in each col-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5580,741,37"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5647,742,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"lege, and the enlargement of the"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5647,742,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5713,740,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"almost nonexistent Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5713,740,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5781,358,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American faculty."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5781,358,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2923,5847,682,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Dr. Witherspoon was committed"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2923,5847,682,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/2863,5913,742,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"to ensuring that NCSU offered an"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=2863,5913,742,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3670,4445,737,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"environment in which Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3670,4445,737,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3670,4512,739,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American students could excel. In"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3670,4512,739,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,4579,737,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"order to provide Afrikan—American"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,4579,737,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,4646,737,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"students with the opportunity to net-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,4646,737,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,4712,738,43","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"work, interact with one another, and"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,4712,738,43"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3670,4778,738,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"become acquainted with Afrikan-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3670,4778,738,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,4845,738,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American faculty and staff, he sup-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,4845,738,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,4911,738,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"plemented the regular orientation"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,4911,738,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3670,4977,738,49","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"process to include an Afrikan—"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3670,4977,738,49"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,5046,456,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"American Symposium."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,5046,456,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3732,5111,679,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"When it became apparent that"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3732,5111,679,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,5178,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"there was an alarmingly large dis-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,5178,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3671,5245,744,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"crepancy between the number of"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3671,5245,744,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3672,5312,738,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"Afrikan-American students entering"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3672,5312,738,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5379,738,45","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"as freshman, and those actually eam-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5379,738,45"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5445,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"ing a degree, even for those students"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5445,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5512,739,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"whose performance was above aver-"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5512,739,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5578,740,48","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"age in high-school, Dr. Witherspoon"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5578,740,48"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5645,740,46","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"introduced the idea of adding a new"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5645,740,46"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5711,741,38","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"course to the curriculum that would"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5711,741,38"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3673,5779,586,47","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"help rectify this discrepancy."},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3673,5779,586,47"},{"@id":"https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001-annotation-list-line/3768,5852,552,64","@type":"oa:Annotation","motivation":"sc:painting","resource":{"@type":"cnt:ContentAsText","format":"text/plain","chars":"see Grant, page 3"},"on":"https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001#xywh=3768,5852,552,64"}]} diff --git a/dcmi-workshop/annotation-use-cases/cynefin.png b/dcmi-workshop/annotation-use-cases/cynefin.png new file mode 100644 index 00000000..8bb62a50 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/cynefin.png differ diff --git a/dcmi-workshop/annotation-use-cases/eu_player_annotations.png b/dcmi-workshop/annotation-use-cases/eu_player_annotations.png new file mode 100644 index 00000000..15d6052a Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/eu_player_annotations.png differ diff --git a/dcmi-workshop/annotation-use-cases/eu_player_subtitles.png b/dcmi-workshop/annotation-use-cases/eu_player_subtitles.png new file mode 100644 index 00000000..4e6f7285 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/eu_player_subtitles.png differ diff --git a/dcmi-workshop/annotation-use-cases/exemptions.png b/dcmi-workshop/annotation-use-cases/exemptions.png new file mode 100644 index 00000000..8de45dc0 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/exemptions.png differ diff --git a/dcmi-workshop/annotation-use-cases/ida.md b/dcmi-workshop/annotation-use-cases/ida.md new file mode 100644 index 00000000..3332b6c1 --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/ida.md @@ -0,0 +1,15 @@ +# The Indigenous Digital Archive + +This project is an important demonstration of a community reclaiming ownership of their records and re-contextualizing them to make sure the story is heard. The first part of the project was to make available 78 linear feet of microfilmed government records from the National Archives relating to the Indian boarding schools in New Mexico. + +"The era of government-run Indian boarding schools is a controversial and sometimes shameful +chapter in American history. Many children were sent away for years at a time, forced to wear +European clothes and forbidden from speaking their Native languages. They dressed in military- +style uniforms, marched to meals and were sent out to work during school vacations, a practice +called “outing.” + +The schools were designed to disperse and mix students to separate them from their culture." + +From an article in the *[Santa Fe New Mexican](https://perma.cc/7G2P-V934)*. + +Once the material was available as IIIF they could use various automated tools to extract the names of schools and tribes to make the content discoverable. They thought very carefully about what items to make available and enlisted fellows from the indigenous community to vet content and also add annotations using Madoc to re-interpret some of the content in the Archive. For more information on this process see the [Respectful Online Access](https://omeka.dlcs-ida.org/s/ida/page/respect) statement on the project website. diff --git a/dcmi-workshop/annotation-use-cases/madoc_wikidata.png b/dcmi-workshop/annotation-use-cases/madoc_wikidata.png new file mode 100644 index 00000000..25ac8700 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/madoc_wikidata.png differ diff --git a/dcmi-workshop/annotation-use-cases/nubian.json b/dcmi-workshop/annotation-use-cases/nubian.json new file mode 100644 index 00000000..30a91be5 --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/nubian.json @@ -0,0 +1,311 @@ +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "https://d.lib.ncsu.edu/collections/catalog/nubian-message-1995-04-01/manifest", + "@type": "sc:Manifest", + "attribution": "The Nubian Message (LH1 .H6 N83), Special Collections Research Center at NC State University Libraries", + "dcterms:created": "2016-02-23T21:02:56.000Z", + "dcterms:modified": "2021-02-03T08:43:04.000Z", + "label": "Nubian Message, April 1, 1995", + "license": [ + "https://d.lib.ncsu.edu/collections/about#rights_and_use" + ], + "logo": { + "@id": "https://d.lib.ncsu.edu/collections/assets/ncsu-libraries-white-logo-placement-0ac6d32dfc3427d3325882e6a32c81be.jpg" + }, + "metadata": [ + { + "label": "title", + "value": "Nubian Message, April 1, 1995" + }, + { + "label": "Creator", + "value": "Nubian Message (Raleigh, N.C.) (Publisher)" + }, + { + "label": "Created Date", + "value": "1995-04-01" + }, + { + "label": "URL", + "value": "https://d.lib.ncsu.edu/collections/catalog/nubian-message-1995-04-01" + }, + { + "label": "", + "value": "IIIF drag & drop (About IIIF)" + } + ], + "related": { + "@id": "https://d.lib.ncsu.edu/collections/catalog/nubian-message-1995-04-01", + "dcterms:modified": "2021-02-03T08:43:04.92Z", + "format": "text/html", + "label": "HTML page for the resource" + }, + "seeAlso": [ + { + "@id": "https://d.lib.ncsu.edu/collections/catalog/oai?identifier=ncsul%2Fnubian-message-1995-04-01&metadataPrefix=oai_dc&verb=GetRecord", + "format": "text/xml", + "label": "Dublin Core XML via OAI-PMH" + }, + { + "@id": "https://d.lib.ncsu.edu/collections/catalog/nubian-message-1995-04-01/schemaorg.json", + "format": "application/ld+json", + "label": "Schema.org metadata as JSON-LD", + "profile": "https://schema.org" + } + ], + "sequences": [ + { + "@type": "sc:Sequence", + "canvases": [ + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001", + "@type": "sc:Canvas", + "height": 6559, + "images": [ + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001/image", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "on": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0001", + "resource": { + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0001/full/1170,/0/default.jpg", + "@type": "dctypes:Image", + "height": 6559, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0001", + "profile": "http://iiif.io/api/image/2/level2.json" + }, + "width": 4724 + } + } + ], + "label": "[1]", + "otherContent": + { + "@id": "https://training.iiif.io/annotations/use_cases/annotations.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (line level)" + } + , + "seeAlso": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001.hocr", + "format": "text/vnd.hocr+html", + "label": "hOCR", + "profile": "https://github.com/kba/hocr-spec/blob/master/hocr-spec.md" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0001/nubian-message-1995-04-01_0001.txt", + "format": "text/plain", + "label": "plain text OCR" + } + ], + "width": 4724 + }, + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0002", + "@type": "sc:Canvas", + "height": 6547, + "images": [ + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0002/image", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "on": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0002", + "resource": { + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0002/full/1170,/0/default.jpg", + "@type": "dctypes:Image", + "height": 6547, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0002", + "profile": "http://iiif.io/api/image/2/level2.json" + }, + "width": 4768 + } + } + ], + "label": "[2]", + "otherContent": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0002/nubian-message-1995-04-01_0002-annotation-list-word.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (word level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0002/nubian-message-1995-04-01_0002-annotation-list-line.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (line level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0002/nubian-message-1995-04-01_0002-annotation-list-paragraph.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (paragraph level)" + } + ], + "seeAlso": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0002/nubian-message-1995-04-01_0002.hocr", + "format": "text/vnd.hocr+html", + "label": "hOCR", + "profile": "https://github.com/kba/hocr-spec/blob/master/hocr-spec.md" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0002/nubian-message-1995-04-01_0002.txt", + "format": "text/plain", + "label": "plain text OCR" + } + ], + "width": 4768 + }, + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0003", + "@type": "sc:Canvas", + "height": 6548, + "images": [ + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0003/image", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "on": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0003", + "resource": { + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0003/full/1170,/0/default.jpg", + "@type": "dctypes:Image", + "height": 6548, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0003", + "profile": "http://iiif.io/api/image/2/level2.json" + }, + "width": 4660 + } + } + ], + "label": "[3]", + "otherContent": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0003/nubian-message-1995-04-01_0003-annotation-list-word.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (word level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0003/nubian-message-1995-04-01_0003-annotation-list-line.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (line level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0003/nubian-message-1995-04-01_0003-annotation-list-paragraph.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (paragraph level)" + } + ], + "seeAlso": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0003/nubian-message-1995-04-01_0003.hocr", + "format": "text/vnd.hocr+html", + "label": "hOCR", + "profile": "https://github.com/kba/hocr-spec/blob/master/hocr-spec.md" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0003/nubian-message-1995-04-01_0003.txt", + "format": "text/plain", + "label": "plain text OCR" + } + ], + "width": 4660 + }, + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0004", + "@type": "sc:Canvas", + "height": 6548, + "images": [ + { + "@id": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0004/image", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "on": "https://d.lib.ncsu.edu/collections/canvas/nubian-message-1995-04-01_0004", + "resource": { + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0004/full/1170,/0/default.jpg", + "@type": "dctypes:Image", + "height": 6548, + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01_0004", + "profile": "http://iiif.io/api/image/2/level2.json" + }, + "width": 4715 + } + } + ], + "label": "[4]", + "otherContent": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0004/nubian-message-1995-04-01_0004-annotation-list-word.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (word level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0004/nubian-message-1995-04-01_0004-annotation-list-line.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (line level)" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0004/nubian-message-1995-04-01_0004-annotation-list-paragraph.json", + "@type": "sc:AnnotationList", + "label": "Text of this page (paragraph level)" + } + ], + "seeAlso": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0004/nubian-message-1995-04-01_0004.hocr", + "format": "text/vnd.hocr+html", + "label": "hOCR", + "profile": "https://github.com/kba/hocr-spec/blob/master/hocr-spec.md" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01_0004/nubian-message-1995-04-01_0004.txt", + "format": "text/plain", + "label": "plain text OCR" + } + ], + "width": 4715 + } + ], + "rendering": [ + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01/nubian-message-1995-04-01.pdf", + "format": "application/pdf", + "label": "Download as PDF, 1.98 MB" + }, + { + "@id": "https://ocr.lib.ncsu.edu/ocr/nu/nubian-message-1995-04-01/nubian-message-1995-04-01.txt", + "format": "plain/text", + "label": "Download OCR Text" + } + ], + "viewingHint": "paged" + } + ], + "service": [ + { + "@context": "http://iiif.io/api/search/0/context.json", + "@id": "https://ocr.lib.ncsu.edu/search/nubian-message-1995-04-01", + "label": "Search within this thing", + "profile": "http://iiif.io/api/search/0/search", + "service": { + "@id": "https://ocr.lib.ncsu.edu/suggest/nubian-message-1995-04-01", + "label": "Get suggested words", + "profile": "http://iiif.io/api/search/0/autocomplete" + } + } + ], + "thumbnail": { + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01/full/150,/0/default.jpg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://iiif.lib.ncsu.edu/iiif/nubian-message-1995-04-01", + "profile": "http://iiif.io/api/image/2/level2.json" + } + } +} diff --git a/dcmi-workshop/annotation-use-cases/printed_material.md b/dcmi-workshop/annotation-use-cases/printed_material.md new file mode 100644 index 00000000..04a2c414 --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/printed_material.md @@ -0,0 +1,27 @@ +# Printed Material + +So far we have covered annotations generated by crowdsourcing or academic projects but another popular use case is working with auto generated annotations for printed material. You can generate annotations from OCR files like ALTO using a [XSLT here](https://glenrobson.github.io/iiif_stuff/alto2annotations/). Once you have done the conversion you can link the annotations to the manifest and also implement the search API. Below is an example from North Carolina State University (NCSU) showing a Newspaper which has the search API in the Universal Viewer: + + + +It is also possible to view the linked annotations in Mirador: + +
+ + + + +And you can imagine importing these annotations to an annotation store and setting up a project to correct OCR. + +[Import into SAS](https://dev.gdmrdigital.com/view.xhtml?manifest=https://d.lib.ncsu.edu/collections/catalog/nubian-message-1995-04-01/manifest) diff --git a/dcmi-workshop/annotation-use-cases/tribunal.png b/dcmi-workshop/annotation-use-cases/tribunal.png new file mode 100644 index 00000000..370a9761 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/tribunal.png differ diff --git a/dcmi-workshop/annotation-use-cases/tribunal_search.png b/dcmi-workshop/annotation-use-cases/tribunal_search.png new file mode 100644 index 00000000..68388ee1 Binary files /dev/null and b/dcmi-workshop/annotation-use-cases/tribunal_search.png differ diff --git a/dcmi-workshop/annotation-use-cases/wikidata.md b/dcmi-workshop/annotation-use-cases/wikidata.md new file mode 100644 index 00000000..e2d18413 --- /dev/null +++ b/dcmi-workshop/annotation-use-cases/wikidata.md @@ -0,0 +1,42 @@ +# Pandemic Crowdsourcing with Wikidata + +During the COVID Pandemic I saw this tweet from an old colleague at the National Library of Wales. + +

Our volunteer team have just started an exciting new project to tag the location of things depicted in our #openaccess images using the #IIIF. The data will be saved to #Wikidata - https://t.co/TZIcdr3Llk pic.twitter.com/gIbapKxh1h

— Jason Evans (@WIKI_NLW) January 28, 2020
+ +This is another great idea for allowing volunteer engagement without having to setup a large amount of infrastructure. Jason made use of a tool called [Wikidata Image Positions](https://wd-image-positions.toolforge.org/) which allows users to tag different regions of an image with an entity from Wikidata. This could be generic tags like farm, windmill, cattle or horse but can also be specific tags like Aberystwyth or the particular Church depicted in a painting. + +Jason was able to manage the project using a spreadsheet which contains links into the tool like this one: + +[https://wd-image-positions.toolforge.org/item/Q21614047](https://wd-image-positions.toolforge.org/item/Q21614047) + +which opens up one of the images ready for volunteers to start annotating. All the volunteers needs is a Wikipedia login. + +The Wikidata Image Positions tool also creates a IIIF Manifest which can be used in a normal IIIF Viewer. See [this example manifest](https://wd-image-positions.toolforge.org/iiif/Q21614047/P18/manifest.json) and the [Manifest in Mirador 3](https://projectmirador.org/embed/?iiif-content=https://wd-image-positions.toolforge.org/iiif/Q21614047/P18/manifest.json). + +For this project the images need to be on Wikimedia so will work with any type of Image. If you already have IIIF Images then these would also need to be uploaded to Wikimedia but through the use of a [IIIF Manifest property](https://www.wikidata.org/wiki/Property:P6108) it should be possible to map the annotations back to the original IIIF images. + +# The Madoc Crowdsourcing System + +Extending this project further the National Library of Wales also embedded this feature into a more classic crowdsourcing application called [Madoc](https://github.com/digirati-co-uk/madoc-platform). This allows a more controlled volunteer process and links the Wikidata entries to the original IIIF Image. + +![Screenshot of wikidata and Madoc](madoc_wikidata.png) + +The National Library of Wales have also used this Crowdsourcing system to get volunteers to transcribe other material including a 15,000 pages of a collection of WW1 Welsh Tribunal Records. These are the applications made by people in Ceredigion, a county in Wales for exemption to national service. You can see below that Madoc can be configured to customise the data captured. + +![Screenshot of Tribunal Record](tribunal.png) + +The volunteers completed the transcription in about 6 months and the data is made available in a similar way to the Book of Remembrance. The annotations are searchable using the Universal Viewer on the [project webpage](https://www.library.wales/discover/digital-gallery/archives/cardiganshire-great-war-tribunal-appeals-records#?c=&m=&s=&cv=&xywh=-1229%2C-1%2C6135%2C5714): + +![Screenshot of searching the Tribunal Records](tribunal_search.png) + +The NLW have also made the source annotations available for research: + +[https://github.com/NLW-paulm/Welsh-Tribunal-annotations](https://github.com/NLW-paulm/Welsh-Tribunal-annotations) + +and similarly it is possible to create various visualisations of the data including looking at the reasons for exemption: + +![Graph showing exemptions over time](exemptions.png) + +A full write up of this investigation is available [here](https://iiif.gdmrdigital.com/ww1-tribunal/index.html). + diff --git a/dcmi-workshop/book.json b/dcmi-workshop/book.json new file mode 100644 index 00000000..ec8e41eb --- /dev/null +++ b/dcmi-workshop/book.json @@ -0,0 +1,26 @@ +{ + "title": "DCMI 2023 IIIF Workshop", + "plugins": [ + "include", + "theme-default", + "toggle-chapters", + "git-author", + "-highlight", + "toggle-chapters" + ], + "gitbook": "3.2.3", + "styles": { + "website": "styles/website.css" + }, + "pluginsConfig": { + "theme-default": { + "showLevel": true + }, + "git-author": { + "position": "bottom", + "modifyTpl": "Last modified by {user} {timeStamp}", + "createTpl": "Created by {user} {timeStamp}", + "timeStampFormat": "YYYY-MM-DD HH:mm:ss" + } + } +} diff --git a/dcmi-workshop/demos.md b/dcmi-workshop/demos.md new file mode 100644 index 00000000..9e4a2417 --- /dev/null +++ b/dcmi-workshop/demos.md @@ -0,0 +1,39 @@ +# Project demos + +We've now completed the course and would be interested in seeing the demos you've been working on. + +## Slack channels + +Join the [IIIF slack](http://bit.ly/iiif-slack): + + * general - general discussion and announcements + * beginner - beginner questions lots of people to help + * iiif-in-the-classroom - ideas for IIIF in the classroom + * curators_of_awesome - become a curator of awesome by helping to curate: https://github.com/IIIF/awesome-iiif + * mirador - ask questions and see the latest developments with Mirador + * technical - ask difficult technical questions :-) + +## Zoom calls +Community Calls https://iiif.io/community/call/ + +## Community groups +See all IIIF calls on the IIIF Calendar: https://iiif.io/community/ + +Community groups: + * [3D](https://iiif.io/community/groups/3d) + * [A/V](https://iiif.io/community/groups/av) + * [Design](https://iiif.io/community/groups/D4H) + * [Maps](https://iiif.io/community/groups/maps) + * [Museums](https://iiif.io/community/groups/museums) + * [Outreach](https://iiif.io/community/groups/outreach) + +Technical Groups + * [3D](https://iiif.io/community/groups/3d/tsg/) + * [Authentication](https://iiif.io/community/groups/auth-tsg) + * [Content Search](https://iiif.io/community/groups/content-search-tsg) + + +## Stay informed + + * Join the [monthly newsletter](https://iiif.io/newsletter/) + * Join the IIIF Discuss [email list](https://groups.google.com/forum/#!forum/iiif-discuss) diff --git a/dcmi-workshop/exhibit/exhibit.md b/dcmi-workshop/exhibit/exhibit.md new file mode 100644 index 00000000..7f2dcf1d --- /dev/null +++ b/dcmi-workshop/exhibit/exhibit.md @@ -0,0 +1,66 @@ +# Create an Exhibit (extra) + + + +If you have successfully uploaded your Manifest to the Workbench you may want to create an exhibit using a IIIF compatible tool. An example of an exhibit I created is here: + + + +This tells the story of a ship called the Canganian and brings together IIIF resources from Newspapers to Manuscripts to make the presentation. + +## Step 1: Create an Exhibit + +Navigate to: + +[https://www.exhibit.so/](https://www.exhibit.so/) + +Scroll to the bottom until you see the 'Create an Exhibit' button. Click this and you will be taken to the following screen: + +![Create Exhibit screen](img/create.png) + +On this screen you can choose the following type of presentation: + + * Kiosk - this will auto play the slides and is useful for a public display terminal + * Scroll - 'slides' will be presented in a single long web page and uses will scroll down to read the story + * Slides - the default and allows uses to press right or left to navigate the different parts of the story. + * Quiz - Similar to the Slides option buy you can ask your viewers to answer a questions + +For this tutorial we will focus on the slides option. Fill in a Title, Author and Description for your exhibit and agree to the Terms and Conditions and tick the I am not a robot button. Then click "Create Exhibit". + +You will then be presented with the following screen: + +![Exhibition start screen](img/start.png) + +The first thing to do is to add your Manifest. If you switch back to the workbench ([https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/index.xhtml)) in another browser tab. Navigate to your Manifest and right click the IIIF icon and select "Copy link": + +![Workbench copy manifest link](img/workbench.png) + +Now switch back to the Exhibit tool and click the Add Item button and it will show this dialog: + +![Add Manifest URL](img/add_item.png) + +Paste the Manifest URL into the text box and click import. You should see the manifest load in the background and the manifest title in the Items dialog: + +![List items dialog](img/list_items.png) + +Click the cross to close this dialog. + +Now we have the manifest loaded we want to create a 'slide'. Click the + on the left hand side of the screen underneath the Title and description: + +![add slide button](img/add_anno.png) + +Enter a description of what you would like to show and then zoom the right hand image into an area of the image you would like to highlight. + +![add description and zoom](img/zoom.png) + +Once you are happy with the description and zoom click the tick symbol to save the annotation. + +You can now add a number of different slides to tell your story. You can also add different Manifests using the Add Item button. + +Once you are happy click the Preview button which will show you what your presentation looks like: + + + +You can find Manifests from various institutions by going to the IIIF Guides website: + +[https://guides.iiif.io/finding_resources/](https://guides.iiif.io/finding_resources/) diff --git a/dcmi-workshop/exhibit/img/add_anno.png b/dcmi-workshop/exhibit/img/add_anno.png new file mode 100644 index 00000000..9cf0eff7 Binary files /dev/null and b/dcmi-workshop/exhibit/img/add_anno.png differ diff --git a/dcmi-workshop/exhibit/img/add_item.png b/dcmi-workshop/exhibit/img/add_item.png new file mode 100644 index 00000000..8f268599 Binary files /dev/null and b/dcmi-workshop/exhibit/img/add_item.png differ diff --git a/dcmi-workshop/exhibit/img/create.png b/dcmi-workshop/exhibit/img/create.png new file mode 100644 index 00000000..aff55d35 Binary files /dev/null and b/dcmi-workshop/exhibit/img/create.png differ diff --git a/dcmi-workshop/exhibit/img/list_items.png b/dcmi-workshop/exhibit/img/list_items.png new file mode 100644 index 00000000..d9652e88 Binary files /dev/null and b/dcmi-workshop/exhibit/img/list_items.png differ diff --git a/dcmi-workshop/exhibit/img/start.png b/dcmi-workshop/exhibit/img/start.png new file mode 100644 index 00000000..ed9a87cc Binary files /dev/null and b/dcmi-workshop/exhibit/img/start.png differ diff --git a/dcmi-workshop/exhibit/img/workbench.png b/dcmi-workshop/exhibit/img/workbench.png new file mode 100644 index 00000000..a8eba808 Binary files /dev/null and b/dcmi-workshop/exhibit/img/workbench.png differ diff --git a/dcmi-workshop/exhibit/img/zoom.png b/dcmi-workshop/exhibit/img/zoom.png new file mode 100644 index 00000000..f4e7b015 Binary files /dev/null and b/dcmi-workshop/exhibit/img/zoom.png differ diff --git a/dcmi-workshop/manifests.md b/dcmi-workshop/manifests.md new file mode 100644 index 00000000..fa566e8b --- /dev/null +++ b/dcmi-workshop/manifests.md @@ -0,0 +1,11 @@ +# Things to do with Manifests + +Once you have a IIIF manifest hosted publicly on the web you are ready to use most IIIF tools. The next part of this tutorial is an exercise to [Create annotations with Mirador](part4/annotations-stores.md). + +The following pages provide a few highlights and there are also extras in the following online training: + + * [Transcription for Pedagogy](annotation-use-cases/FromThePage.md) + * [Pandemic Crowdsourcing with Wikidata](annotation-use-cases/wikidata.md) + * [Exhibiting content with Omeka-s](https://training.iiif.io/advanced_iiif/modules/omeka/) + * [Crowdsourcing with Zooniverse](https://training.iiif.io/advanced_iiif/modules/zooniverse/) + * [See more tools on awesome-iiif](https://github.com/IIIF/awesome-iiif) diff --git a/dcmi-workshop/part1/README.md b/dcmi-workshop/part1/README.md new file mode 100644 index 00000000..56343e8f --- /dev/null +++ b/dcmi-workshop/part1/README.md @@ -0,0 +1,4 @@ +# Day 1 - Introductions and IIIF Basics +## Monday + +The first day of the workshop is focused on getting to know each other and to learn the basics of IIIF before diving into the different API specifications on day two and three. There is a short introduction to IIIF followed by a basic exercise to View a IIIF object in a IIIF Viewer. diff --git a/dcmi-workshop/part1/guides.md b/dcmi-workshop/part1/guides.md new file mode 100644 index 00000000..da198003 --- /dev/null +++ b/dcmi-workshop/part1/guides.md @@ -0,0 +1,45 @@ +# Finding IIIF Manifests + +One of the issues facing the IIIF Community is how to find IIIF resources. One method that the community is using to solve this problem is to create a list of guides showing how to access IIIF manifest for various institutions. + +![Screenshot of the Guides Website](img/guides.png) + +This is available on the IIIF website at the following location: + +[https://iiif.io/guides/finding_resources/](https://iiif.io/guides/finding_resources/) + +This is a community effort and if your institution isn't listed then please feel free to add it to the [Github Repository](https://github.com/IIIF/guides) or fill in the following [Google form](https://forms.gle/S6LLjBy2o4iEBR8C9). + +If you look through the different collections listed you will notice there are many ways to get the link to a Manifest and this is also something the community is looking to standardise. + +# Task 1: Find a Manifest + +Using the [finding resources guides site](https://iiif.io/guides/finding_resources/), find an interesting item and its Manifest. Copy the Manifest URL. + +Next we'll use the Manifest URL open the item in Mirador and the Universal Viewer (UV). Opening Manifests in the UV and Mirador is something that we will do a lot of during this workshop. + +# Task 2: Open the Manifest in Mirador 3 + +Navigate to [https://projectmirador.org/](https://projectmirador.org/) and click the __Try a Live Demo__ button. Once Mirador opens close the two demo objects by clicking the two crosses highlighted in the screen shot below: + +![Mirador close window screenshot](img/mirador_close.png) + +Then click the Start here button on the top left. + +![Mirador start screenshot](img/mirador-start.png) + +Then click the add resource button at the bottom right: + +![Mirador add Manifest button](img/mirador-add-resource.png) + +Finally you can paste your URL to your manifest and click Add and Mirador should open your Manifest. + +![Mirador add Manifest](img/mirador-add-manifest.png) + +# Task 3: Open the Manifest in the Universal Viewer + +Navigate to [http://universalviewer.io/](http://universalviewer.io/). Scroll down to where you see the __View a IIIF Manifest__ heading and enter in your Manifest URL and click View. + +![UV enter manifest screenshot](img/uv_manifest.png) + +If you want to switch to a new manifest then scroll to the bottom of the UV page and enter it in the __Set IIIF Manifest Id__ box and click the button next to it. diff --git a/dcmi-workshop/part1/img b/dcmi-workshop/part1/img new file mode 120000 index 00000000..0d0c3d87 --- /dev/null +++ b/dcmi-workshop/part1/img @@ -0,0 +1 @@ +../../iiif-online-workshop/day-one/img \ No newline at end of file diff --git a/dcmi-workshop/part1/whatisiiif.md b/dcmi-workshop/part1/whatisiiif.md new file mode 100644 index 00000000..b0237d0e --- /dev/null +++ b/dcmi-workshop/part1/whatisiiif.md @@ -0,0 +1,150 @@ +# What is IIIF? + +IIIF stands for the International Image Interoperability Framework and is best described by looking at the acronym. Broadly it is two things: + +
IIIF is a globally-adopted open source standardized model for delivering many types of image-based resources on the web in many different formats so that audiences can interact with them. It provides a lot of benefits to the institutions that use it, and when implemented across many institutions provides additional benefits across institutional boundaries.
+
+
But, IIIF is more than a standard: it is also an open, global community of software developers, librarians, researchers, educators, museums, universities, creative agencies, and more that work together to develop open APIs, implement them in software, and expose images and A/V files. It’s a grassroots effort between many different institutions to solve their shared problems with delivering, managing, sharing, and working with their resources."
+ +## International + +IIIF has been implemented internationally and is not based in one country. It has been implemented by places like: + + * National Institutions: + * Österreichische Nationalbibliothek (Austrian National Library), + * [BnF](https://guides.iiif.io/guides/gallica.bnf.fr/), + * [Library of Congress](https://guides.iiif.io/guides/loc.gov/) and + * the British library. + * Aggregators: + * Artstore, + * ContentDM, + * Internet Archive and + * Europeana + * Universities & Research Institutions: + * [Göttingen University Collections](https://guides.iiif.io/guides/gdz.sub.uni-goettingen.de/), + * [Leiden University](https://guides.iiif.io/guides/universiteitleiden.nl/) and + * [Stanford University](https://guides.iiif.io/guides/searchworks.stanford.edu/) + * Museums & Galleries: + * British Museum, + * [National Gallery of Art (US)](https://guides.iiif.io/guides/nga.gov/) and + * [J. Paul Getty Trust](https://guides.iiif.io/guides/search.getty.edu/), + +For a fuller list of institutions who advertise their IIIF resources please see the [IIIF guides](https://guides.iiif.io/) site. + + + +## Image* + +First and foremost IIIF started with the problem of making large images available on the Web. This means allowing users to zoom into large images in way that is scaleable and allows quick zooming on large images. + +One of the examples of this is with the Japanese Tax Map below. In the image Wayne Vanderkuil, the Stanford lead photographer is shown next to the map for a sense of scale. Wayne is 6' 4" (1.93m) tall. The map is so big that it had to be photographed in separate sections and stitched together using Photoshop. If you click on the image below you will be taken to the IIIF image which allows you to zoom around this massive map. + + + +For details on how this map was scanned, there is a blog post [here](https://web.archive.org/web/20230527005027/https://library.stanford.edu/blogs/digital-library-blog/2015/11/adventures-oversized-imaging-digitizing-omi-kuni-ezu-jin-jiang). + +* the star next to the image is because IIIF now also supports Audio Visual resources but it was too late to change the name... There is also current work towards a specification for 3d objects. + +Here is an example of a video with table of contents shown in the [Universal Viewer](https://uv-v3.netlify.app/#?c=&m=&s=&cv=&manifest=https%3A%2F%2Fiiif.io%2Fapi%2Fcookbook%2Frecipe%2F0003-mvm-video%2Fmanifest.json) + +## Interoperability + +Interoperability, the ability for different systems and data sources to work together, can be thought of in different ways and there are a few examples below on how IIIF achieves interoperability. + +### Interoperable Viewers + +First, because IIIF provides a standard way of exposing images and metadata it is possible to switch viewers to view the same content. Users might want to do this for a number of reasons: + + * A Library provides content in a general purpose Viewer like the UniversalViewer + * A user might want to take that manuscript and annotate using the features of the Mirador viewer + * A user might want to run some AI tools using the Curation IIIF image viewer + +![Same IIIF manifest in UV and Mirador](img/viewers.png) + + * [Manuscript in NLW using the UniversalViewer](http://hdl.handle.net/10107/4574752) + * [Same Manuscript in Mirador 3](https://projectmirador.org/embed/?iiif-content=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + * [Tify](https://demo.tify.rocks/demo.html?manifest=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + * [IIIF Curation Viewer](http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/?manifest=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + +For instructions on how to take content from one viewer to another there is this [medium post](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013). + +### Interoperable Images + +The second way IIIF supports interoperability is by allowing images from different locations to be used together. For example, to be reunited distributed images in new digital editions. The manuscript below is one that was owned by the infamous biblioclast (someone who destroys books) [Otto Ege](https://en.wikipedia.org/wiki/Otto_Ege). In the early 20th century he split the manuscript and sold individual pages to institutions across the US. Using IIIF these images have been reconstructed in the following way: + +![Image showing how the manuscript was constructed with remote images](img/otto_ege.png) + +See [the full manuscript in Mirador](https://projectmirador.org/embed/?iiif-content=https://dms-data.stanford.edu/data/manifests/Stanford/ege1/manifest.json). + +Another example of a reconstructed manuscript is the one below from the BnF, where illustrations are held by one institution and the rest of the manuscript by another. With IIIF illustrations can be overlaid onto the manuscript pages from which they were cut. + + + +The full demo of this manuscript can be found on the [Biblissima website](https://demos.biblissima.fr/chateauroux/demo/). + +There is also a IIIF Cookbook [recipe](https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/) for this example which supports version 3. + + +### Interoperable Collections + +As well as brining distributed images together it is also possible to compare different collections in a single viewer. The Mirador viewer allows side by side comparison and using the techniques discussed earlier its possible for users to collect manifests from different locations and then compare them. The example here is from a [blog by Ben Albritton of Stanford University](https://blalbrit.github.io/2015/07/14/fellow-travelers-the-canterbury-tales-and-iiif). It shows two copies of Chaucer's Canterbury Tales, one from the National Library of Wales in the UK and one from the Huntington Library in Los Angeles. + + + + + + +
+ + + +## Framework + +The last part of the acronym is Framework and this is for the different standards that IIIF provides to ensure viewers and publishers all agree on sharing compatible data. These standards are known as [APIs](https://en.wikipedia.org/wiki/API) and the two main APIs are: + +![Image and Presentation APIs](img/apis.png) + +These two APIs will be covered in detail in the rest of the workshop. As well as these APIs there are a number of other APIs defined by IIIF including: + + * [Content Search API](https://iiif.io/api/search/) - to search annotations, a bit like a searching within a PDF file + * [Content State API](https://iiif.io/api/content-state/) - to improve the method of taking content from one viewer to another + * [Authorization Flow API](https://iiif.io/api/auth/) - describes services that allow the client to guide users through existing access control systems, including mechanisms that might offer different content to users with different credential + * [Change Discovery API](https://iiif.io/api/discovery/) - for Aggregators like Europeana to efficiently harvest IIIF data and keep track of updates + * [Maps Extension](https://iiif.io/api/extension/navplace/) - to link a Geographical place to a IIIF object. This API can be used to Georeference a map or photograph diff --git a/dcmi-workshop/part2/README.md b/dcmi-workshop/part2/README.md new file mode 100644 index 00000000..8081f3dc --- /dev/null +++ b/dcmi-workshop/part2/README.md @@ -0,0 +1,13 @@ +# Day 2 - Image API +## Tuesday + +The second day of the workshop will focus on the IIIF Image API. Participants may find it helpful to have the video open at the same time as the workshop webpages as the video takes you through these pages. + +### Image API session - 1 hour +Glen Robson the IIIF Technical Coordinator will introduce you to the IIIF Image API starting with the background before going into showing examples of how it works. + +During the call participants will be given a guided hands on task to create their own IIIF images. At a minimum by the end of this topic participants should have their own images available through the Internet Archive. These images will then be used in the next stage with the Presentation API. + + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=1-8hT9YARiY) diff --git a/dcmi-workshop/part2/canvas_finder.js b/dcmi-workshop/part2/canvas_finder.js new file mode 100644 index 00000000..f50e950a --- /dev/null +++ b/dcmi-workshop/part2/canvas_finder.js @@ -0,0 +1,371 @@ + +function loadManifest(event) { + event.preventDefault(); + let manifest_uri = document.getElementById('manifest_uri').value; + + let target_div = document.getElementById('manifest_content'); + + if (manifestOK(manifest_uri, target_div)) { + fetch(manifest_uri) + .then(response => { + if (!response.ok) { + throw new Error(response.statusText); + } + return response.json(); + }) + .then(data => { + if ("@type" in data) { + if (data["@type"] != 'sc:Manifest') { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a @type of sc:Manifest but has a type of: ' + data["@type"]); + } else { + loadv2(data, target_div); + } + } else if ("type" in data) { + if (data["type"] != 'Manifest') { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a type of Manifest but has a type of: ' + data["type"]); + } else { + loadv3(data, target_div); + } + } else { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a @type or type value of Manifest'); + } + }) + .catch(error => { + showMessage(target_div, 'Manifest retrieval error', 'I was unable to get the Manifest you supplied due to: ' + error); + }); + + } +} + +function clearManifest(event) { + event.preventDefault(); + let target_div = document.getElementById('manifest_content'); + target_div.innerHTML = ''; +} + +function isObject(variable) { + return typeof variable === 'object' && !Array.isArray(variable) && variable !== null +} + +function filter(event) { + var source = event.target || event.srcElement; + console.log(source.value); + let canvases = document.getElementsByClassName("canvasDiv"); + for (const canvas of canvases) { + if (source.value == null || source.value.length === 0 || canvas.dataset.label.toLowerCase().includes(source.value.toLowerCase())) { + canvas.style.display = "flex"; + } else { + canvas.style.display = "none"; + } + } +} + +function fallbackCopyTextToClipboard(text) { + var textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + var successful = document.execCommand('copy'); + var msg = successful ? 'successful' : 'unsuccessful'; + console.log('Fallback: Copying text command was ' + msg); + } catch (err) { + console.error('Fallback: Oops, unable to copy', err); + } + + document.body.removeChild(textArea); +} +function copyTextToClipboard(text, success) { + if (!navigator.clipboard) { + fallbackCopyTextToClipboard(text); + return; + } + navigator.clipboard.writeText(text).then(success, function(err) { + console.error('Async: Could not copy text: ', err); + }); +} + +function copyURL(event) { + event.preventDefault(); + var source = event.target || event.srcElement; + copyTextToClipboard(source.dataset.link, function () { + source.innerHTML = ' Copied!'; + setTimeout(function () { + source.innerHTML = ' Copy Image URL'; + }, 1000) + }); +} + +function loadv2(manifest, target_div) { + if ('sequences' in manifest) { + let sequences = manifest.sequences; + if (isObject(sequences)) { + sequences = [ sequences ]; + } + let foundCanvas = false; + let filterDiv = document.createElement('div'); + filterDiv.style="display: flex; justify-content: flex-end; padding-top: 5px; padding-bottom: 5px;" + filterDiv.innerHTML = ''; + + let textBox = document.createElement('input'); + textBox.style = "margin-left:10px;"; + textBox.id = 'filter'; + textBox.type="text"; + textBox.placeholder="Filter canvas label"; + textBox.addEventListener('input',filter); + filterDiv.appendChild(textBox); + target_div.appendChild(filterDiv); + + for (const sequence of sequences) { + if ('canvases' in sequence) { + foundCanvas = true; + for (const canvas of sequence.canvases) { + let canvasDiv = document.createElement('div'); + canvasDiv.style = "border: 1px black solid; padding: 5px;margin-top: 5px;"; + canvasDiv.className = 'canvasDiv'; + canvasDiv.dataset.label = canvas.label; + + let thumbnail = document.createElement('img'); + thumbnail.src = getCanvasThumbnail(canvas, 150,150); + thumbnail.className = 'thumbnail'; + let thumbDiv = document.createElement('div'); + thumbDiv.style="display: inline-block;"; + thumbDiv.appendChild(thumbnail); + + let contentDiv = document.createElement('div'); + contentDiv.style="width: 70%; display: inline-block;position: relative; padding-left: 20px;" + let label = document.createElement('p'); + label.innerHTML = 'Page Label: ' + canvas.label; + + var iiifURL = canvas.images[0].resource.service["@id"]; + + let link = document.createElement('a'); + link.href = iiifURL; + link.innerHTML = iiifURL; + + let pLink = document.createElement('p'); + pLink.innerHTML = 'IIIF Image URL:
'; + pLink.appendChild(link); + + let button = document.createElement('button'); + button.style = "cursor: pointer; background-color: #0069d9; color: #fff; border-color: #0062cc; font-weight: 400; text-align: center; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; -webkit-appearance: button;text-transform: none; overflow: visible; margin: 0; font-family: inherit;box-sizing: border-box; "; + button.innerHTML = ' Copy Image URL'; + button.addEventListener('click', copyURL); + button.dataset.link = link; + + contentDiv.appendChild(label); + contentDiv.appendChild(pLink); + contentDiv.appendChild(button); + canvasDiv.appendChild(thumbDiv); + canvasDiv.appendChild(contentDiv); + + target_div.appendChild(canvasDiv); + } + } else { + if (!foundCanvas) { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no canvases so there are no images to show.'); + } + } + } + } else { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no sequence so there are no images to show.'); + } +} + +function loadv3(manifest, target_div) { + if ('items' in manifest) { + let canvases = manifest.items; + let foundCanvas = false; + let filterDiv = document.createElement('div'); + filterDiv.style="display: flex; justify-content: flex-end; padding-top: 5px; padding-bottom: 5px;" + filterDiv.innerHTML = ''; + + let textBox = document.createElement('input'); + textBox.style = "margin-left:10px;"; + textBox.id = 'filter'; + textBox.type="text"; + textBox.placeholder="Filter canvas label"; + textBox.addEventListener('input',filter); + filterDiv.appendChild(textBox); + target_div.appendChild(filterDiv); + + let canvasLabel = ""; + foundCanvas = true; + for (const canvas of canvases) { + let canvasDiv = document.createElement('div'); + canvasDiv.style = "border: 1px black solid; padding: 5px;margin-top: 5px;"; + canvasDiv.className = 'canvasDiv'; + canvasLabel = getLangString(canvas.label); + canvasDiv.dataset.label = canvasLabel; + + let thumbnail = document.createElement('img'); + thumbnail.src = getCanvasThumbnail(canvas, 150,150); + thumbnail.className = 'thumbnail'; + let thumbDiv = document.createElement('div'); + thumbDiv.style="display: inline-block;"; + thumbDiv.appendChild(thumbnail); + + let contentDiv = document.createElement('div'); + contentDiv.style="width: 70%; display: inline-block;position: relative; padding-left: 20px;" + let label = document.createElement('p'); + label.innerHTML = 'Page Label: ' + canvasLabel; + + var iiifURL = canvas.items[0].items[0].body.service[0]["@id"]; + + let link = document.createElement('a'); + link.href = iiifURL; + link.innerHTML = iiifURL; + + let pLink = document.createElement('p'); + pLink.innerHTML = 'IIIF Image URL:
'; + pLink.appendChild(link); + + let button = document.createElement('button'); + button.style = "cursor: pointer; background-color: #0069d9; color: #fff; border-color: #0062cc; font-weight: 400; text-align: center; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; -webkit-appearance: button;text-transform: none; overflow: visible; margin: 0; font-family: inherit;box-sizing: border-box; "; + button.innerHTML = ' Copy Image URL'; + button.addEventListener('click', copyURL); + button.dataset.link = link; + + contentDiv.appendChild(label); + contentDiv.appendChild(pLink); + contentDiv.appendChild(button); + canvasDiv.appendChild(thumbDiv); + canvasDiv.appendChild(contentDiv); + + target_div.appendChild(canvasDiv); + } + } else { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no sequence so there are no images to show.'); + } + +} + +function manifestOK(manifest_uri, target_div) { + if (manifest_uri.startsWith('http://')) { + showMessage(target_div, 'http/https issue', 'The manifest link you supplied is a http link. To use this tool you need to supply a link that starts with https. This is a common problem you come across with IIIF. If the webpage you are using is https then the Manifest link must also start with https. The training site and most modern websites uses https which is a secure way of accessing the web.'); + + return false; + } + return true; +} + +/* + * Get thumbnail URL from canvas with canvas_id + * canvas_id can contain a fragement + * image returned will be the same size as desired_width and height or bigger + * zero means discount axis. + */ +function getCanvasThumbnail(canvas, desired_width, desired_height) { + // First try canvas thumbnail + if ('thumbnail' in canvas && (isObject(canvas.thumbnail) || Array.isArray(canvas.thumbnail))) { + let thumbnail = canvas.thumbnail; + if (Array.isArray(thumbnail)) { + thumbnail = thumbnail[0]; + } + if ('width' in thumbnail && 'height' in thumbnail) { + if (thumbnail.width > desired_width && thumbnail.height > desired_height) { + if ("@id" in thumbnail) { + return thumbnail["@id"]; + } else { + return thumbnail.id; + } + } + } + } + + // Next try first image + if ('images' in canvas && Array.isArray(canvas.images) + && 'resource' in canvas.images[0] && typeof canvas.images[0].resource === 'object') { + if ('service' in canvas.images[0].resource && typeof canvas.images[0].resource.service === 'object' + && '@id' in canvas.images[0].resource.service && typeof canvas.images[0].resource.service["@id"] === 'string') { + + let imageService = canvas.images[0].resource.service; + let isLevel0 = false; + if ('profile' in imageService) { + if (Array.isArray(imageService.profile)) { + imageService.profile.forEach(function(value) { + if (typeof key === 'string' && key === "http://iiif.io/api/image/2/level0.json") { + isLevel0 = true; + } + }); + } else if (typeof imageService.profile === 'string' && imageService.profile === "http://iiif.io/api/image/2/level0.json") { + isLevel0 = true; + } + } + + let imageId = imageService["@id"]; + + var region = "full"; + + let size = ""; + if (!isLevel0) { + let widthStr = ""; + let heightStr = ""; + if (desired_width != 0) { + widthStr = "" + desired_width; + } + if (desired_height != 0) { + heightStr = "" + desired_height; + } + size = widthStr + "," + heightStr; + } else { + // Find size that is bigger than the one we want. + if ('sizes' in imageService && Array.isArray(imageService.sizes)) { + smallest_width = imageService.width; + smallest_height = imageService.height; + + imageService.sizes.foreach(function(sizeOption) { + if ('width' in sizeOption && 'height' in sizeOption) { + if (sizeOption.width < smallest_width && sizeOption.height < smallest_height) { + smallest_width = sizeOption.width; + smallest_height = sizeOption.height; + } + } + }); + + size = "" + smallest_width + "," + smallest_height; + } else { + // At this point we should go and get the info.json + // No sizes so just have to use full + size = "full"; + } + } + + return imageId + '/' + region + '/' + size + '/0/default.jpg'; + } else { + // No image service so just return image. Really this should have a thumbnail + return canvas.images[0].resource["@id"]; + } + } +} + +function getLangString(label) { + if ('en' in label) { + return label.en; + } else if ('none' in label) { + return label.none; + } else { + return label; + } +} + +function showMessage(div, title, message) { + div.innerHTML = ''; + + let h3 = document.createElement('h3'); + h3.innerHTML = title; + div.appendChild(h3); + + let p = document.createElement('p'); + p.innerHTML = message + div.appendChild(p); + +} diff --git a/dcmi-workshop/part2/crop-exercise.md b/dcmi-workshop/part2/crop-exercise.md new file mode 100644 index 00000000..e98dc332 --- /dev/null +++ b/dcmi-workshop/part2/crop-exercise.md @@ -0,0 +1,22 @@ +## Exercise: Cropping Images + +In this exercise we will use the [UCD Image Cropping tool](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.lib.harvard.edu/ids/iiif/25286607) to select a region of a IIIF image (and optionally adjust other parameters), and see that the region can be be reused via its URI. + +### Step 1: Start the Cropping Tool with an image + +You can start the tool with any IIIF Image by appending the image identifier to the URL base `https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=` + +Examples include: +* A [Map of Seoul](https://collections.si.edu/search/detail/edanmdm:nmnhanthropology_8480110) in the [cropping tool](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.si.edu/ids/iiif/NMNH-81-10767) (from Smithsonian) +* An [Emroidered Screen with 10 panels](https://collections.si.edu/search/detail/edanmdm:nmnhanthropology_8337004?q=korea+art&iiif.enabled=true&record=8&hlterm=korea%2Bart&inline=true) in the [cropping tool](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.si.edu/ids/iiif/NMNH-NHB2017-00559-000003) + +### Step 2: Explore selection of a region + +Use the graphic region selection tool and experiment with the other parameters. + +### Step 3: Use the cropped image + +Look at item 4 within the cropping tool: +1. Preview the cropped image +2. Download the cropped image +3. Copy the cropped image URI into another browser tab to see how it could be reused by reference on any web page diff --git a/dcmi-workshop/part2/fileformats.md b/dcmi-workshop/part2/fileformats.md new file mode 100644 index 00000000..1363f509 --- /dev/null +++ b/dcmi-workshop/part2/fileformats.md @@ -0,0 +1,18 @@ +# File formats + +The IIIF specification makes no mention of the source format of an image and the type of image you can use is driven by the IIIF Image Server you choose. Most support the common file formats like jpeg, png, tiff or gif. To get the fastest experience it is advised to use a special kind of image format that supports tilling. Examples of these include JPEG2000 and special types of Tiff files called Pyramid Tiffs. + +The reason for this can be demonstrated in the following diagram: + +![Pyramid Image](imgs/JPEG2000_format.png) + +When you zoom into a image the viewer only shows you the tiles that are in your view. The view is shown in the red box. This means a very large image can be viewed but the viewer never downloads all of the images. Only the ones that are required. The JPEG2000 and Pyramid Tiff format have these tiles and levels pre-generated into the file format. A Image server just needs to read and extract the correct tiles. This makes them much faster particularly for larger images. Of course if a custom region is requested then the Image server would need to stitch the images together. + +The are various methods (or recipes) to create JPEG2000 and Pyramid Tiffs but to give a few examples the Bodleian method for creating JPEG2000s is detailed here: + +https://image-processing.readthedocs.io/en/latest/jp2_profile.html + +and a method for creating Pyramid Tiffs is detailed on the Serverless IIIF image server: + +https://github.com/nulib/serverless-iiif#creating-tiled-tiffs + diff --git a/dcmi-workshop/part2/image-api.md b/dcmi-workshop/part2/image-api.md new file mode 100644 index 00000000..2850a433 --- /dev/null +++ b/dcmi-workshop/part2/image-api.md @@ -0,0 +1,93 @@ +# Image API + + + + +## Learning objectives + * Understand what the Image API provides + * Be able to change an Image API URL to get access to different parts of an image + * Understand the different types of Image API implementations (level0, level1 etc) + * Know the tools that work with the Image API so you can test your Image API server + +## Introduction + + * What is the Image API? A contract between the server and a viewing client + * It was the first of the IIIF APIs and provides for rich image viewing experience + * It is easy to implement because others have written servers you can install which provide the service + +## Terminology + * __API__ - Application Programming Interface. In this case an agreed standard between the Image API Server and the Image API Client. + * __Client__- The software which allows you to view a IIIF Image. As Web Browsers don't support the Image API Natively there are many Javascript viewers that live on webpages that can allow you to view IIIF Images. Examples include OpenSeaDragon, Mirador and Universal Viewer. + * __Viewer__ - also known as a IIIF Viewer. This is the same as a Client and lets you view IIIF Images. Examples include OpenSeaDragon, Mirador and Universal Viewer. + * __Server__ - Software that runs on a machine at all times and is assessable over the Web. For this workshop I will mostly be referring to Image API Servers but there are other types of servers including Web servers or Email servers. Sometimes they are also know as Services e.g. Image API service, Web Service or Mail Service. + * __Image API__ - the agreed standard and specification which forms the contract between Client and Server + * __Image API Server__ - the running software that provides access to images using the Image API. Sometimes shortened in this context to Image Servers. + * __IIIF Image__ - an Image that is made available through a IIIF Image API Server. + +## History + +IIIF started out to better support the study of Medieval Manuscripts and to overcome difficulties using digitised versions. Ben Albritton has written a great blog on the difficulties of working with images at that time and the promise IIIF gives in [Fellow Travelers: The Canterbury Tales and IIIF](https://blalbrit.github.io/2015/07/14/fellow-travelers-the-canterbury-tales-and-iiif). + +Here we look at Glen Robson's experience at the National Library of Wales where manuscripts were digitized and three images were created per page: + +1. A thumbnail: + + ![Example thumbnail](https://damsssl.llgc.org.uk/iiif/2.0/image/4628571/full/90,/0/default.jpg) + +2. A Web or reference sized image: + + ![Example web copy of image](https://damsssl.llgc.org.uk/iiif/2.0/image/4628571/full/300,/0/default.jpg) + +3. and a high quality archival Tiff that was only available on request. + +These were made available through a viewer allowing you to browse around the Manuscript and switch between Thumbnail and Web view: + +![Image of a historical digital viewer](imgs/Chaucer_viewer.png) + +As screens got bigger and the internet got faster the limited size of the Web images became a real barrier to use. Although the Archival Tiff was too big to put on the web, they needed some way to allow access to large images and support new methods of access like mobile browsers and the new uses scholars were making of the collection. The solution many institutions moved to, was to create Zooming viewers like [Zoomify](http://www.zoomify.com/) and [Microsoft's DZI](https://en.wikipedia.org/wiki/Deep_Zoom). These viewers tended to use Flash which was unsupported on Mobile and required proprietary file formats to support. Around this time the JPEG2000 file format started to gain traction as an open file format that could support Zoomable viewers. + +Enter: + +![IIIF Logo](imgs/logo.png) + +Provides: + * A standard URL structure for accessing images (easy to support) + * Enough information to drive a zoom viewer + * Human hackable URLs + * Cacheable and Scalable URLs + + + +## Example: + +
+
+ diff --git a/dcmi-workshop/part2/image-api/format.md b/dcmi-workshop/part2/image-api/format.md new file mode 100644 index 00000000..62a56c1b --- /dev/null +++ b/dcmi-workshop/part2/image-api/format.md @@ -0,0 +1,45 @@ +## Format + + + + +The format parameter specifies the format of the image returned, for example `jpg` or `png`. The list of images supported by the image server is again listed in the `info.json`. + +
+
+ diff --git a/dcmi-workshop/part2/image-api/identifier.md b/dcmi-workshop/part2/image-api/identifier.md new file mode 100644 index 00000000..82e1759a --- /dev/null +++ b/dcmi-workshop/part2/image-api/identifier.md @@ -0,0 +1,86 @@ +## Identifier + + + +The identifier is highlighted below. Everything to the right of the identifier is controlled by the Image API and is predictable. In the viewer below a full IIIF image URL is shown. One thing to watch out for with a image URL is that it uses _https_ rather than _http_. With _http_ URLs you will not be able to open the image in a _https_ hosted viewer. + +You can see some different image examples by changing the identifier. +
+
+ + +## Info.json + +As well as images there is special file accessible from the Identifier and this is the `info.json`: + +[https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001/info.json](https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001/info.json) + +This is a small JSON file that gives information to a viewer on the makeup of the image and what the server supports. For example the `info.json` gives the full width and height of the source image. A simple example `info.json` is below: + +``` +{ + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001", + "protocol": "http://iiif.io/api/image", + "width": 5471, + "height": 3757, + "tiles": [ + { + "width": 512, + "scaleFactors": [ + 1, + 2, + 4, + 8 + ] + } + ], + "profile": [ + "http://iiif.io/api/image/2/level2.json", + { + "formats": [ + "jpg" + ], + "supports": [ + "sizeByH", + "sizeByW", + "sizeByForcedWh" + ] + } + ] +} +``` + +The `profile` element advertises what the image server supports. In this example it only supports the `jpg` image format and a few features. These features are defined in the [Image API specification](https://iiif.io/api/image/2.1/compliance/). diff --git a/dcmi-workshop/part2/image-api/quality.md b/dcmi-workshop/part2/image-api/quality.md new file mode 100644 index 00000000..df919ffc --- /dev/null +++ b/dcmi-workshop/part2/image-api/quality.md @@ -0,0 +1,75 @@ +## Quality + + + +The quality parameter defines whether the image should be delivered as: + +| Name | Definition | +| --- | --- | +| Default | Using source color palette/style | +| Gray | Grayscale | +| Bitonal | Each pixel is black or white | +| Color | The color image. This could be a colorized version of a black and white source image | + +This can be useful for some image processing tools like OCR generation. To see what types a image server supports you can look into the `info.json` profile section: + +[https://ids.lib.harvard.edu/ids/iiif/25286607/info.json](https://ids.lib.harvard.edu/ids/iiif/25286607/info.json) + +``` +profile": [ + + "http://iiif.io/api/image/2/level2.json", + { + "supports": [ + "canonicalLinkHeader", + "profileLinkHeader", + "mirroring", + "rotationArbitrary", + "regionSquare", + "sizeAboveFull" + ], + "qualities": [ + "default", + "bitonal", + "gray", + "color" + ], + "formats": [ + "jpg", + "tif", + "png", + "gif", + "webp" + ] + } + +], +``` + +See the example below: + +
+
+ diff --git a/dcmi-workshop/part2/image-api/region.md b/dcmi-workshop/part2/image-api/region.md new file mode 100644 index 00000000..44b29c96 --- /dev/null +++ b/dcmi-workshop/part2/image-api/region.md @@ -0,0 +1,58 @@ +## Region + + + + +The region portion of the URL allows you to extract a portion of an image. The format is `/x,y,width,height/` with the origin of the image being the top left. See this simplified version below: + +![region example](https://iiif.io/api/image/2.1/img/region_px.png) + +This region would be noted as `/125,15,120,140/` which is: + * x = 125 pixels from the left + * y = 15 pixels from the top + * width = 120 pixels + * heigh = 140 pixels + +The pixel dimensions are relative to the full width and height of the image. This generally makes the regions fiddly to work out by hand and there are many cropping tools available which will give you a region, for example: + + * [Jack Reed's Cropping tool](https://bl.ocks.org/mejackreed/6936585f435b60aa9451ae2bc1c199f2) + * [UCD Image Cropping tool](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.lib.harvard.edu/ids/iiif/25286607) + +As well as specifying the exact pixel dimensions there are a couple of short cuts: + + * `full` the full image. + * `square` a region where the width and height are equal. The region is positioned by the server. This can be useful for square thumbnails. + +Use the region drop down to select different regions of the image: + +
+
+ diff --git a/dcmi-workshop/part2/image-api/rotation.md b/dcmi-workshop/part2/image-api/rotation.md new file mode 100644 index 00000000..7c350d95 --- /dev/null +++ b/dcmi-workshop/part2/image-api/rotation.md @@ -0,0 +1,54 @@ +## Rotation + + + + +The rotation portion of the URL allows the image to be rotated up to 360 degrees. You can also use the `!n` form to mirror and rotate the image. Note not all image servers support rotation and there are the following levels of support, known as [compliance levels](https://iiif.io/api/image/2.1/compliance/): + +| Feature | Level | +| --- | --- | +| No rotation supported | Level 0 | +| Only 90 degree rotation supported | Optional in Level 1 mandatory in level 2 | +| Arbitrary rotation | Optional at all levels | +| Mirroring | Optional at all levels | + +The Harvard image service supports all rotation parameters and is known as a Level 2 implementation. + +
+
+ diff --git a/dcmi-workshop/part2/image-api/size.md b/dcmi-workshop/part2/image-api/size.md new file mode 100644 index 00000000..e482b6a4 --- /dev/null +++ b/dcmi-workshop/part2/image-api/size.md @@ -0,0 +1,54 @@ +## Size + + + + +The size portion of the URL governs the size of the output image, possibly scaling the selected region. A full list of options is available in the [Image API specification](https://iiif.io/api/image/2.1/#size). Some of the more common ones: + +| Form | Description | +| -- | -- | +| full | The full image (this is renamed `max` in 3.0) | +| w, | Only the width is specified and the server works out the correct height to keep the aspect ratio. Example `500,`| +| ,h | The alternative only specifying the height. Example `,250`| +| w,h | Explicit width and height. Note this will distort the image. Example: `250,250` | +| !w,h | Fit in a box width by height but don't distort the image. Example `!250,250` | + +See the examples below: + +
+
+ diff --git a/iiif-5-day-workshop/images/4_Quadrants.jpg b/dcmi-workshop/part2/image-servers/4_Quadrants.jpg similarity index 100% rename from iiif-5-day-workshop/images/4_Quadrants.jpg rename to dcmi-workshop/part2/image-servers/4_Quadrants.jpg diff --git a/dcmi-workshop/part2/image-servers/README.md b/dcmi-workshop/part2/image-servers/README.md new file mode 100644 index 00000000..c9255be0 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/README.md @@ -0,0 +1,75 @@ +# Getting started with the Image API + +There are many ways to make a IIIF Image available which is both a big advantage but also can add complexity. The decision on which option to go for depends on your institution or personal use case. IIIF can be used by single researchers up to national institutions, and there are setups to handle ethis range of case. Below we list some options noting benefits and considerations. + +In a 2018 survey we asked what people were using to provide the Image API and these were the results: + +Use of image servers + +Respondents were mostly from within the IIIF community and there is a weighting to larger institutions. Most respondents had installed one of the Image Servers but others are using hosted and DAMS solutions. + +For the purposes of this workshop we will ask you to use the Internet Archive hosted option. You are welcome to follow the guides on installing Cantaloupe and a level0 image server but these are optional extensions. + +## Vendor / DAMS + +For an institution, the best solution is probably to use existing software that you already have. If you have a DAMS system or repository this may already implement IIIF and if it doesn't the best solution maybe to talk them into implementing. This reduces the duplication of images between your image management system and your IIIF Image Server. This solution may not be suitable to individual researchers or institutions who don't have these kind of systems. + + * Where are your images stored now? + * Examples of IIIF supporting Vendors include: + * [OCLC ContentDM](https://www.oclc.org/en/contentdm/iiif.html), + * [GallerySystems](https://www.gallerysystems.com/iiif-what-is-it-and-what-does-it-do/), + * [NetX](https://www.netx.net/blog/iiif_museums_dams), + * [ResourceSpace](https://www.resourcespace.com/knowledge-base/api/iiif) + * [Rosetta](https://knowledge.exlibrisgroup.com/Rosetta/Training/What%27s_New_Videos/Rosetta_5-3/IIIF_Image_Viewing) + * [Veridian](https://veridiansoftware.com/news/veridian-joins-iiif-community/) and many others. + +We have a [page on the IIIF website that lists](https://iiif.io/get-started/vendors/) some of the major digital asset management (DAMs), collections management, and repository tools that support IIIF. + +## Hosted + +Hosting allows you to upload your images to a service that provides a IIIF Image API. These hosting providers run the IIIF Image Servers mentioned below for you and provide interfaces for uploading and managing images. These are good solutions for individual researchers who want to make a few images available and for the commercial providers they also provide a good solution for mid to large sized institutions. For the commercial providers there are costs involved and you will have to weigh up the costs against the costs of running and supporting the Open Source Image servers in the next section. + + * Free hosting from the Internet Archive - [Guide](https://training.iiif.io/iiif-online-workshop/day-two/image-servers/iiif-hosting-ia.html) + + * Commercial hosting: + * [Klokan iiifhosting.com](https://www.iiifhosting.com/) - ([Guide from another workshop](https://training.iiif.io/iiif-1-day-workshop/image-api/iiif-hosting-saas.html)) if its of interest. + * [Digirati DCLS platform](https://dlcs.info/) + +## Run a IIIF Image server + +There are many Open Source IIIF Image servers available. These are free to use but require infrastructure and staff time to setup and maintain. Four popular options are listed below. They can be setup to serve a few images or many millions of images. For the individual researcher or small institution the overhead with installing and maintaining these services may be too much. + + * https://github.com/IIIF/awesome-iiif#image-servers + * Main ones: + * [IIP Image](https://iipimage.sourceforge.io/) - written in C + * [Loris](https://github.com/loris-imageserver/loris) - python + * [Cantaloupe](https://cantaloupe-project.github.io/) - Java + * [Serverless IIIF](https://github.com/samvera/serverless-iiif) - an AWS serverless application in JavaScript + +## Static tiles + +The final option is to use a feature of the Image API where all of the derivative images can be extracted and made available without an image server. There are many ways to get access to free or cheap web hosting. This solution has many steps but can provide a very low cost option for providing access to IIIF Images for researchers and smaller institutions. One thing it doesn't support is custom regions so for example the following level0 image: + + [https://glenrobson.github.io/iiif/welsh_book/page002/full/212,/0/default.jpg](https://glenrobson.github.io/iiif/welsh_book/page002/full/212,/0/default.jpg) + + ![Level0 image example](https://glenrobson.github.io/iiif/welsh_book/page002/full/212,/0/default.jpg) + +Only has a limited number of sizes and regions defined. Enough to work in a zoomable viewer but it won't work with things like the UCD Image Cropper which can select any region. + + + +You can see the [generated files on github](https://github.com/glenrobson/glenrobson.github.io/tree/master/iiif/welsh_book/page002/). There is also a blog on how to use IIIF level 0 images. [IIIF from Scratch](https://glenrobson.github.io/iiif/2018/01/12/iiif-from-scrtach.html). + +You can optionally follow this guide to create your own level 0 images. [Workshop Guide](https://training.iiif.io/iiif-online-workshop/day-two/image-servers/level0-workbench.html) + +Once you have created your level 0 images you can make them available with the following example services: + +Free: + * [GitHub Pages](https://pages.github.com/) - ([Workbench Guide](https://training.iiif.io/iiif-online-workshop/day-two/image-servers/level0-workbench.html)) + +Paid for: + * [Amazon s3 web hosting](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) + +For an idea of costs, the Amazon S3 costs are available [here](https://aws.amazon.com/s3/pricing/). For a ball park figure 2,000 images would cost around a $1 a month. + +Once the images are generated there is little maintenance required and the solution scales to millions of users. diff --git a/dcmi-workshop/part2/image-servers/bl_images.md b/dcmi-workshop/part2/image-servers/bl_images.md new file mode 100644 index 00000000..d696a1e3 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/bl_images.md @@ -0,0 +1,73 @@ + + +# Finding British Library IIIF Images + +For this exercise we are going to find a couple of British Library IIIF Images that we can use tomorrow in the IIIF Presentation API session. This exercise will show you how to find a single IIIF image within a digital object and then how you can manipulate this image so you can use it to tweet or embed in a blog or publication. + +## Stage 1: Find a BL digital item + +Using the [BL collection guide](https://www.bl.uk/collection-guides/iiif) find a digital object and open it up in the Viewer. Once you have found your item it should look as follows: + +![BL digital item in the UV](imgs/uv_bl.png) + +Now we have found the item we want to get the 'IIIF Manifest' for this item. We will go into more details about IIIF Manifests on Wednesday but a Manifest is a JSON document that contains links to all of the images and metadata that goes into a digital item. We are going to find the link to the IIIF Manifest and past this into a tool below which will allow us to find the IIIF Image URL to the image we want. + +To find the manifest click the 'share' link at the bottom of the viewer and then right click on the IIIF icon and select 'Copy link' or 'Copy Link Address' in Chrome: + +***Note:*** some collections like the Google printed books collection do not currently allow sharing so the share button will not be present. + +![BL digital item with manifest link open](imgs/uv_bl_share.png) + + +You can see the copy link from Firefox in this image: + +![Copy link for IIIF Manifest](imgs/uv_bl_copy_link.png) + +The copied link should look something like: + +``` +https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json?manifest=https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json +``` + +You can see the link to the manifest is created twice in this link so it can be cleaned up by removing everything after the `?` to leave: + +``` +https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json +``` + +Some IIIF viewers and tools will be able to cope with the manifest being repeated but if possible its best to remove everything after the `?`. + +## Stage 2: Find IIIF Image URL + +Now we have got our Manifest we need to find the URL (or link) for image we want. We could do this by looking through the JSON and we can have a look at doing this after the Presentation API session on Wednesday but for now I have created the following tool that will take a link to a manifest and allow you to choose the image you want. Paste your manifest into the box below and click Load. + + +
+
+
+ + + + +
+
+
+
+
+ +## Stage 3: Experiment + +Now you have a IIIF Image URL you can plug it into the following IIIF Tools: + +Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2/info.json) + +![Open seadragon](imgs/bl_osd-qa.png) + +Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2) + +![TCD Image cropper](imgs/bl_image_cropping-qa.png) diff --git a/dcmi-workshop/part2/image-servers/cantaloupe b/dcmi-workshop/part2/image-servers/cantaloupe new file mode 120000 index 00000000..6ec91717 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/cantaloupe @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-two/image-servers/cantaloupe \ No newline at end of file diff --git a/dcmi-workshop/part2/image-servers/chrome b/dcmi-workshop/part2/image-servers/chrome new file mode 120000 index 00000000..c5edf6e8 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/chrome @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-two/image-servers/chrome \ No newline at end of file diff --git a/dcmi-workshop/part2/image-servers/github b/dcmi-workshop/part2/image-servers/github new file mode 120000 index 00000000..8ad95350 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/github @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-two/image-servers/github \ No newline at end of file diff --git a/dcmi-workshop/part2/image-servers/ia b/dcmi-workshop/part2/image-servers/ia new file mode 120000 index 00000000..27398ef7 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/ia @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-two/image-servers/ia \ No newline at end of file diff --git a/dcmi-workshop/part2/image-servers/iiif-hosting-ia.md b/dcmi-workshop/part2/image-servers/iiif-hosting-ia.md new file mode 100644 index 00000000..4862a839 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/iiif-hosting-ia.md @@ -0,0 +1,145 @@ +# Using the Internet Archive + +The Internet Archive allows you to upload images and then provides a IIIF Image API service. Helpfully they also have a function to delete your images after 30 days if you are using this as a test. The overall process is as follows: + +__Note__: some people have had some issues getting their images to show when uploading to the Internet Archive. To avoid these issues: + + * Ensure you only upload 1 image ( if you want multiple images you will need to create multiple items) + * Ensure the collection is 'Community Image' collection. The `Community Texts` collection seems to break the image viewing currently + * Some of the IIIF images appear very small even if you uploaded a large image. See the note below on adding the filename to the URL to get the original image available as IIIF. + +1. Register for a user account at [archive.org](https://archive.org) +2. Upload your image + * __Ensure you only upload a single image__ + * __Ensure you select the 'Community Image' collection__ +3. On the details page get the identifier for the image. For example if the details page link is: + + https://archive.org/details/img-8664_202009 + + the identifier would be `img-8664_202009` +4. Use the Internet Archive image service with this identifier: + + https://iiif.archivelab.org/iiif/img-8664_202009/info.json + +5. You should then be able to use this image: + + Create an image link: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg) + + Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json) + + Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009) + + **Note:** the UCD selector tool requires the Image link without the `info.json` at the end of the URL. + +### Small images workaround + +Some images are appearing small, to get round this issue you will need to add the filename to the URL. In the following example: + +https://archive.org/details/img-8664_202009 + +you would normally create the following URL: + +https://iiif.archivelab.org/iiif/img-8664_202009/info.json + +but to make the image larger you need to add the filename (`$IMG_8664.jpg`) so it looks like: + +https://iiif.archivelab.org/iiif/img-8664_202009$IMG_8664.jpg/info.json + +To find the image navigate to the details page: + +https://archive.org/details/img-8664_202009 + +and click on the main image. This will show the image full screen and if you look in the address bar you will be able to see the filename. The reason this happens is due to a bug in the Internet Archive IIIF implementation and I have submitted a [Bug](https://github.com/ArchiveLabs/iiif.archivelab.org/issues/44) and a fix on their github. + +## Step by step guide + +A step by step guide with screen shots for the above steps is below: + +1. Register for a user account at [archive.org](https://archive.org) + + Click signup or login if you already have an account: + + Sign up / Login + + Then create your user: + + Create user + + They will then ask you to verify your email address: + + Send verification email + + You will then see an email like the following: + + Verification Email + + Click on the link on the email and you will get the following screen: + + success + +2. Upload your image + + Select upload on the Archive Welcome screen: + + welcome screen + + You will then see the following screen. Select the green Upload Files button: + + upload choices + + Then click on the 'choose files to upload' button and select the image to upload: + + choose files + + Add metadata. The Title, URL, Description tags are mandatory. I left it in the Community Image collection. Usefully you can also say if its a test item which can be deleted after 30 days. + + __Update__: ensure collection is `Community Image Collection` otherwise the image won't work as IIIF. + + Metadata + + Then click 'Upload and Create Your Item'. This took at least 5 minutes and after the bar has completed you have to wait longer presumably so it can setup the derivative images. + + Upload wait + + If all has gone well you should see the item page: + + item page + +3. On the details page get the identifier for the image. For example if the details page link is: + + https://archive.org/details/img-8664_202009 + + the identifier would be `img-8664_202009` + + Get image identifier + +4. Use the Internet Archive image service with this identifier: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/full/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/full/0/default.jpg) + + IIIF Image URL + +5. You should then be able to use this image: + + Create an image link: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg) + + Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json) + + OpenSeaDragon example + + Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009) + + UCD Image Cropper + diff --git a/dcmi-workshop/part2/image-servers/images_in_manifest.md b/dcmi-workshop/part2/image-servers/images_in_manifest.md new file mode 100644 index 00000000..c6f8b08d --- /dev/null +++ b/dcmi-workshop/part2/image-servers/images_in_manifest.md @@ -0,0 +1,42 @@ + + +# Finding images in Manifests + +Some IIIF tools work with IIIF Image URLs rather than manifests. This is less common than it used to be but for tools like Omeka and basic region image generators getting the URL for the image you want is useful. + +Once you have a Manifest URL you can use the tool below to extract the Image URL. We could do this by looking through the Manifest JSON but this requires a deeper dive in to the Presentation API. + +## Stage 1: Find IIIF Image URL + +If you paste your Manifest URL in the box below and click Load it should show all of the images which are part of your Manifest. You can use the filter to search for a page label and then click `Copy Image URL` to copy the link to the IIIF Image. + + +
+
+
+ + + + +
+
+
+
+
+ +## Stage 2: Experiment + +Now you have a IIIF Image URL you can plug it into the following IIIF Tools: + +Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011/info.json) + +![Open seadragon](imgs/bl_osd.png) + +Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011) + +![TCD Image cropper](imgs/bl_image_cropping.png) diff --git a/dcmi-workshop/part2/image-servers/imgs b/dcmi-workshop/part2/image-servers/imgs new file mode 120000 index 00000000..f88047d4 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/imgs @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-two/image-servers/imgs \ No newline at end of file diff --git a/dcmi-workshop/part2/image-servers/level0-github-hosting.md b/dcmi-workshop/part2/image-servers/level0-github-hosting.md new file mode 100644 index 00000000..a8089ed3 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/level0-github-hosting.md @@ -0,0 +1,101 @@ +# Level 0 hosting with GitHub Pages + +Once you have created your level 0 image we need to make it available to the public. + +One way to get access to free web hosting is to use GitHub pages. GitHub is a software and web application created to manage projects with multiple developers and manages the source code to ensure people's changes don't get overwritten. One feature of Github is GitHub Pages which allows you to create a Web page about your project. We are going to use this functionality to host a IIIF Image. This is a relatively convoluted process but once setup it will give you a free way to publish IIIF Images. + +## Step 1: Sign up to GitHub +Created an account by going to [Github](https://github.com/) and clicking signup. + + * Create Username, password, email + +![image](github/level0-github-signup.png) + + * Complete verify puzzle + +![image](github/level0-verifygithub.png) + + * Choose free option + +![image](github/level0-github-account-type.png) + + * Customise experience (skip this step) + +![image](github/level0-github-customise.png) + + * Verify email address + +![image](github/level0-github-email-verify.png) + + * Success!! + +![image](github/level0-github-success.png) + +## Step 2: Get Read/write access to repo + * Add username to: https://github.com/dhsi-iiif/dhsi-iiif.github.io/issues/1 + * You will get an invitation through the email you registered with in GitHub + +![image](github/level0-github-invitation.png) + + * Accept invitation + +![image](github/level0-github-invitation-accept.png) + +## Step 3: Check out repo +The GitHub desktop application manages the upload of your data to GitHub. It is possible to do this through the Git command line but for this part of the workshop it is suggested to use the Desktop version. + + * Download and install Github desktop https://desktop.github.com/ + * Login + * Click login through website + +![image](github/level0-github-desktop-login.png) + + * Configure name and email + +![image](github/level0-github-desktop-nameemail.png) + + * Download the GitHub dhsi 2019 repository to your local machine in the dhsi2019/dhsi-iiif.github.io. GitHub calls download a repository 'cloning'. So select the dhsi-iiif.github.io repository and click clone. + +![image](github/level0-github-clone.png) + + * Selecting where to download the repo to. + +![image](github/level0-github-clone-2.png) + + * Click open in Finder or similar for Windows + +![image](github/level0-github-desktop-open.png) + + * Make a directory inside the 2019 directory for your examples: + + ``` + dhsi-iiif.github.io/2019/ +``` +## Step 4: Upload level 0 image +Now move the directory you created in the previous step (Step 3 from [static-tiles](static-tiles.md)) into the following: + + ``` + dhsi-iiif.github.io/2019/ + ``` + +Now go to Github Desktop + +![image](github/level0-github-commit.png) + + * Add a commit message on the left hand side. Fill in the Summary and a short description. + * Click commit to master + * You now need to send your local changes to GitHub. To do this click the Push Origin button. Note if others in the class are also on this step they may have made changes to GitHub and the GitHub desktop application will not let you send your changes until you have the latest copy from GitHub. If this is the case it may ask you to Pull from origin. If this is the case Pull the latest changes before pushing your changes. + +![image](github/level0-github-pushpull.png) + + * In your local copy of `2019///info.json`, open it up in an editor and edit the `@id` with: `https://dhsi-iiif.github.io/2019//` + * As you did earlier add a Commit summary and description then commit and Push changes + * Wait 2mins + * Go to: `https://dhsi-iiif.github.io/2019///info.json` + * and you should see your info.json! + +## Step 5: View image: + * Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json + * Openseadragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json + * Note not all software works with level 0 images. + diff --git a/dcmi-workshop/part2/image-servers/level0-workbench.md b/dcmi-workshop/part2/image-servers/level0-workbench.md new file mode 100644 index 00000000..5179b4d2 --- /dev/null +++ b/dcmi-workshop/part2/image-servers/level0-workbench.md @@ -0,0 +1,148 @@ +# Training Workbench + +This option takes advantage of a Website called [GitHub](https://github.com/) which provides among other things a small amount of free Web Space called [GitHub Pages](https://pages.github.com/). This process is similar to the one mentioned in the [Static tiles](static-tiles.html) task but instead of having to install and run the software locally this is provided as a cloud service for the training. + +As mentioned in the previous chapter, the IIIF Image API defines the following structure: + +`http://host:port/identifier/region/size/rotation/quality.format` + +and it is possible to generate images that fit this URL structure and conform to the IIIF Image API using a tile generator. This will generate the minimum required amount of files to implement the IIIF Image API. It does have some limitations, the main one being it is not possible to request images of a size that haven't been pre-generated. This type of pre-generated IIIF Image is known as a `Level 0` implementation. + +The workbench will generate these tiles and upload them to your own GitHub account and has a number of advantages over the Internet Archive option: + + * Images are owned by you on GitHub + * Support for IIIF version 3 + * Faster access to images + +The main disadvantage of this route is the one mentioned above in that it uses static images so you can not request custom sizes or regions, only the ones that have been pre-generated. This option will still allow you to use these images in Manifests and will perform the same for most annotation use cases. + +This solutions is suitable for those that want to use IIIF images but don't have the organisational support or funding to run an image server. The main stages for this process are as follows: + +1. Register for a GitHub account +2. Login to the Workbench +3. Create your project +4. Upload your images +5. View your image + +These steps are detailed below with screen shots. + +## Stage 1: Register for a GitHub account + +Create an account by going to [Github](https://github.com/) and clicking signup. + + * Create Username, password, email + +![image](github/level0-github-signup.png) + + * Complete verify puzzle + +![image](github/level0-verifygithub.png) + + * Choose free option + +![image](github/level0-github-account-type.png) + + * Customise experience (skip this step) + +![image](github/level0-github-customise.png) + + * Verify email address + +![image](github/level0-github-email-verify.png) + + * Success!! + +![image](github/level0-github-success.png) + +## Stage 2: Login to Workbench +In this stage we will go to the workbench and login using the GitHub account we just created. By using the GitHub account to login it allows the Workbench to create a Repository where it can store your uploaded images. If you ever lose access to the Workbench software the files will be safe and accessible on your GitHub account. + +Navigate to the Workbench: [https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/) + +You should see the following screen: + +![image](workbench/login.png) + +Click the Login with GitHub button. + +This will either ask you to login as shown in the following screen shot or if you are already logged in take you straight to the permissions page. + +![image](workbench/github_login.png) + +Next you will see the following permissions page. This is asking you if you are happy for the Workbench to write to your GitHub account. Click Authorize. + +![image](workbench/authorize.png) + +You should now be taken to the projects page: + +![image](workbench/no_project.png) + +You have now successfully logged into the Workbench using your GitHub username and password. Once you have been through the Authorisation step once your browser and GitHub will remember that you have given permission and it should log you straight in. The next stage is to create your project. + +## Stage 3. Create your project + +A project is a place to store the images and manifests you are working on. You can have multiple projects for every GitHub account but note each project is limited to 1GB in size. In the GitHub terminology a project in this case is equivalent to a GitHub Repository. + +To start click the Create Project button: + +![image](workbench/no_project.png) + +and enter a name for your project. Note the name can only contain letters, numbers or the following symbols `-` and `_` so don't add any spaces. + +![image](workbench/create_project.png) + +Click create. This will take a few seconds but will setup an empty project on GitHub and then forward you onto the images part of the Workbench. + +![image](workbench/no_images.png) + +You are now ready to upload your images. + +## Stage 4. Upload your images + +This stage will allow you to upload an image from your computer to the workbench which will convert it into IIIF tiles and store them on GitHub. To start click the upload button and you will see the following screen: + +![image](workbench/upload_image1.png) + +Click the Browse button and select an image on your computer. Once you have an image a `Name` box will appear which allows you to choose the name for your IIIF image. This will appear in the ID of the IIIF image so can't contain spaces and other characters. + +Next select the IIIF Image version either version 2 or 3. For this guides please select version 2 so they can be used in a version 2 manifest. + +![image](workbench/upload_image2.png) + +Then click upload. This will upload the image to Github, create the Image tiles and upload the files to GitHub. This can take a couple of minutes and you will see the following screen while the image is processing: + +![image](workbench/upload_image3.png) + +Once it has finished processing you should see a thumbnail of your image. + +![image](workbench/upload_image4.png) + +You have now uploaded an image and the next stage is to see if it has worked. + +## Stage 5. Viewing your images + +Underneath each of your images you should see two links. One to the `info.json` which we will use later and one to the full image. If you click the Full image link: + +![image](workbench/full_image.png) + +This will open the largest size of your image and the URL will look something like: + +https://iiif-test.github.io/test2/images/IMG_8711/full/full/0/default.jpg + +And note the end of the URL is a IIIF url asking for the `full` region, `full` size, `0` degrees rotation, `default` quality and a `jpg` file format. + +To view this in a zoomable viewer we need to copy the URL to the `info.json`. If you right click on the `info.json` link and select copy link. This should copy a URL similar to the following to your clipboard: + +https://iiif-test.github.io/test2/images/IMG_8711/info.json + +This is called a link to your Info.json and you should be able to open your images in the following two zoomable viewers by appending the link to your info.json to the end: + + * [Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url=](http://mejackreed.github.io/Leaflet-IIIF/examples/?url=https://iiif-test.github.io/test2/images/IMG_8711/info.json) + * [Openseadragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image=](http://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif-test.github.io/test2/images/IMG_8711/info.json) + * Note not all software works with level 0 images. + +If you want to see the tiles that have been generated click the GitHub symbol on the top left: + +![image](workbench/github_link.png) + +this will open GitHub and show the files that it has generated. diff --git a/dcmi-workshop/part2/image-servers/static-tiles.md b/dcmi-workshop/part2/image-servers/static-tiles.md new file mode 100644 index 00000000..3814cd6c --- /dev/null +++ b/dcmi-workshop/part2/image-servers/static-tiles.md @@ -0,0 +1,113 @@ +# Generating static tiles + +As mentioned in the previous chapter, the IIIF Image API defines the following structure: + +`http://host:port/identifier/region/size/rotation/quality.format` + +It is possible to generate images that fit this URL structure and conform to the IIIF Image API using a tile generator. This will generate the minimum required amount of files to implement the IIIF Image API. It does have some limitations, the main one being it is not possible to request images of a size that haven't been pre-generated. This type of pre-generated IIIF Image is known as a `Level 0` implementation. + +To generate these IIIF images we are going to use a IIIF tilling program which is available on Github. This workshop is useful for those that are looking for a cheap method of making a small amount of images available although there are instances where this method can be scaled to support hundreds of thousands of images. See this article for a method of making level 0 images scalable: [The Code4Lib Journal – Scaling IIIF Image Tiling in the Cloud](https://journal.code4lib.org/articles/14933). + +# Prerequisites + +### Java + +In this workshop we will install and run a IIIF Image server and for this you will need Java 11 installed. + + - [Downloading Java 11](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) + +To verify you have the correct package installed, you can run the following command from a terminal or command prompt: + +```sh +$ java -version +# java version "1.11.0_102" +``` + +You should see version `1.11.x`. For more information on the install options see: + + - [Java install options](https://java.com/en/download/help/download_options.xml) + +## Step 1: Download the IIIF Tiler + + * Navigate to the release page: https://github.com/glenrobson/iiif-tiler/releases/tag/0.9.1 + * Click the `assets` drop down + * Download [iiif-tiler.jar](https://github.com/glenrobson/iiif-tiler/releases/download/0.9.1/iiif-tiler.jar) + * Store this jar file in your `~/iiif-workshop` directory + +## Step 2: Prepare your image files + * Move the image files you want to work with into your `~/iiif-workshop` directory + +## Step 3: Generate the IIIF Image tiles + +Now either: + * Double click on the `iiif-tiler.jar` file in Finder or Windows. + +or + + * from the command line run: + +```sh +cd ~/iiif-workshop +java -jar iiif-tiler.jar +``` + * This will generate the IIIF image tiles in a `iiif` directory for every image it finds in the same directory as the iiif-tiler.jar. + +### Common issues: + +If you see the following error: + +``` +Exception in thread "main" java.lang.IllegalArgumentException: Failed to find combination under 100 files +``` + +Try running the following command: + +``` +java -jar iiif-tiler.jar image_filename 5 +``` + +Where `image_filename` is the filename of your image e.g. `image.jpg` + +## Step 4: Point the Chrome webserver to your `iiif-workshop` directory +We will cover the Chrome WebServer in more detail in the Presentation API session but this plugin makes your laptop work like an image server. + + * Open Chrome + * Click the Apps button on the top left + +![image](chrome/chrome_apps.png) + + * Click on the `Web Server` (if this is not listed ensure you have installed the [prerequisites](../prerequisites.md)). + * You should see the following: + +![image](chrome/chrome_web_server.png) + + * Click `choose folder` and select your `iiif-workshop` folder + * Where it says `Enter port` change it to 8887 + * Click `Show Advanced Settings` + * Ensure `Set CORS headers` has a tick next to it. + +## Step 5: Serve your IIIF Image through a http server + + * Open a browser and navigate to [http://127.0.0.1:8887/](http://127.0.0.1:8887/) + * You should see a `iiif` directory and if you click that you should see your image file. + * Click this directory then click on the `info.json`. + * If your image was called `image.jpg` the URL should be. + +`http://127.0.0.1:8887/iiif/image/info.json` + + * If you see the info.json you are now ready to view your image in a IIIF Image viewer. + +## Step 6: Show your image in a IIIF Viewer + +You can now load your image to a IIIF image viewer. The main image viewer is OpenseaDragon. This takes the URL of the info.json. So if your info.json URL is: + +```http://127.0.0.1:8887/iiif/image/info.json``` + +Open it with OpenseaDragon: + +[http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8887/iiif/image/info.json](http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8887/iiif/image/info.json) + +## Step 7: Hosting your image publicly + +You now have a working level 0 implementation. As you are using the Chrome plugin the images are only accessible on your machine. You can't share your images with other people. To be able to share your images you need to copy them to a public Web Server. As mentioned there are paid for services but you can also access free Web Hosting through GitHub which we will do next. + diff --git a/dcmi-workshop/part2/imgs b/dcmi-workshop/part2/imgs new file mode 120000 index 00000000..b0c40c45 --- /dev/null +++ b/dcmi-workshop/part2/imgs @@ -0,0 +1 @@ +../../iiif-online-workshop/day-two/imgs \ No newline at end of file diff --git a/dcmi-workshop/part2/question.md b/dcmi-workshop/part2/question.md new file mode 100644 index 00000000..32f22627 --- /dev/null +++ b/dcmi-workshop/part2/question.md @@ -0,0 +1,18 @@ +# Question + + +Given this image: + + [https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg](https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg) + + ![Example image](https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg) + +How could we construct a URL that: + + * Shows the full image + * is 512px wide + * is upside down + * gray scale + * has a format of png + + diff --git a/dcmi-workshop/part2/scaling.md b/dcmi-workshop/part2/scaling.md new file mode 100644 index 00000000..82365750 --- /dev/null +++ b/dcmi-workshop/part2/scaling.md @@ -0,0 +1,17 @@ +# Image Server Scalability + + + +Horizontal scaling: + +![Diagram showing Horizontal Scaling](imgs/horizontal.jpg) + +Content Delivery Network + +![CDN](imgs/cdn.jpg) + +Further reading: + * [Getty Common Image Service](https://drive.google.com/file/d/1pB2eqlSlC4Ua5ZrEEEdJTbofl0wdDApg/view?usp%3Dsharing) - a useful comparison of Image API Servers + * [IIIF by the Numbers](https://journal.code4lib.org/articles/15217) - the UCLA image API setup and experiments + * [Evaluating HTJ2K as a Drop-In Replacement for JPEG2000 with IIIF](https://journal.code4lib.org/articles/17596) + diff --git a/dcmi-workshop/part2/uses.md b/dcmi-workshop/part2/uses.md new file mode 100644 index 00000000..c36a76fb --- /dev/null +++ b/dcmi-workshop/part2/uses.md @@ -0,0 +1,29 @@ +## Uses of the Image API + +The Image URL can be used in the same way as a normal image and has lots of practical uses. + +Embedding on web pages: + +![example iiif image](https://ids.lib.harvard.edu/ids/iiif/25286607/full/,250/0/default.jpg) + +A home teaching background for a menu: + +![menu example](./imgs/menu.jpg) + +[Smithsonian Record](https://collections.si.edu/search/detail/edanmdm:chndm_1980-32-1810-11?q=menu&iiif.enabled=true&record=116&hlterm=menu) + +## Zoom Viewer: +The most common use case is to show the image in a viewer like OpenSeaDragon: + + + + +## National Museum of Sweden + +Some places embed a IIIF Image into their content management system and it means they don't need to use the Presentation API. For example: + +[Magistrate Heurlin's Residence Truveholm in Västergötland](http://emp-web-84.zetcom.ch/eMP/eMuseumPlus?service=ExternalInterface&module=collection&objectId=26240&viewType=detailView) + +## Geo-referencing: + +The [georefrencer.com](https://www.georeferencer.com/) tool is another example which works just with the Image API. diff --git a/dcmi-workshop/part2/viewer.html b/dcmi-workshop/part2/viewer.html new file mode 100644 index 00000000..7fe5047b --- /dev/null +++ b/dcmi-workshop/part2/viewer.html @@ -0,0 +1,29 @@ + + + George and Glen's Teaching Viewer + + + + + +
+
+ + + diff --git a/dcmi-workshop/part2/viewer.js b/dcmi-workshop/part2/viewer.js new file mode 100644 index 00000000..a268bcbc --- /dev/null +++ b/dcmi-workshop/part2/viewer.js @@ -0,0 +1,591 @@ +infoJsons = {}; + +/* + * Config: + * { + * # identifer for div + * div: "div_id", + * # IIIF Images to use + * images: [ + * 'http://example.com/image1' + * ], + * # Optional regions to use + * regions: [ + 'full', + 'square' + * ], + # Optional sizes + sizes: [ + '500,' + ], + # Optional rotations + rotations: [ + '45', + '90' + ], + # Optional qualities + qualities: [ + 'default', + 'gray' + ] + * } + */ +function addViewer(config) { + let iiifContent = getURLParameter("iiif-content"); + if (iiifContent != null) { + config.images.unshift(iiifContent); + } + if (typeof addExtraImages == 'function') { + addExtraImages(config); + } + Promise.all(config.images.map(url => fetch(url + "/info.json").then(resp => cacheInfoJson(config, url, resp)))).then(addParams(config)); +} + +async function addParams(config) { + console.log('Running addParams') + let foundAll = false; + let maxCount = 1000; + let count = 0; + while (!foundAll) { + foundAll = true; + for (var i = 0; i < config.images.length; i++) { + if (config.images[i] in infoJsons) { + console.log('Awaiting ' + config.images[i]); + await infoJsons[config.images[i]]; + } else { + console.log('Not found: ' + config.images[i]); + foundAll = false; + } + } + if (count++ > maxCount) { + console.log('Failed to load images'); + return; + } + await new Promise(r => setTimeout(r, 1000)); + } + var div = document.getElementById(config.div); + + var ul = createElementStyle('ul', 'demo'); + div.appendChild(ul) + + addIdentifiers(ul, config); + addRegion(ul, config); + addSizes(ul, config); + addRotation(ul, config); + addQuality(ul, config); + addFormats(ul, config); + + var linkDiv = document.createElement('div'); + linkDiv.setAttribute('style', 'margin-bottom:20px'); + div.appendChild(linkDiv); + + var aLink = createElementStyle('a', 'centre'); + aLink.id = "link"; + aLink.setAttribute('target', '_blank'); + aLink.setAttribute('rel', 'noopener noreferrer'); + linkDiv.appendChild(aLink); + + var imgDiv = createElementStyle('div', 'iiif-image-api text-center'); + div.appendChild(imgDiv); + + var img = createElementStyle('img', 'centre'); + img.id = config.div + '_iiif-image-api-img'; + imgDiv.appendChild(img); + showImage(config.div,null); +} + +function cacheInfoJson(config, identifier, response) { + console.log('Running cache info json', identifier); + if (!(identifier in infoJsons)) { + if (!response.ok) { + console.error("Error: (" + response.status + ") " + response.statusText); + + console.log('Removing: ', identifier); + config.images.splice(config.images.indexOf(identifier), 1); + } + response.json().then((data) => { + infoJsons[identifier] = data; + }); + } +} + +function addIdentifiers(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('identifier')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Identifier')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','identifier'); + select.id = 'identifier_' + config.div; + select.onchange = function(){ showImage(config.div,'identifier'); }; + div.appendChild(select); + + addOptions('identifier_' + config.div, config.images, '', ''); +} + +function addRegion(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('region')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Region')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','region'); + select.id = 'region_' + config.div; + select.onchange = function(){ showImage(config.div,'region'); }; + div.appendChild(select); + + var regions = null; + if ('regions' in config) { + // Use supplied regions + regions = config.regions; + } + updateRegion(config.div, regions); +} + +function clearSelect(select) { + var i, L = select.options.length - 1; + for(i = L; i >= 0; i--) { + select.remove(i); + } +} + +function updateRegion(uuid, suppliedRegions) { + if (suppliedRegions) { + var regions = suppliedRegions; + } else { + var regions = ['full']; + if (supports(getCurrentImage(uuid), 'regionSquare')) { + regions.push('square'); + } + var infoJson = infoJsons[getCurrentImage(uuid)]; + if (infoJson.width > 1500 && infoJson.height > 1500) { + centerX = Math.floor(infoJson.width / 2); + centerY = Math.floor(infoJson.height / 2); + regions.push((centerX - 500) + "," + (centerY - 500) + ",1000,1000"); + } + + } + addOptions('region_' + uuid, regions, '', ''); +} +function addSizes(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('size')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Size')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','size'); + select.id = 'size_' + config.div; + select.onchange = function(){ showImage(config.div,'size'); }; + div.appendChild(select); + + if ('sizes' in config) { + // Use supplied sizes + var sizes = config.sizes; + } else { + var sizes = ['250,', '500,', '1000,']; + if (serviceVersion(getCurrentImage(config.div)) == '2') { + sizes.push('full'); + } else { + sizes.push('max'); + } + } + + addOptions('size_' + config.div, sizes, '', ''); +} + +function addRotation(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('rotation')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Rotation')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','rotation'); + select.id = 'rotation_' + config.div; + select.onchange = function(){ showImage(config.div,'rotation'); }; + div.appendChild(select); + + var rotations = null; + if ('rotations' in config) { + // Use supplied rotations + rotations = config.rotations; + } + updateRotation(config.div, rotations); +} + +function updateRotation(uuid, suppliedRotations) { + if (suppliedRotations) { + var rotations = suppliedRotations; + } else { + var rotations = ['0']; + if (supports(getCurrentImage(uuid), 'rotationBy90s')) { + rotations.push('90'); + rotations.push('180'); + rotations.push('270'); + } + if (supports(getCurrentImage(uuid), 'rotationArbitrary')) { + rotations.push('45'); + rotations.push('135'); + } + if (supports(getCurrentImage(uuid), 'mirroring')) { + rotations.push('!0'); + rotations.push('!180'); + } + } + addOptions('rotation_' + uuid, rotations, '', ''); +} + +function addOptions(identifier, options, prepend, append, selected=null) { + var select = document.getElementById(identifier); + clearSelect(select); + for (var i = 0; i < options.length; i++) { + var optionValue = options[i]; + option = document.createElement('option'); + option.text = prepend + optionValue + append; + option.value = optionValue; + + select.appendChild(option); + } + if (selected != null) { + select.value = prepend + selected + append; + } +} + +function addQuality(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('quality')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Quality')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','quality'); + select.id = 'quality_' + config.div; + select.onchange = function(){ showImage(config.div,'quality'); }; + div.appendChild(select); + + var qualities = null; + if ('qualities' in config) { + // Use supplied qualities + qualities = config.qualities; + } + updateQuality(config.div, qualities); +} + +function updateQuality(uuid, suppliedQualities) { + var select = document.getElementById('quality_' + uuid); + clearSelect(select); + if (suppliedQualities) { + var qualities = suppliedQualities; + } else { + var qualities = getImageQualities(uuid); + } + addOptions('quality_' + uuid, qualities, '', '', 'default'); +} + +function addFormats(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('format')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Format')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','format'); + select.id = 'format_' + config.div; + select.onchange = function(){ showImage(config.div,'format'); }; + div.appendChild(select); + + var formats = null; + if ('formats' in config) { + // Use supplied formats + formats = config.formats; + } + updateFormats(config.div, formats); +} + +function updateFormats(uuid, suppliedFormats) { + var select = document.getElementById('format_' + uuid); + clearSelect(select); + if (suppliedFormats) { + var formats = suppliedFormats; + } else { + var formats = getImageFormats(uuid); + } + addOptions('format_' + uuid, formats, '.', ''); +} + +function serviceVersion(image) { + var version = '2'; + if (image in infoJsons) { + var infoJson = infoJsons[image]; + if ('type' in infoJson && infoJson['type'] == "ImageService3") { + version = '3'; + } + } + return version; +} + +function getImageFormats(uuid) { + var image = getCurrentImage(uuid); + var infoJson = infoJsons[image]; + + var version = serviceVersion(image); + var formats = ['jpg']; + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object') { + if ('formats' in infoJson.profile[i]) { + for (var j = 0; j < infoJson.profile[i]['formats'].length; j++) { + if (!formats.includes(infoJson.profile[i]['formats'][j])) { + formats.push(infoJson.profile[i]['formats'][j]); + } + } + } + } else { + if (infoJson.profile[i] == "http://iiif.io/api/image/2/level2.json" && !(formats.includes('png'))) { + formats.push('png'); + } + } + } + } + } else { + if (infoJson['profile'] == 'level2') { + formats.push('png'); + } + if ('extraFormats' in infoJson) { + for (var i = 0; i < infoJson['extraFormats']; i++) { + if (!formats.includes(infoJson['extraFormats'][i])) { + formats.push(infoJson['extraFormats'][i]); + } + } + } + } + return formats; +} + +function getImageQualities(uuid) { + var image = getCurrentImage(uuid); + var infoJson = infoJsons[image]; + + var version = serviceVersion(image); + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object' && 'qualities' in infoJson.profile[i]) { + let qualities = infoJson.profile[i]['qualities']; + if (!qualities.includes("default")) { + qualities.unshift("default"); + } + return qualities; + } + } + } + return ['default']; + } else { + if ('extraQualities' in infoJson) { + return infoJson['extraQualities'] + } else { + return ['default']; + } + } +} + +function supports(image, feature) { + var infoJson = infoJsons[image]; + var version = serviceVersion(image); + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object' && 'supports' in infoJson.profile[i]) { + return infoJson.profile[i]['supports'].includes(feature); + } + } + } + return false; + } else { + if ('extraFeatures' in infoJson) { + return infoJson['extraFeatures'].includes(feature); + } + return false; + } +} + +function getCurrentImage(ident) { + var select = document.getElementById('identifier_' + ident); + return select.options[select.selectedIndex].value; +} + +function createDescription(text) { + var div = document.createElement('div'); + div.setAttribute('class', 'attr'); + div.innerHTML = text; + + return div; +} + +function createElementStyle(element, style) { + var el = document.createElement(element); + el.setAttribute('class', style); + + return el; +} + + /*
  • +
    Region
    +
    + +
    +
  • +
  • +
    Size
    + +
    +
  • +
  • +
    Rotation
    +
    + +
    +
  • +
  • +
    Quality
    +
    + +
    +
  • +
  • +
    Format
    +
    + +
    +
  • + + +
    + + +
    +
    + +
    */ + + + +function showImage(uuid, source) { + if (source == 'identifier') { + updateRegion(uuid, null); + updateRotation(uuid, null); + updateQuality(uuid, null); + updateFormats(uuid, null); + } + var identifier = getSelected(uuid, 'identifier'); + var region = getSelected(uuid, 'region'); + var size = getSelected(uuid, 'size'); + var rotation = getSelected(uuid, 'rotation'); + var quality = getSelected(uuid, 'quality'); + var format = getSelected(uuid, 'format'); + + var url = identifier + "/" + region + "/" + size + "/" + rotation + "/" + quality + "." + format; + + var link = document.getElementById('link'); + link.href = url + link.innerHTML = url + + //var img = document.getElementById('iiif-image-api-div'); + //img.style.backgroundImage = "url(" + identifier + "/full/" + size + "/0/" + quality + format + ")"; + + /*var highlight = document.getElementById('highlight'); + if (region.indexOf(',') != -1) { + coords = region.split(','); + highlight.style.top = coords[0] + "px"; + highlight.style.left = coords[1] + "px"; + highlight.style.width = coords[2] + "px"; + highlight.style.height = coords[3] + "px"; + } else if (region == "full") { + highlight.style.top = "0px"; + highlight.style.left = "0px"; + highlight.style.width = img.offsetWidth; + highlight.style.height = img.offsetHeight; + }*/ + + var img = document.getElementById(uuid + '_iiif-image-api-img'); + img.src = url; +} + +function getSelected(uuid, ident) { + var select = document.getElementById(ident + '_' + uuid); + return select.options[select.selectedIndex].value; +} + +function getURLParameter(param) { + if(typeof(param) == "string" && param.length > 0) { + if(typeof(window.location.search) == "string" && window.location.search.length > 0) { + var _results = new RegExp(param + "=([^&]*)", "i").exec(window.location.search); + if(typeof(_results) == "object" && _results !== null && typeof(_results.length) == "number" && _results.length > 0 && _results[1]) { + if(typeof(_results[1]) == "string" && _results[1].length > 0) { + return unescape(_results[1]); + } + } + } + } + return null; +} diff --git a/dcmi-workshop/part3/BL-Audio b/dcmi-workshop/part3/BL-Audio new file mode 120000 index 00000000..ae6ea7ab --- /dev/null +++ b/dcmi-workshop/part3/BL-Audio @@ -0,0 +1 @@ +../../iiif-online-workshop/day-three/BL-Audio \ No newline at end of file diff --git a/dcmi-workshop/part3/README.md b/dcmi-workshop/part3/README.md new file mode 100644 index 00000000..26aa8363 --- /dev/null +++ b/dcmi-workshop/part3/README.md @@ -0,0 +1,17 @@ +# Day Three - IIIF Presentation API +## Wednesday + +### Presentation API + +This day will focus on the IIIF Presentation API. This session will focus on [version 2.1](https://iiif.io/api/presentation/2.1/) of API and core concepts of IIIF Presentation for 2D images. The session for today is split into two videos. The first one gives a background to the IIIF Presentation API and the second one is a practical hands on session taking you through creating your first manifest. + +Prerequisite video: + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=98z9YNFiUqU) + +Main video: + + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=u63jHDH3pDM) diff --git a/dcmi-workshop/part3/bodleian-editor b/dcmi-workshop/part3/bodleian-editor new file mode 120000 index 00000000..d23a0b88 --- /dev/null +++ b/dcmi-workshop/part3/bodleian-editor @@ -0,0 +1 @@ +../../iiif-online-workshop/day-three/bodleian-editor \ No newline at end of file diff --git a/dcmi-workshop/part3/chrome-web-server b/dcmi-workshop/part3/chrome-web-server new file mode 120000 index 00000000..650f1a16 --- /dev/null +++ b/dcmi-workshop/part3/chrome-web-server @@ -0,0 +1 @@ +../../iiif-online-workshop/day-three/chrome-web-server \ No newline at end of file diff --git a/dcmi-workshop/part3/digirati-editor b/dcmi-workshop/part3/digirati-editor new file mode 120000 index 00000000..51dcab17 --- /dev/null +++ b/dcmi-workshop/part3/digirati-editor @@ -0,0 +1 @@ +../../iiif-online-workshop/day-three/digirati-editor \ No newline at end of file diff --git a/dcmi-workshop/part3/edit-a-manifest/README.md b/dcmi-workshop/part3/edit-a-manifest/README.md new file mode 100644 index 00000000..7669b8af --- /dev/null +++ b/dcmi-workshop/part3/edit-a-manifest/README.md @@ -0,0 +1,82 @@ +# Manually Editing a Manifest +The concepts of the Presentation API can be difficult to grasp until we actually start building a manifest. + +Learning by doing: In production systems (such as a digital library's image collection), manifests can get very big and are usually machine generated, but for getting the basic concepts down, there's no substitute for editing a manifest "by hand." + +## Save a Copy +Save a copy of the Manifest you created in the last lesson as `manifest2.json`. Edit `manifest2.json` for this section. + +That way you'll be sure to have a working version that you can fall back on. + +To do this in VS Code, if you right click on `manifest.json` in the Explorer window and select copy and then right click again below the `manifest.json` file and click paste it will create a copy called `manifest copy.json`. Rename this (by right clicking on the file and selecting Rename) to manifest2.json. + +## View the Manifest Copy +Load the Manifest in the [Universal Viewer](http://universalviewer.io). The URL of the copied Manifest for this section should be http://127.0.0.1:5500/manifest2.json + +## Edit Your Manifest +There are some important elements of the Manifest that we did not add or edit using the online editor. The goal of this exercise will be to edit or add them manually. Each task is linked to the specification for the property that you will need to edit or add to the Manifest. + +1. Provide a short [description](https://iiif.io/api/presentation/2.1/#description) of this manifest -- the content is up to you. +1. Modify the [attribution](https://iiif.io/api/presentation/2.1/#attribution) to the manifest that names the source of the images +1. Add the [viewingHint](https://iiif.io/api/presentation/2.1/#viewinghint) to indicate that the item is paged (i.e., should display in two-up book reader mode). + +***Note:*** the Universal Viewer at http://universalviewer.io has a bug which means it doesn't respect the viewingHint and will always show the manifest as `paged`. To test the viewingHint use this development version of the UniversalViewer that has the fix: https://www.universalviewer.dev/ + +1. Assert a Creative Commons 4.0 by-nc-sa [license](https://iiif.io/api/presentation/2.1/#license). +1. Add properties to the [metadata](https://iiif.io/api/presentation/2.1/#metadata) following the pattern described in [Language of Property Values](https://iiif.io/api/presentation/2.1/#language-of-property-values). + +Hints: + - After each step, reload the Manifest in the [Universal Viewer](http://universalviewer.io) and confirm that the changes appear. Remember that the URL of the Manifest for this section is http://127.0.0.1:5500/manifest2.json because you are editing the copy. + - Consult the [sample Manifest](https://iiif.io/api/presentation/2.1/#c-example-manifest-response) in the specification to find examples of these properties. + - If your Manifest doesn't load, first check for missing quotes or commas. + + +## A short introduction to JSON + +JSON is a structured language related to HTML and XML and defines a method of separating and structuring data that is designed for a computer to read. It is possible to edit JSON by hand but care must be taken to ensure you adhere to the rules set out in the JSON standard. + +The basic structure of a JSON object is as follows: + +``` +{ + "key":"value", + "name":"Glen", + "location":"Aberystwyth" +} +``` + +In this example JSON each of the rows is called a key value pair where the key is on the left and the value is on the right. For example the key 'name' has the value 'Glen'. Note that each key value pair has a `,` at the end apart from the last key value pair which doesn't. The `{}` brackets means this is a JSON Object with keys and values. + +The following example denoted by `[]` (Square brackets) is for a list of items: + +``` +[ + "apple", + "pear", + "orange" +] +``` + +Note again every item in the list has a `,` at the end apart from the last one. + +JSON objects and lists can be embedded which creates nested structures and this is where matching brackets becomes important so the Computer can understand which keys are part of which object. + +``` +{ + "person": { + "name":"Glen", + "location":"Aberystwyth" + "eats": [ + "apple", + "pear", + "orange" + ] + } +} +``` + +The indentation is not important for the computer in processing JSON but is important for humans so its possible to see where the brackets matchup. + +Below there is a screen shot of the same JSON in VS Code and it draws vertical lines between the brackets so you can tell which brackets match. + +![VS code JSON handling](imgs/vs_code_json.png) \ No newline at end of file diff --git a/dcmi-workshop/part3/edit-a-manifest/imgs/vs_code_json.png b/dcmi-workshop/part3/edit-a-manifest/imgs/vs_code_json.png new file mode 100644 index 00000000..d79f2bd4 Binary files /dev/null and b/dcmi-workshop/part3/edit-a-manifest/imgs/vs_code_json.png differ diff --git a/dcmi-workshop/part3/prezi-how.md b/dcmi-workshop/part3/prezi-how.md new file mode 100644 index 00000000..6556db64 --- /dev/null +++ b/dcmi-workshop/part3/prezi-how.md @@ -0,0 +1,55 @@ +# How do people create Manifests? + + + +In this workshop we are going to take you through creating a Manifest using a Manifest Editor. This works well for a small number of manifests and to give you an idea of what a Manifest contains. If you are going to create thousands or millions of manifests then you would need to look at automating this process. + +Generally the data required to create a manifest generator are as follows: + + * Accessible IIIF Images + * Structural data on how the images relate to each other. For example the order of the pages in a manuscript + * Descriptive metadata for example: + * Title - Name of the item this is called a `label` in IIIF + * Description (optional) + * Rights or licensing (optional) + * Metadata useful for discovery (optional) - this will be explained later + +Generally the format of the incoming metadata means that often these manifest generation tools are custom to each institution although there are the following libraries that can assist in the process: + + * [biiif](https://github.com/edsilv/biiif/) Organise your files according to a simple naming convention to generate IIIF v3 manifests. + * [demetsiiify](https://github.com/jbaiter/demetsiiify) - Web service for creating IIIF manifests from METS/MODS documents. + +## Presentation API Libraries + * [IIIF Manifest Generator](https://github.com/yale-web-technologies/IIIF-Manifest-Generator) - PHP library for generating IIIF manifests. + * [iiif-apis](https://github.com/dbmdz/iiif-apis) - Java IIIF API libraries. + * [iiif-prezi](https://github.com/IIIF/iiif-prezi) - Python library providing a reference implementation. + * [O'Sullivan](https://github.com/IIIF/osullivan) - Ruby API for creating IIIF manifests. + * [Swiiift](https://github.com/mejackreed/Swiiift) - IIIF presentation API library for Swift. + * [tabula-rasa](https://www.npmjs.com/package/tabula-rasa) - npm module for creating and manipulating IIIF manifests. + * [ViewDir](https://iiif-commons.github.io/) - Documentation on IIIF-related libraries and components. + +Once the Manifests are generated they can be stored on any Web Server and don't need a specific server like the Image API. + +## Important Considerations + +When publishing manifests there are a couple of considerations you need to take in account. + +### Use https not http + +Most of the web has moved to secure data transfer: `https` (http over TLS/SSL) and not `http`. If you publish your manifests as `http` it means they will not work in most online viewers and tools because browsers enforce rule forbidding mixing secure and insecure access. Using `http` will work only in unusual and restricted circumstances. + +### CORS headers are required for reuse + +Another requirement for IIIF interoperability is to enable CORS headers. CORS headers tell the browser that its OK to open this JSON on a website which doesn't match the location of your Manifest. For example it says `projectmirador.org` can open a manifest from the Library of Congress (domain `loc.gov`). Without CORS headers being set then you will only be able to open your Manifest on your website. For more details see: + +https://enable-cors.org/ + +### JSON validity + +Finally, if you are hand editing JSON documents it is very easy to miss required commas and brackets so the following tool is useful to validate your JSON: + + * [JSONLint](https://jsonlint.com/) + +If your Manifest is valid JSON but its not working in a viewer there is a IIIF Validator which will let you know if the JSON has fields that are not part of the IIIF specifications: + + * [IIIF Presentation Validator](https://iiif.io/api/presentation/validator/service/) diff --git a/europeana/prezi-intro.md b/dcmi-workshop/part3/prezi-intro.md similarity index 100% rename from europeana/prezi-intro.md rename to dcmi-workshop/part3/prezi-intro.md diff --git a/dcmi-workshop/part3/ranges b/dcmi-workshop/part3/ranges new file mode 120000 index 00000000..f75ac63b --- /dev/null +++ b/dcmi-workshop/part3/ranges @@ -0,0 +1 @@ +../../iiif-online-workshop/day-three/ranges \ No newline at end of file diff --git a/iiif-5-day-workshop/gitbook/gitbook-plugin-toggle-chapters/toggle.css b/dcmi-workshop/part3/v3-changes/README.md similarity index 100% rename from iiif-5-day-workshop/gitbook/gitbook-plugin-toggle-chapters/toggle.css rename to dcmi-workshop/part3/v3-changes/README.md diff --git a/dcmi-workshop/part3/workbench/README.md b/dcmi-workshop/part3/workbench/README.md new file mode 100644 index 00000000..01818f9a --- /dev/null +++ b/dcmi-workshop/part3/workbench/README.md @@ -0,0 +1,74 @@ +# Publishing your Manifest + +In the previous sections we have asked you to use the Chrome web server to make your manifests available. This works well for trying out your manifest but it does limit some of the tools you can use. The main issue is to do with the Chrome web server making your manifests available as http. In the last few years most web sites have moved over to https which encrypts the traffic and increases privacy. One of the restrictions of https is that it limits access to http resources which can cause problems with some IIIF tools. + +The solution to this is to use a service which will host your manifest using https and for the purposes of this course we are going to use the Workbench introduced in the [Static Images - Workbench](../../part2/image-servers/level0-workbench.md) section. This encompasses the following stages: + +1. Logon to Workbench and navigate to the Manifests section +2. Upload your Manifest +3. View your Manifest in compatible IIIF tools. +4. Making changes to your manifest + +Further details on these stages are below with screen shots: + +# Stage 1. Logon to Workbench and navigate to the Manifests section + +Navigate to the training workbench: + +[https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/index.xhtml) + +Select the project you are working on and then select the Manifests heading at the top of the page. + +![image](images/start.png) + +# Stage 2. Upload your Manifest + +Now you can upload your manifest. Click the upload button and choose the manifest you want to upload. + +![image](images/upload.png) + +You can change the name of the manifest before uploading. You may want to do this if you already have a manifest with the same name that you've uploaded previously. Ensure that the filename doesn't have any spaces or characters that aren't `.`,`-` or `_`. + +![image](images/change_name.png) + +Then click upload. The upload happens in two stages. The first is uploading the manifest to GitHub which happens quite quickly. The second stage is GitHub updating the website which can take a couple of minutes. While the website is updating you may see the following which will wait to show the Mirador and UV links until the Manifest is available on the website. + +![image](images/loading.png) + +Once you see the IIIF image and other logos it is safe to start using your manifest in other tools. + +# Stage 3. View your Manifest in compatible IIIF tools. + +Now you have a public https manifest you can start using it! There are a number of buttons underneath your manifest which is a good place to get started. + +![image](images/buttons.png) + +The buttons from left to right are as follows: + + * IIIF Logo - if you click this, it will open your manifest in a new window and show you the JSON. If you right click on the image and select `Copy link`, this is the link to your manifest which you can use in other tools. + * Edit icon - click this if you want to make small edits to your manifest. This feature is discussed further in stage 4. + * Delete icon - This will delete the manifest from your project. + * Github icon - This will take you to the GitHub location of your manifest. + * Mirador icon - click this to see your manifest in the latest version of Mirador. + * UV icon - click this to see your manifest in the public UV version. + +As well as the tools above there are also a number of other tools that work with IIIF manifests. For these you will need to copy the Manifest URL in the IIIF logo. Some other tools to try are: + + * [A guide to IIIF viewers](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013) - try your manifest in Mirador 2, Tify, IIIF Curation Viewer and Diva.js + * [exhibit.so](https://exhibit.so/) a tool for creating Exhibits or presentations of your manifests. See the [Guest Videos](../../GuestPresentations.md) for more details. + * [FromThePage](https://www.fromthepage.com/) a transcription tool. Also see the video in the [Guest Videos](../../GuestPresentations.md). + * [Recogito](https://recogito.pelagios.org/) a hosted free transcription and teaching tool. + +# Stage 4. Making changes to your manifest + +If after trying out some of the tools above you want to make some changes to your manifest. There are two ways to do it. The first is to delete the manifest from your project and upload it again. + +The second way is to click the Edit icon. This will take you into GitHub and will look something like this: + +![image](images/github_edit.png) + +You can make changes to the manifest here but be careful as the GitHub interface doesn't provide any validation for the JSON so its easy to miss a `,` or brackets. Once you have made your changes scroll to the bottom of the page where you should see: + +![image](images/github_commit.png) + +Click the commit button to save the changes to your manifest. Note although your changes will be saved straight away it will take a couple of minutes for them to be reflected in the website version of the manifest. diff --git a/dcmi-workshop/part3/workbench/images b/dcmi-workshop/part3/workbench/images new file mode 120000 index 00000000..2a9789a5 --- /dev/null +++ b/dcmi-workshop/part3/workbench/images @@ -0,0 +1 @@ +../../../iiif-online-workshop/day-three/workbench/images \ No newline at end of file diff --git a/dcmi-workshop/part3/workbench/short.md b/dcmi-workshop/part3/workbench/short.md new file mode 100644 index 00000000..4e52beb2 --- /dev/null +++ b/dcmi-workshop/part3/workbench/short.md @@ -0,0 +1,98 @@ +# Publishing your Manifest + + + +Now we have downloaded the Manifest we can use a tool developed for the training called the Workbench. This will publish your manifest using GitHub and make it available on the Web. This encompasses the following stages: + +1. Logon to Workbench and navigate to the Manifests section +2. Upload your Manifest +3. View your Manifest in compatible IIIF tools. +4. Making changes to your manifest + +Further details on these stages are below with screen shots: + +# Stage 0. Register for a GitHub account if you don't have one. + +If you don't have a GitHub account register for one on the [Github](https://github.com/) webpage. + +# Stage 1. Logon to Workbench + +Then Navigate to the training workbench: + +[https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/index.xhtml) + +You should see the following screen: + +![image](../../part2/image-servers/workbench/login.png) + +Click the Login with GitHub button. + +This will either ask you to login as shown in the following screen shot or if you are already logged in take you straight to the permissions page. + +![image](../../part2/image-servers/workbench/github_login.png) + +Next you will see the following permissions page. This is asking you if you are happy for the Workbench to write to your GitHub account. Click Authorize. + +![image](../../part2/image-servers/workbench/authorize.png) + +You should now be taken to the projects page: + +![image](../../part2/image-servers/workbench/no_project.png) + +You have now successfully logged into the Workbench using your GitHub username and password. Once you have been through the Authorisation step once your browser and GitHub will remember that you have given permission and it should log you straight in. The next stage is to create your project. + +## Stage 2. Create your project + +A project is a place to store the images and manifests you are working on. You can have multiple projects for every GitHub account but note each project is limited to 1GB in size. In the GitHub terminology a project in this case is equivalent to a GitHub Repository. + +To start click the Create Project button: + +![image](../../part2/image-servers/workbench/no_project.png) + +and enter a name for your project. Note the name can only contain letters, numbers or the following symbols `-` and `_` so don't add any spaces. + +![image](../../part2/image-servers/workbench/create_project.png) + +Click create. This will take a few seconds but will setup an empty project on GitHub and then forward you onto the images part of the Workbench. + +![image](../../part2/image-servers/workbench/no_images.png) + +You are now ready to upload your Manifest. + +# Stage 3. Upload your Manifest + +Now you can upload your manifest. Click the upload button and choose the manifest you want to upload. + +![image](images/upload.png) + +You can change the name of the manifest before uploading. You may want to do this if you already have a manifest with the same name that you've uploaded previously. Ensure that the filename doesn't have any spaces or characters that aren't `.`,`-` or `_`. + +![image](images/change_name.png) + +Then click upload. The upload happens in two stages. The first is uploading the manifest to GitHub which happens quite quickly. The second stage is GitHub updating the website which can take a couple of minutes. While the website is updating you may see the following which will wait to show the Mirador and UV links until the Manifest is available on the website. + +![image](images/loading.png) + +Once you see the IIIF image and other logos it is safe to start using your manifest in other tools. + +# Stage 4. View your Manifest in compatible IIIF tools. + +Now you have a public https manifest you can start using it! There are a number of buttons underneath your manifest which is a good place to get started. + +![image](images/buttons.png) + +The buttons from left to right are as follows: + + * IIIF Logo - if you click this, it will open your manifest in a new window and show you the JSON. If you right click on the image and select `Copy link`, this is the link to your manifest which you can use in other tools. + * Edit icon - click this if you want to make small edits to your manifest. This feature is discussed further in stage 4. + * Delete icon - This will delete the manifest from your project. + * Github icon - This will take you to the GitHub location of your manifest. + * Mirador icon - click this to see your manifest in the latest version of Mirador. + * UV icon - click this to see your manifest in the public UV version. + +As well as the tools above there are also a number of other tools that work with IIIF manifests. For these you will need to copy the Manifest URL in the IIIF logo. Some other tools to try are: + + * [A guide to IIIF viewers](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013) - try your manifest in Mirador 2, Tify, IIIF Curation Viewer and Diva.js + * [exhibit.so](https://exhibit.so/) a tool for creating Exhibits or presentations of your manifests. See the [Guest Videos](https://training.iiif.io/iiif-online-workshop/GuestPresentations.html#exhibit) for more details. + * [FromThePage](https://www.fromthepage.com/) a transcription tool. Also see the video in the [Guest Videos](https://training.iiif.io/iiif-online-workshop/GuestPresentations.html#crowdsourced-transcription-using-fromthepage--iiif). + * [Recogito](https://recogito.pelagios.org/) a hosted free transcription and teaching tool. diff --git a/dcmi-workshop/part4/README.md b/dcmi-workshop/part4/README.md new file mode 100644 index 00000000..4beb67c9 --- /dev/null +++ b/dcmi-workshop/part4/README.md @@ -0,0 +1,12 @@ +# Day 4 - Annotations +## Thursday + +The fourth day of the workshop will focus on the annotations. Participants may find it helpful to open the video in a separate window so they can follow the workshop web pages at the same time. + +### IIIF and Annotations - 1 hour + +Glen Robson the IIIF Technical Coordinator introduces annotations and IIIF by using an annotation server and looking into the IIIF Search API. + + + +This video is also available on [YouTube](https://youtu.be/y0I5_BW1OLQ) diff --git a/dcmi-workshop/part4/advanced-annotations.md b/dcmi-workshop/part4/advanced-annotations.md new file mode 100644 index 00000000..0f191d96 --- /dev/null +++ b/dcmi-workshop/part4/advanced-annotations.md @@ -0,0 +1,19 @@ +# Advanced Annotations + +There is unlikely to be time to cover this in the session but if your interested in other ways of doing annotation there is this [google slides](https://docs.google.com/presentation/d/1StVt_Eixt9wmFXoyPRjjlq-J1VevR7b4qvVmVs7yBWg/edit?usp=sharing) presentation. The links for the different examples are available below: + + * [Georeferencer for maps](https://www.georeferencer.com/) + * [Stanford Georeference example](https://www.davidrumsey.com/view/georeferencer) + * [Final site for the Cynefin data](https://places.library.wales/) + * [Visualisation of the Shipping records data](https://medium.com/@404mike/shipping-records-73e3fd48a16e#.aqxgfeogl) + * Tribunal data + * Graphs: https://iiif.gdmrdigital.com/ww1-tribunal/index.html + * Data: https://github.com/NLW-paulm/Welsh-Tribunal-annotations + * [Video on how to configure the crowdsourcing system](https://www.youtube.com/playlist?list=PLMd2mmRYjSJlKs829X0z_kYueQemSfwDd) + * [Recogito](https://recogito.pelagios.org/) + * [From the Page](https://fromthepage.com/) + * [Indigenous Digital Archive](https://omeka.dlcs-ida.org/s/ida/page/home) + * [LibCrowds from the BL](https://www.libcrowds.com/collection/playbills) + +One of the real promises of IIIF is that once you have interoperable Images and presentation packages (Manifests) it should be easy to then take these and use them in these advanced tools. In practice once you have IIIF Images and Manifests you should be able to take them and run a crowdsourcing project using one of the tools above. + diff --git a/dcmi-workshop/part4/annotating.md b/dcmi-workshop/part4/annotating.md new file mode 100644 index 00000000..1c437d50 --- /dev/null +++ b/dcmi-workshop/part4/annotating.md @@ -0,0 +1,34 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a very recently released version of the SimpleAnnotationStore. Once we have finished annotating we are going to test viewing and searching your annotations with a public viewer. + +## Step 1 find a Manifest + +If you haven't already go back to the [Finding Manifests](basics/guides.md) guide and find a Manifest from one of the public collections. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 2 Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](images/sas/login.png) + +The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +## Step 3 Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](images/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + +![image](images/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the Manifest has, this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](images/sas/manifest.png) + +Once you have finished annotating click the Home link at the top to get back to your collections. + diff --git a/dcmi-workshop/part4/annotation-linking.md b/dcmi-workshop/part4/annotation-linking.md new file mode 100644 index 00000000..ed82cb2a --- /dev/null +++ b/dcmi-workshop/part4/annotation-linking.md @@ -0,0 +1,153 @@ +# Downloading and linking your annotations + +In the last section we created a SimpleAnnotationServer (SAS) version of your manifest but now we are going to download the annotations from SAS and link them to your Workbench manifest. This is useful to create a read only copy of your annotations and you will also be able to view them using a feature of the Workbench and a tool called Annona. You will also see how annotations are connected to a manifest and how a viewer follows these links in your manifest to show annotations. + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. The overall process is as follows: + + * Step 1: Setup your environment + * Step 2: Download your annotations from SAS + * Step 3: Upload your annotations to Workbench + * Step 4: Link your manifest to the annotations + * Step 5: Exhibit your annotations with Annona + + +### Step 1: Setup your environment + +Through various iterations of this workshop we have found it easiest to save a copy of your manifest from Workbench to you computer. Make your edits to your local copy, test to make sure its working and then finally replace the Manifest on Workbench when you are happy with all of your changes. To get a copy of your Workbench manifest ready for editing: + + * Navigate to your manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the `iiif-workshop` directory you created as part of the Presentation API section and call it `manifest2.json`. If you already have a file called manifest2.json you can replace it. + * Ensure the VS Code live server is running. This should be running on port `5500` and the manifest should be available at http://127.0.0.1:5500/manifest2.json + * Open the downloaded manifest in VS Code ready for editing. + +## Step 2: Download your annotations from SAS + +Now you have finished annotating you need to download the annotations before uploading it to the Workbench. To do this you will download 1 annotation list per page or canvas. + + * Navigate back to the collections page by either clicking the Home menu item or following this link: https://dev.gdmrdigital.com/collections.xhtml + * Now click the grey "Browse Annotations" button + +![image](images/sas/browse_annos.png) + + * You should now see the canvases which have annotations. + * Click the "Download Annotations" link. + +![image](images/sas/browse_manifest.png) + +If you download this annotation file to your workshop directory. The name of the file isn't important as long as it ends in .json. + +### Step 3: Upload your annotations to Workbench + +In a new Browser tab navigate to your Workbench by going to https://workbench.gdmrdigital.com/login.xhtml and logging in. Select the project you are working on and click the Annotations section. + +![image](images/noannos.png) + +Now upload the annotations you downloaded from SAS: + +![image](images/upload_anno.png) + +Once you have uploaded your annotations you should see the screen below. + +![image](images/annos_workbench.png) + +It takes about 10mins for the Workbench to publish the annotation list to your Website but we can still copy the URL to the annotations list to move on to the next stage. To do this right click on the IIIF logo and select "Copy Link" to copy the URL of your annotations. This is what we will add to your manifest. + +![image](images/copy_annos_url.png) + +## Step 4: Link your manifest to the annotations + +To get the annotations to display you need to link them into the manifest. Open up your manifest (manifest2.json) in the `iiif-workshop` directory in VS Code. + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. Replace the URL after the `@id` with the URL you copied from Workbench. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like VS Code which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest2.json` then the link will be: + +http://127.0.0.1:5500/manifest2.json + +If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 5: Test to see if your annotations are working + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the VS Code web server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +Another method to see your annotations is with a tool using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +If you navigate to your Workbench and click the Annotations tab you should see an `Annona` button next to your annotation list: + +![image](images/sas/workbench-annoa.png) + +If you click this Annona will open in a new window. Use the arrow buttons to navigate through your annotations: + +![image](images/sas/workbench-annoa-demo.png) diff --git a/dcmi-workshop/part4/annotation-store-download-sas1.md b/dcmi-workshop/part4/annotation-store-download-sas1.md new file mode 100644 index 00000000..aab28088 --- /dev/null +++ b/dcmi-workshop/part4/annotation-store-download-sas1.md @@ -0,0 +1,163 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using the hosted SimpleAnnotationStore. Once we have finished annotating we are going to download the annotations created in an Annotation list and link them to the Manifest. This is a way of permanently attaching annotations to a manifest. + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. There are three options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This is the preferred option as it will save some steps later on. This option uses a combination of annotating the version of the manifest from your Workbench (see step [Publishing your Manifest](../part3/workbench/)) and creating a copy that you can edit and test using the Chrome Web Server. For this option you need to do the following two things: + +1. Download your manifest for editing + + * Navigate to the manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the Chrome Web Server directory + * Ensure your Chrome Web server is running. This should be running on port `8887` + * Open the downloaded manifest in [Atom](https://atom.io/) ready for editing. + +2. Copy the Manifest URL + +Now go back to your manifest in the Workbench and right click on the IIIF logo again but this time select `copy link`. This will copy the Manifest URL to your clipboard. + +### Option 2 Use manifest2.json in your Chrome Web Server + +As part of the Presentation API stage you created a file called `manifest2.json` in your Chrome Web Server directory. You can use this file and the URL: `http://localhost:8887/manifest2.json` for the annotations but note there are some extra steps you will need in the next section on presenting your annotations. + + +### Option 3 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous step you can use any IIIF Manifest. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1 Load your manifest into the hosted Mirador: + * Go to http://sas.gdmrdigital.com + * Add your manifest to the addNewObject field and click load: + * If you are using the Workbench use the URL copied from the IIIF logo. + * If you are using the Chrome web server the URL is: http://localhost:8887/manifest2.json + +![image](images/annos_download_annotating.png) + +## Step 2: annotate manifest + + * Start annotating your manifest + +![image](images/annos_download_success.png) + +## Step 3: Download annotations + +Now you have finished annotating you need to download the annotations and link them to canvases in your manifest. To do this you will download 1 annotation list per page/canvas. + + * Navigate to http://sas.gdmrdigital.com/manifests.xhtml + +You will see a list of manifests that have been annotated by the class and previous classes. You will need to search for your manifest by getting the `@id` from your manifest. For example if my manifest started with: + +``` +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://d937e822-64cd-4815-a6da-bc6a79f11619", + "@type": "sc:Manifest", + "label": "Test Manifest", + "metadata": [], +``` + +I would look for `http://d937e822-64cd-4815-a6da-bc6a79f11619` in the list of Annotated Manifests. Once you have found your manifest click the link and you should see a page similar to the following: + +![image](images/anno_download_canvas.png) + +The links at the bottom of the page are annotations for each canvas (page) you have annotated. For each canvas Right click and do save as. Save the annotations to your Google Chrome Web server folder with the name `annotations1.json`, `annotations2.json` etc... Do this step for both the Workbench and `manifest2.json` options. + +![image](images/anno_download_saveas.png) + +## Step 4: Link annotations to Manifest +To get the annotations to display you need to link them into the manifest. Open up your manifest in your Chrome Web Server directory in [Atom](https://atom.io/). + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "http://localhost:8887/annotations1.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "http://localhost:8887/annotations1.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like [ATOM](https://atom.io/) which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest2.json` then the link will be: + +http://localhost:8887/manifest2.json + +If you are using the workbench then the link will be similar but the name might be different to `mainfest2.json`. If you go to: + +http://localhost:8887/ + +You should be able to see your manifest. If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 5: check the annotations are showing + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the Chrome Web Server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +It is also possible to do the above with a locally running SimpleAnnotationServer just follow the [Annotating Stores - Do it yourself](annotations-stores-install.md) part of the course. diff --git a/dcmi-workshop/part4/annotation-store-download.md b/dcmi-workshop/part4/annotation-store-download.md new file mode 100644 index 00000000..38c5561b --- /dev/null +++ b/dcmi-workshop/part4/annotation-store-download.md @@ -0,0 +1,202 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a recently released version of the SimpleAnnotationStore. Once we have finished annotating we are going to link the annotations to your Manifest. This is a way of permanently attaching annotations to a manifest. + +The major difference with this new version of the SimpleAnnotationServer is that you are asked to login and you will have a collection of Manifests that you have annotated. The previous version only had a single user so everyone could see and edit all of the annotations. In this version only you can see your annotations until you publish them. The high level process is as follows: + + * Step 1: Create your annotations + * Step 2: Upload your annotations to Workbench + * Step 3: Link your manifest to the annotations + * Step 4: Test to see if your annotations are working + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. There are two options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This option uses a combination of annotating the version of the manifest from your Workbench (see step [Publishing your Manifest](../part3/workbench/)) and creating a copy that you can edit and test using the Chrome Web Server. For this option you need to do the following two things: + +1. Download your manifest for editing + + * Navigate to your manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the Chrome Web Server directory and call it `manifest3.json` + * Ensure your Chrome Web server is running. This should be running on port `8887` and the manifest should be available at http://localhost:8887/manifest3.json + * Open the downloaded manifest in [Atom](https://atom.io/) ready for editing. + +2. Copy the Manifest URL + +Now go back to your manifest in the Workbench and right click on the IIIF logo again but this time select `copy link`. This will copy the Manifest URL to your clipboard. + +### Option 2 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous session you can use any IIIF Manifest. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1: Create your annotations + +### Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](images/sas/login.png) + +Unlike the workbench SAS doesn't write to your Google drive or GitHub account. The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +### Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](images/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + * If you are using the Workbench use the URL copied from the IIIF logo. + * If you are using the Chrome web server the URL is: http://localhost:8887/manifest2.json + +![image](images/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the manifest takes this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](images/sas/manifest.png) + +### Annotate manifest + + * Now we have the manifest loaded into your SAS account we can start annotating. + * Click the blue "Annotate in Mirador" button. + * This should open up your manifest in Mirador + * Navigate to a page you want to annotate then click the speech bubbles at the top right to start annotating. + +![image](images/sas/annotate.png) + +## Step 2: Upload your annotations to Workbench + +### Download annotations from SAS + +Now you have finished annotating you need to download the annotations before uploading it to the Workbench. To do this you will download 1 annotation list per page or canvas. + + * Navigate back to the collections page by either clicking the Home menu item or following this link: https://dev.gdmrdigital.com/collections.xhtml + * Now click the grey "Browse Annotations" button + +![image](images/sas/browse_annos.png) + + * You should now see the canvases which have annotations. + * Click the "Download Annotations" link. + +![image](images/sas/browse_manifest.png) + +If you download this annotation file to your workshop directory. The name of the file isn't important as long as it ends in .json. + +### Upload annotations to Workbench + +In a new Browser tab navigate to your Workbench by going to https://workbench.gdmrdigital.com/login.xhtml and logging in. Select the project you are working on and click the Annotations section. + +![image](images/noannos.png) + +Now upload the annotations you downloaded from SAS: + +![image](images/upload_anno.png) + +Once you have uploaded your annotations you should see the screen below. + +![image](images/annos_workbench.png) + +It takes about 10mins for the Workbench to publish the annotation list to your Website but we can still copy the URL to the annotations list to move on to the next stage. To do this right click on the IIIF logo and select "Copy Link" to copy the URL of your annotations. This is what we will add to your manifest. + +![image](images/copy_annos_url.png) + +## Step 3: Link your manifest to the annotations + +To get the annotations to display you need to link them into the manifest. Open up your manifest in your Chrome Web Server directory in [Atom](https://atom.io/). + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. Replace the URL after the `@id` with the URL you copied from Workbench. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like [ATOM](https://atom.io/) which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest3.json` then the link will be: + +http://localhost:8887/manifest3.json + +If you are using the workbench then the link will be similar but the name might be different to `mainfest2.json`. If you go to: + +http://localhost:8887/ + +You should be able to see your manifest. If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 4: Test to see if your annotations are working + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the Chrome Web Server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +Another method to see your annotations is with a tool using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +Annona is unusal in that it takes a link to the Annotation List rather than the Manifest but if you change the URL after iiif-content below to your own Annotation List URL from workbench you should be able to browse through your annotations. + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json) diff --git a/dcmi-workshop/part4/annotations-and-annotation-lists.md b/dcmi-workshop/part4/annotations-and-annotation-lists.md new file mode 100644 index 00000000..dd185099 --- /dev/null +++ b/dcmi-workshop/part4/annotations-and-annotation-lists.md @@ -0,0 +1,122 @@ +# What are annotations? + +We have seen many examples of annotations during the course and they have many uses including: + + * Transcribing documents + * Commenting or analysis of content + * Highlighting areas of the item like hand written annotations on a printed book + * Teaching or explaining content (Storiiies and Exhibit) + +and we also saw yesterday that annotations are fundamental to how a IIIF Manifests work with images and video painted on to a canvas with annotations. + +Annotations in IIIF follow the [W3C annotation model](https://www.w3.org/TR/annotation-model/) and its precursor [Open Annotations](http://www.openannotation.org/). I will go through the differences briefly later but the model is conceptionally similar: + +![Web Annotation model](https://www.w3.org/TR/annotation-model/images/intro_model.png) + +The annotation is made up of two parts. The body which is the **resource** you want to annotate **on** to something and the target which is the thing you are annotating. Examples of bodies might be: + + * Text transcription of a line + * Video giving background to a painting + * IIIF Image painted on to a canvas + +A target might be: + * A whole canvas + * A part of a canvas (maybe a line in the transcription example above) + +## Example Annotation +A simple commenting annotation looks like the following: + +```json +{ + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +This is using Open annotations and the keys map as follows: + + * Body -> resource + * Target -> on + +Other things to take note of are: + + * motivation is `commenting` + * Annotations should have an `@id` + +In this example the body or resource is the text `Zeus seated on stool-throne`. The canvas id in this example is `http://localhost:8887/coin/canvas` and the `#xywh=3706,208,522,522` denotes we are looking at a rectangle starting `3706` pixels from the left, `208` pixels from the top and with dimensions `522` pixels wide and `522` pixels high. The image mentioned in this annotation is: + +![Coin image](https://ronallo.com/iiif-workshop-new/images/coin-side-by-side.png) + +## Caveat: Open Annotations vs Web Annotations + +For this workshop we will be focusing on Open Annotations which are in the examples above. One of the changes with IIIF version 3.0 is that we are moving to the W3C Web Annotations model. The concepts are the same but the JSON is slightly different. The transcription example now looks like: + +```json +{ + "id": "http://localhost:8887/coin/list/1", + "type": "Annotation", + "motivation": "commenting", + "body": { + "type": "TextualBody", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "target": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +The changes are: + * `@id` becomes `id` + * `@type` becomes `type` and `oa:Annotation` becomes `Annotation` + * `resource` becomes `body` + * `on` becomes `target` + * The body type changes from `cnt:ContentAsText` to `TextualBody`. + +Quite a few changes but it is defiantly clearer to understand. + +## What are annotations lists? + +See Specification Chapter: [http://iiif.io/api/presentation/2.1/#annotation-list](http://iiif.io/api/presentation/2.1/#annotation-list) + +Annotation lists are ways to group annotations and are often at a Canvas or Page level. Examples might be a transcription of a page or the OCR of a single page in annotation format. We will come back to this in the exercises but for now there is an example below. Note annotation lists are usually resolvable which means if you take the `@id` and put it into a Web Browser you should get the annotation list back. + +```json +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://localhost:8887/coin/canvas/AnnotationList", + "@type": "sc:AnnotationList", + "resources": [ + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" + }, + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "commenting", + "motivation": "sc:painting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=0,208,522,522" + } + ] +} +``` + + diff --git a/dcmi-workshop/part4/annotations-annona.md b/dcmi-workshop/part4/annotations-annona.md new file mode 100644 index 00000000..0d5019f5 --- /dev/null +++ b/dcmi-workshop/part4/annotations-annona.md @@ -0,0 +1,57 @@ +# Presenting your Annotations + +In this exercise we are going to create a presentation of our annotations using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +The overall process is as follows: + + * Create your annotations in SAS + * Get the link to your annotation list for a canvas (see previous page). + * Pass the Annotation list URL to Annona: + +`http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[Annotation List URL]` + +If you took the option of annotating the Manifest in your Workbench then you can go ahead and use Annona straight away. The URL is in the following form: + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json) + +If you used the `manifest2.json` in your Chrome Web Server there are a few extra steps. + +## Step 1 Find your Manifest ID + +The cause of this issue is the value of `@id` in your manifest doesn't match the URL that you type into the address bar of your browser. For example if you open up your manifest (http://localhost:8887/manifest2.json). You will see something similar to the following: + +``` +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://3063ff10-9dcd-47c4-a687-48df47f2c245", + "@type": "sc:Manifest", + "label": "Glen's fantastic manifest", +``` + +and the issue is `@id` should be: + +``` + "@id": "http://localhost:8887/manifest2.json", +``` + +The effect of this is that SAS has been pointing the annotations to `http://3063ff10-9dcd-47c4-a687-48df47f2c245` rather than `http://localhost:8887/manifest2.json`. For most tools like Mirador, this wouldn't be a big issue but Annona is one of the few that follows the links from the AnnotationList to the Manifest rather than from the Canvas to the AnnotationList. + +The id issue is an important point to remember and applies to Manifests, Annotation lists and Collections. The `@id` should always match the URL you put in the browser to get the JSON. This self referencing id is sometimes referred to as resolvable. For example the `@id` is __resolvable__. The original id (`http://3063ff10-9dcd-47c4-a687-48df47f2c245`) was generated by the Bodleian Manifest Editor and is meant to be unique but can't be resolvable as the Manifest Editor doesn't know where you are going to put the Manifest. + +__BUT__ for the workshop we haven't asked you to change the `@id` because if you all changed it to `http://localhost:8887/manifest2.json` when you went to SAS all of the annotations would have been combined and it would have caused chaos! + +## Step 2 Fix your Annotation list + +The fix we are going to do is to do a search and replace in the Annotation list and replace all instances of the temporary manifest id (`http://3063ff10-9dcd-47c4-a687-48df47f2c245`) with the real URL to the manifest (`http://localhost:8887/manifest2.json`). + +## Step 3 Navigate through your annotations + +Once this is done you should be able to view your annotations in the Storyboard viewer by using the following URL: + +`http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[URL to your Annotations List]` + +If you named your annotations `annotations1.json` the link would be: + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json) + + diff --git a/dcmi-workshop/part4/annotations-exercises.md b/dcmi-workshop/part4/annotations-exercises.md new file mode 100644 index 00000000..9e4204fb --- /dev/null +++ b/dcmi-workshop/part4/annotations-exercises.md @@ -0,0 +1,79 @@ +# Annotation Exercise with Mirador + +In this example we are going to have a look at Annotating in Mirador 2. Mirador 3 now supports creating annotations so future workshops will probably be based on Mirador 3. + +During the session I will go through the steps and feel free to follow along although if you get lost you can follow the instructions below. + +## Step 1 - Open Mirador + + * Go to [https://deploy-preview-13--mirador.netlify.app/demo/](https://deploy-preview-13--mirador.netlify.app/demo/) + * __Note__ now Mirador 3 is released you have to use the link above as they have moved Mirador 3 to the front page of [https://projectmirador.org](https://projectmirador.org). + +### A quick intro into using Mirador: + +The image below shows a circle around the cross at the top left of the image. Use this to close one of the windows. Then click the 4 rectangles to drop down a menu where you can select **Replace Object**. Click this to view other manifests. + +![image](images/annos_mirador.png) + +Select a Manifest by clicking on one of the rows or add your own manifest in the 'Add new object from URL'. + +![image](images/annos_select_manifest.png) + +## Step 2 - Start annotating: +Click the speech bubble on the top left + +![image](images/annos_toggle_annotations.png) + +Lots of options: + +![image](images/annos_anno_options.png) + +From left to right the buttons are: + * Speech bubble - hide annotation buttons + * Pointer - to select existing annotations and change the size or edit the content + * Rectangle - Draw a rectangle annotation + * Oval - Draw a Oval annotation + * Freeform - Go free style with the shape of the annotation + * Ploygon - Create a shape with straight sides + * Pin - Drop a pin as the target of the annotation + * Thickness - change the thickness of the shape's line + * Line colour - change the colour of the shape's line + * Fill - fill the shape with a colour. + +Once you have drawn a shape on the image you get a box where you can add content for the annotation. + +![image](images/annos_anno_options.png) + +Again you have more buttons to choose from and these are to format the content of the annotation: + * Make the text bold + * Make the text italics + * Insert a link + * Insert an image + * Insert a video or audio file + * Clear formatting + * and change orientation of the text (left/right or right/left) + +To format the text with bold or italics, type of your text then highlight it and click the bold or italics button. + +Once you have added some text click save. You can also add a tag if you like. + +You will then see a box appear and if you put your mouse over the box you will see the text you entered: + +![image](images/annos_created.png) + +Take 5 minutes to play around creating annotations so you get a feel for how it works. Also think on the following questions: + + * What type of project would this be useful for? + * What might it not work so well with? + +## Where are these annotations stored? + +This version of Mirador stores the annotations in the browser local storage. This means: + + * They are only accessible on your machine + * They are not permanent and may disappear + * Its the perfect storage location for a demo site + +## How do we make these annotations more permanent? + +With an Annotation Store. diff --git a/dcmi-workshop/part4/annotations-sas.md b/dcmi-workshop/part4/annotations-sas.md new file mode 100644 index 00000000..684a3e3e --- /dev/null +++ b/dcmi-workshop/part4/annotations-sas.md @@ -0,0 +1,75 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a recently released version of the SimpleAnnotationServer. Once we have finished annotating we are going to view the annotations in a viewer which isn't connected to the annotation server. + +The major difference with this new version of the SimpleAnnotationServer is that you are asked to login and you will have a collection of Manifests that you have annotated. The previous version only had a single user so everyone could see and edit all of the annotations. In this version only you can see your annotations until you publish them. The high level process is as follows: + + * Step 1: Load your manifest into the Annotation server + * Step 2: Create your annotations + * Step 3: Share your annotations + +There are two options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This option uses the Manifest you uploaded to the workbench in the [Publishing your Manifest](../part3/workbench/) guide. To use this manifest you need to copy the manifest URL by going to Workbench, Manifests tab and right clicking on the IIIF logo and select `Copy link`. This will copy the Manifest URL to your clipboard. + +![image](images/workbench_iiif_link.png) + +### Option 2 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous session you can use any IIIF Manifest. My personal favorite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1: Load your manifest into the Annotation server + +### Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](images/sas/login.png) + +Unlike the workbench SAS doesn't write to your Google drive or GitHub account. The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +### Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](images/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + * If you are using the Workbench use the URL copied from the IIIF logo. + +![image](images/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the manifest takes this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](images/sas/manifest.png) + +## Step 2: Create your annotations + + * Now we have the manifest loaded into your SAS account we can start annotating. + * Click the blue "Annotate in Mirador" button. + * This should open up your manifest in Mirador + * Navigate to a page you want to annotate then click the speech bubbles at the top right to start annotating. + +![image](images/sas/annotate.png) + +## Step 3: Share your annotations + +Once you have finished annotating return to the collections screen by clicking the `Home` link. We are now going to generate a copy of your Manifest with links to your annotations. The SimpleAnnotationServer provides this functionality by clicking on the Share button. + +![image](images/sas/share-annos.png) + +Once you click on the Share link the SimpleAnnotationServer will retrieve a copy of your manifest from the Workbench, add links to the annotation lists per canvas and add a link to the Search service. It will then story a copy of this new manifest in SAS for you to use. Once it has generated this new manifest you should see the screen below: + +![image](images/sas/share-annos-page.png) + +Click on the UV link or Mirador link to see your annotations in these viewers which aren't connected to an annotation server. The annotations that these viewers are reading come from the manifest. + +## Review + +Using these instructions you have a manifest which points to annotation lists and a search service that is hosted by the Simple Annotation Server (SAS). If you add more annotations using SAS they will instantly appear in the new manifest that SAS created. The newly created manifest can be shared with others and will be available as long as the SAS server is running. + +In the next section we will look at extracting the Annotations we created using SAS so they can be linked to from your original Workbench manifest. This will create a read only version of the annotations and they will be available through the workbench. diff --git a/dcmi-workshop/part4/annotations-stores-install.md b/dcmi-workshop/part4/annotations-stores-install.md new file mode 100644 index 00000000..70bfcdd9 --- /dev/null +++ b/dcmi-workshop/part4/annotations-stores-install.md @@ -0,0 +1,81 @@ +# Installing an Annotation Server (Advanced) + +We are now going to attempt to install an Annotation Server locally. This is useful if you want to try out your own annotations and keep them private. This exercise will need you to run some command line commands. + +A summary of the commands we will be using are: + +| Command | Description | +| --- | --- | +| `cd` | Change directory | +| `ls` | list directory | +| `pwd` | to show you where you are (Print Working Directory) | + +For this you will need: + +## Prerequisites + +### Java + +If you followed the Cantaloupe or Static Images exercise as part of the Image API session you may already have this. If not you will need Java 11 installed. + + - [Downloading Java 11](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) + +To verify you have the correct package installed, you can run the following command from a terminal or command prompt: + +```sh +$ java -version +# java version "1.11.0_102" +``` + +You should see version `1.11.x`. + +## Step 1: + * Download the `sas.zip` file from the latest SimpleAnnotationServer release: + +[https://github.com/glenrobson/SimpleAnnotationServer/releases](https://github.com/glenrobson/SimpleAnnotationServer/releases) + +![image](images/annos_sas_download.png) + +## Step 2: + * Extract the zip file into a `iiif-workshop` directory. + * __On windows__ make sure it is extracted by right click on the file and uncompressing. + * __Note__: this doesn't need to be in your Chrome Web server directory + +## Step 3: + * In your terminal window `cd` into the sas directory which should have been created in the last step. + +``` +MacBook-Pro:tmp gmr$ cd sas +MacBook-Pro:sas gmr$ ls +dependency simpleAnnotationStore.war +``` + +## Step 4: + * Run the SimpleAnnotationStore: + +```java -jar dependency/jetty-runner.jar --port 8888 simpleAnnotationStore.war``` + +## Step 5: + * Navigate to http://localhost:8888/index.html + * And you should see Mirador + * Navigate to an item and make an annotation. Does it save? If not ask for help + +## Step 6: + * Now add your manifest + * Go to http://localhost:8888/index.html + * Go to the list of manifests (click the big plus sign or if you are viewing a manifest click the four boxes at the top left and select 'newObject'). + * In the list of manifests paste the link to your manifest http://127.0.0.1:5500/manifest.json into the addNewObject text field and click `load`. + * You should now see: + +![image](images/annos_mirador_addItem.png) + +## Step 7: + * Click on your manifest in the list + * Add some annotations to this manifest. Do they save? + * You should now be able to use the SimpleAnnotationServer to save and search annotations. + +Extras: + + * [Loading a Newspaper example with OCR](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/PopulatingAnnotations.md) + * [Download annotations](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/DownloadAnnotations.md) + * Note as well as storing Static Images you can also host manifests and annotation lists using GitHub pages. For details on loading content to Github see the [Publishing your annotated Manifest](workbench.html). diff --git a/dcmi-workshop/part4/annotations-stores-results.md b/dcmi-workshop/part4/annotations-stores-results.md new file mode 100644 index 00000000..9332dd97 --- /dev/null +++ b/dcmi-workshop/part4/annotations-stores-results.md @@ -0,0 +1,114 @@ +# Results + +Feel for the volunteers who did all 1,000 pages! + +Exercises: + * Navigate to somebody else's section, do you see the annotations? + * Take the Manifest and view it in http://projectmirador.org/. The manifest is https://iiif.gdmrdigital.com/nlw/bor.json + * Do you see the annotations? + * Take the Manifest to the Universal Viewer: https://universalviewer.io/ + * What do you see? + + +## Looking at the annotation: + +``` +{ + "@id" : "http://35.177.224.176:8888/annotation/1559731764132", + "@type" : "oa:Annotation", + "dcterms:created" : "2019-06-05T10:49:24", + "resource" : [ { + "@id" : "_:b2", + "@type" : "dctypes:Text", + "http://dev.llgc.org.uk/sas/full_text" : "Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala", + "format" : "text/html", + "chars" : "

    Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala

    " + } ], + "on" : { + "@id" : "_:b0", + "@type" : "oa:SpecificResource", + "within" : "https://iiif.gdmrdigital.com/nlw/bor.json", + "selector" : { + "@id" : "_:b1", + "@type" : "oa:FragmentSelector", + "value" : "xywh=488,1543,2735,327" + }, + "full" : "https://damsssl.llgc.org.uk/iiif/2.0/4642022/canvas/4642029.json" + }, + "motivation" : [ "oa:commenting" ], + "@context" : "http://iiif.io/api/presentation/2/context.json" +} + +``` + +Looking more closely at the Annotation body: + +``` +

    + Ty.Sub.Lt. + Eric Hugh Allan + R.N.R + Bombala +

    +``` + +This uses RDF/A which is linked data hidden inside HTML. The HTML is what Mirador displays in the annotation but it can also be loaded to a Linked Data database and queried. For example this is looking at all the places listed in the book and putting them on a heat map: + +![image](images/annos_bor_stats_map.png) + +and this is looking at the numbers lost per ship: + +![image](images/annos_bor_ships_lost.png) + +and doing a bit more research I found: + +![image](images/annos_bor_sailors_lost.png) + +and a Newspaper article and blog post: + +![image](images/annos_bor_newspaper.png) + +and this can be tied together into a presentation using the Exhibit tool: + +[https://exhibit.so/exhibits/vjxZwSD0sgKKzQhU4r7i](https://exhibit.so/exhibits/vjxZwSD0sgKKzQhU4r7i) + + +A full export of the data is available at: https://github.com/NLW-paulm/BoR-annotations + +## Search + +Looking at the Manifest in the Universal Viewer: + +[https://universalviewer.io/examples/#?manifest=https://iiif.gdmrdigital.com/nlw/bor.json](https://universalviewer.io/examples/#?manifest=https://iiif.gdmrdigital.com/nlw/bor.json) + +We can see a search box. Can you search for the annotation you created? + +So how did that work? + +Lets have a look at the Manifest: https://iiif.gdmrdigital.com/nlw/bor.json + +The key part is this service definition: + +``` +"service": { + + "profile": "http://iiif.io/api/search/0/search", + "@id": "https://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search", + "@context": "http://iiif.io/api/search/0/context.json" + +}, +``` + +Which tells the UniversalViewer that there is a IIIF Search service available at the following location: + +http://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search + +SAS contains a basic search implementation but you can see the results here if you search for Cardiff: + +http://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search?q=Cardiff + +The search API is meant to replicate the PDF type search within so the parameters you can use are limited: + +https://iiif.io/api/search/0.9/#421-query-parameters + + diff --git a/dcmi-workshop/part4/annotations-stores.md b/dcmi-workshop/part4/annotations-stores.md new file mode 100644 index 00000000..caca200c --- /dev/null +++ b/dcmi-workshop/part4/annotations-stores.md @@ -0,0 +1,89 @@ +# Annotation Stores + +Like image servers there are a number to choose from: + +https://github.com/IIIF/awesome-iiif#annotations + +Popular ones include: + * annotot - Simple IIIF annotations mounted in a Ruby on Rails applications by Jack Reed + * Elucidate - Java and Postgres annotation server by Digirati + * SimpleAnnotationServer - Java annotation server backed by an Apache Jena triple store, Elastic Search, or Solr. - developed while working at the NLW + +A really interesting recent development is Annonatate from [Niqui O'Neill](https://twitter.com/niqui_o) from NCSU Libraries. This is a hosted annotation store which connects to your GitHub account and allows you to store your annotations publicly using GitHub Pages website. You can see examples of the annotations it creates [here](https://github.com/iiif-test/annonatate). There is a demo video here: + + + +and the application is available at [https://annonatate.herokuapp.com/](https://annonatate.herokuapp.com/). + +For this exercise we are going to be using the [SimpleAnnotationServer](https://github.com/glenrobson/SimpleAnnotationServer) and we are going to work on a copy of the Welsh Centre for International Affairs' Book of Remembrance hosted by the National Library of Wales. The live version of the books is available at: + +https://viewer.library.wales/4642022 + +### DOIs (Digital Object Identifiers) + +As an aside a question came up about DOIs. When I worked at the National Library of Wales we created DOIs for our IIIF implementation: + +http://hdl.handle.net/10107/4642022 + +This should resolve to the viewer link above. We didn't create a DOI for the Manifest because this was a 'presentation' of the resource rather than a constituent of the resource. IIIF aims to be good for presentation and doesn't serve the needs required for preservation. + +### Transcribing the Book of Remembrance + +This example will demonstrate the following: + + * Share some experiences of using Mirador in a volunteer lead example + * Use of Mirador with an annotation server + * Show some of the customisation possibilities of Mirador 2 + +We are going to use the following version which has an annotation server connected to Mirador: + +http://sas.gdmrdigital.com/examples/bor/lcc-en.html + +Mirador doesn't cope well with multiple people annotating the same page at the same time so if you can randomly choose a section: + + * Cavalry + * Corps of Lancers + * Grenadier Guards + * The Queen's (Royal West Surrey Regiment) + * The King's Own (Royal Lancaster Regiment) + * Northumberland Fusiliers + * Norfolk Regiment + * The Prince of Wales's Own (West Yorkshire Regiment) + * Canadian Expeditionary Force Service in France (right at the bottom of the book) + * New Zealand Expeditionary Force (also at the bottom) + +For this exercise only transcribe a few lines to get the feel of how the annotation would work in a practical example. As part of this project we wanted to capture not just a transcription but also the fields to allow research so we customised Mirador to capture the different fields. + +To annotate a name: + +## Step 1: + * To navigate make sure the pen and paper at the top left is disabled + * Get the line in full view + * Click the pen and paper to start annotating + * Draw a box as well as you can around the name + +![image](images/anno_bor_start.png) + + * Now type what you see (don't worry about the buttons yet). So in this example I would type `Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala` + +![image](images/anno_bor_text.png) + + * Once you've typed everything double click on a word or highlight two words if required. + +![image](images/anno_bor_highlight.png) + + * Now click the button that matches the type of the text. In this example I would click name and see the text go black: + +![image](images/anno_bor_typed.png) + + * Now do the rest: + +![image](images/anno_bor_finshed.png) + + * Then click save: + +![image](images/anno_bor_view_anno.png) + +## Crowdsourcing Results + +See [Book of Remembrance - Results](annotations-stores-results.md). diff --git a/dcmi-workshop/part4/iiif-search-api-sas1.md b/dcmi-workshop/part4/iiif-search-api-sas1.md new file mode 100644 index 00000000..7b3a0d48 --- /dev/null +++ b/dcmi-workshop/part4/iiif-search-api-sas1.md @@ -0,0 +1,51 @@ +# Searching Annotations + +In the last session we looked at downloading annotations so they could be linked to a manifest. In this session we are going to look at adding a Search service to the manifest so that the annotations you created can be searched using a IIIF Viewer. The procedure to achieve this is: + + * Index your manifest with the SimpleAnnotationServer + * Add a link to the Search service in your manifest + * Test with a IIIF Viewer + + +## Step 1: Index your manifest +The SimpleAnnotationServer supports the IIIF Search API but for it to be able to provide this service it needs to index the manifest so it as a list of Canvas Ids to search. To do this navigate to: + +http://sas.gdmrdigital.com/uploadManifest.xhtml + +and upload your Manifest. We have used http://localhost:8887/manifest2.json in previous examples. + +If this is successful then you will see a page similar to the following: + +![image](images/anno_search.png) + +This page gives details on how to add a link to the search service. Copy the URL circled in Red in the image above. + +## Step 2: Link Manifest to Search Service + +Now open up your Manifest in Atom and it should look like this: + +![image](images/annos_atom_pre_search.png) + +Now add the following JSON to the manifest after the `label`: + +``` +"service": { + "profile": "http://iiif.io/api/search/0/search", + "@id": "SEARCH_ID", + "@context": "http://iiif.io/api/search/0/context.json" +}, +``` + +Now replace the SEARCH_ID with the URL you copied earlier. In my example it would look like: + +![image](images/annos_search_api_atom.png) + +## Step 3: Test with a IIIF Viewer +Test your manifest with the Universal Viewer to see if has worked. + + * Open up http://universalviewer.io/ + * and paste your manifest http://localhost:8887/manifest2.json in the View a IIIF Manifest section + * Does it show a search box? + * Has it found an annotation? Note the search is case sensitive. + * If you add an annotation in Mirador does it show up in the search results in the UV? + diff --git a/dcmi-workshop/part4/iiif-search-api.md b/dcmi-workshop/part4/iiif-search-api.md new file mode 100644 index 00000000..92e20778 --- /dev/null +++ b/dcmi-workshop/part4/iiif-search-api.md @@ -0,0 +1,56 @@ +# Searching Annotations + +In the last session we looked at downloading annotations so they could be linked to a manifest. In this session we are going to look at adding a Search service to the manifest so that the annotations you created can be searched using a IIIF Viewer. The procedure to achieve this is: + + * Find the SAS IIIF Search URL + * Add a link to the Search service in your manifest + * Test with a IIIF Viewer + + +## Step 1: Find the IIIF Search URL + +If you navigate to your collections page either by clicking on the Home link or by navigating to: + +https://dev.gdmrdigital.com/collections.xhtml + +On the collections page click "Browse Annotations": + +![image](images/sas/collections.png) + +and then you will be taken to the Manifest page. Now select the Configure IIIF Search link highlighted below. + +![image](images/sas/manifest-search.png) + +The IIIF search page gives details on how to add a link to the search service. Copy the URL circled in Red in the image below: + +![image](images/sas/search-url.png) + +## Step 2: Link Manifest to Search Service + +Now open up your Manifest in VS Code and it should look like this: + +![image](images/annos_vscode_pre_search.png) + +Now add the following JSON to the manifest after the `label`: + +``` +"service": { + "profile": "http://iiif.io/api/search/0/search", + "@id": "SEARCH_ID", + "@context": "http://iiif.io/api/search/0/context.json" +}, +``` + +Now replace the SEARCH_ID with the URL you copied earlier. In my example it would look like: + +![image](images/sas/search-vscode.png) + +## Step 3: Test with a IIIF Viewer +Test your manifest with the Universal Viewer to see if has worked. + + * Open up http://universalviewer.io/ + * and paste your manifest http://127.0.0.1:5500/manifest2.json in the View a IIIF Manifest section + * Does it show a search box? + * Has it found an annotation? + * If you add an annotation in Mirador does it show up in the search results in the UV? + diff --git a/dcmi-workshop/part4/images b/dcmi-workshop/part4/images new file mode 120000 index 00000000..43c002db --- /dev/null +++ b/dcmi-workshop/part4/images @@ -0,0 +1 @@ +../../iiif-online-workshop/day-four/images \ No newline at end of file diff --git a/dcmi-workshop/part4/sharing.md b/dcmi-workshop/part4/sharing.md new file mode 100644 index 00000000..6dfd2229 --- /dev/null +++ b/dcmi-workshop/part4/sharing.md @@ -0,0 +1,23 @@ +# Sharing your Annotations + +Now you have created your annotations you want to share them with others. To do this make sure you are back on your Collections screen and have the collection with your Manifest selected. + +![SAS Home screen](images/annos_home.png) + +Now click the share link: + +![SAS share button](images/annos_share.png) + +Opening the Share screen will create a copy of the original Manifest and add links to the Annotations and to a IIIF Search service. The share screen gives you a link to the copied Manifest and also two large buttons to open the Manifest in Mirador and the Universal Viewer. + +![Share Manifest Screen](images/manifest_share.png) + +If you click on the Mirador link you will be taken to a public copy of Mirador. Once you navigate to the page you have annotated you should be able to click the 'hamburger' symbol to open up the left hand panel. Once open you can click on either the Annotations panel or Search Panel. + +![Mirador Annotations](images/mirador_annos.png) + +If you go back to the Share screen and click on the Universal Viewer link you will be taken to the following screen: + +![UV Annotations](images/uv_annos.png) + +Note the Universal Viewer doesn't support annotations in the same way as Mirador. To view the annotations you have to search for them using the search bar at the bottom. diff --git a/dcmi-workshop/part4/workbench.md b/dcmi-workshop/part4/workbench.md new file mode 100644 index 00000000..fbfbeb8b --- /dev/null +++ b/dcmi-workshop/part4/workbench.md @@ -0,0 +1,16 @@ +# Publishing your annotated Manifest + +Now you have finished editing your manifest and tested it is working you can upload it to your Workbench so you can share it with others. The reason we have been developing with the Chrome Web Server version is that GitHub caches all of the Website files and so it takes a while for the changes you make to appear on the Website. + +To update the manifest in Workbench click the replace button highlighted below: + +![image](images/workbench-replace.png) + +This will ask you to upload a new version of the Manifest and then will wait for the website to be updated. When you see the links to Mirador and the UV appear it should be OK to view the latest version of the manifest. You not see your changes due to the caching issue mentioned earlier so if this is the case open up a new private window or click Shift and refresh to get the latest copy. + +You should now be able to see your annotations and search service in the following places: + + * Mirador 3: https://projectmirador.org/ + * Universal Viewer: http://universalviewer.io/ + * Annona: http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[annotations_url] + diff --git a/dcmi-workshop/styles b/dcmi-workshop/styles new file mode 120000 index 00000000..6692a04a --- /dev/null +++ b/dcmi-workshop/styles @@ -0,0 +1 @@ +../iiif-online-workshop/styles \ No newline at end of file diff --git a/iiif-5-day-workshop/.gitignore b/dhsi/.gitignore similarity index 100% rename from iiif-5-day-workshop/.gitignore rename to dhsi/.gitignore diff --git a/dhsi/GuestPresentations.md b/dhsi/GuestPresentations.md new file mode 100644 index 00000000..13dfcd43 --- /dev/null +++ b/dhsi/GuestPresentations.md @@ -0,0 +1,75 @@ +# Guest presentations +During the different workshops we have organised a number of Guest presentations around different tools you can use with IIIF. These are optional videos but you may find them useful for your course project. The presentations in reverse chronological order are: + + * [Exhibit](#exhibit) + * [IIIF and AI](#iiif-and-ai) + * [Storiiies – a free online storytelling platform for everyone](#storiiies-–-a-free-online-storytelling-platform-for-everyone) + * [Supporting Teaching and Scholarship using Omeka and IIIF](#supporting-teaching-and-scholarship-using-omeka-and-iiif) + * [IIIF and AV](#iiif-and-av) + * [Crowdsourced Transcription using FromThePage & IIIF](#crowdsourced-transcription-using-fromthepage--iiif) + +### Exhibit +Guest lecture by Andrew Wilson, University of St Andrews and Ed Silverton, Mnemoscene + +Andrew and Ed give a demo of their Exhibit tool. Exhibit was developed in response to the challenge of providing an engaging and interactive experience using the museums and special collections. It addresses the sensory and tactile encounters students would have with original material + +The Exhibit tool is available at: [https://exhibit.so/](https://exhibit.so/) + + + +This was recorded on the 28th of October 2020. + +### IIIF and AI +Guest lecture by Jack Reed, Stanford University + +This workshop will showcase several projects and uses for using machine learning with IIIF content. Based on https://iiif-ml-workshop.netlify.app/docs/machine-learning-iiif/intro + + + +This was recorded on the 9th of June 2020. + +### Storiiies – a free online storytelling platform for everyone +Guest lecture by Andy Cummins, Cogapp + +Take people on a journey round your images. Pan, zoom and annotate points of interest. Whether you are telling the story of an Old Master painting, exploring the cover artwork of your favourite album or teaching a remote cohort the intricacies of an ancient papyrus, Storiiies enables clear, elegant and engaging online storytelling. + +In this presentation Andy Cummins from Cogapp will demonstrate both the editing and viewing experience of Storiiies enabling all attendees to begin creating their own stories. He will describe how you can quickly reuse the manifests and annotation lists created by the system in Mirador and other IIIF compatible viewers. + +Andy is keen to hear any feedback on Storiiies to help direct future enhancements for the good of the wider IIIF community. + + + +This was recorded on the 10th of June 2020. + +### Supporting Teaching and Scholarship using Omeka and IIIF +Guest lecture by Rachel Di Cresce, University of Toronto + +Rachel Di Cresce, Project Librarian, will review how a set of IIIF plugins developed by the University of Toronto Library for the Omeka Classic platform. The talk will outline how IIIF is used at the library and how Omkea supports classes and faculty research. + + + + +This was recorded on the 10th of June 2020. + +### IIIF and AV +Guest presentation by Andy Irving, British Library. + +Andy Irving from the British Library will talk about how they are using the new A/V features in IIIF version 3.0. + + + +This was recorded on the 11th of June 2020. + +### Crowdsourced Transcription using FromThePage & IIIF +Guest Presentation by Sara and Ben Brumfield from Brumfield labs. + +A hands on workshop that will walk you through: + * Ingesting IIIF material into FromThePage for transcription + * Configuring transcription conventions and privacy + * Discussion of how research projects have used transcription + * Advanced features in FromThePage: Translation, OCR Correction, Field Based Transcription + * Exporting & using FromThePage's IIIF API to pull transcriptions out for reuse + + + +This was recorded on the 11th of June 2020. diff --git a/dhsi/README.md b/dhsi/README.md new file mode 100644 index 00000000..0b99a252 --- /dev/null +++ b/dhsi/README.md @@ -0,0 +1,14 @@ +# Introduction + +Instructors: +* Niqui O'Neill +* Jeffrey C. Witt + + + + +This course will introduce students to the basic concepts and technologies that make IIIF possible, allowing for guided, hands-on experience in installing servers and clients that support IIIF, and utilizing the advanced functionality that IIIF provides for interactive image-based research, such as annotation. + +We will use this site to introduce lessons and exercises. Please use the sidebar navigation to move from day to day, session to session, topic to topic. diff --git a/dhsi/SUMMARY.md b/dhsi/SUMMARY.md new file mode 100644 index 00000000..0d8981aa --- /dev/null +++ b/dhsi/SUMMARY.md @@ -0,0 +1,75 @@ +## Monday + + +1. [Introductions](day-one/introductions.md) +2. [Week Overview](day-one/week-overview.md) +3. [What is IIIF](day-one/whatisiiif.md) +4. [Why use IIIF](day-one/whyiiif.md) +5. [The Image API](day-one/image-api.md) +6. [Exercise - Building an Image Viewer](day-one/image-viewer-exercise.md) +7. [Introduction to Image Hosting](day-one/image-hosting.md#introduction-to-image-hosting) + 1. [IIIF workbench](day-one/workbench.md) + 2. [Level 0 Static](day-one/level-0-static.md) + 3. [Cantaloupe](day-one/cantaloupe.md) +8. [Exercise - Integrate Your Images into Your Viewer](day-one/image-hosting.md#exercise) + +## Tuesday + + +1. [OpenSeadragon](day-two/openseadragon.md) +2. [Reflections on using the IIIF Image API](day-two/reflections.md) +3. [Json Crash Course](day-two/json-crash-course.md) +4. [IIIF Presentation API Overview](day-two/presentation-api.md) +5. [Exercise - Create a Manifest](day-two/manifest-exercise.md) + 1. [Bodleian (V2)](day-two/bodleian-editor/README.md) + 2. [Digirati (V3)](day-two/digirati-editor/README.md) + 3. [Digirati A/V](day-two/digirati-editor/Add_video_manifest.md) +7. [Adding Structures/Ranges to your Manifest](day-two/ranges.md) +8. [Auto generating Manifests](day-two/auto-generate-manifest.md) +9. [Publishing Manifests](day-two/publishing-manifests.md) + 1. [Local server](day-two/visual_studio_setup/README.md) + 2. [Workbench](day-two/workbench/README.md) + 3. [GitHub](day-two/github-publishing.md) +10. [IIIF Finding and Using Manifests](day-two/finding-and-using-manifests.md) +11. [Using/Embedding/Configuring IIIF Viewers](day-two/configuring-viewers.md) + 1. [Mirador]((day-two/configuring-viewers.md#mirador)) + 2. [Universal Viewer](day-two/uv.md) + 3. [Annona](day-two/annona.md) + 4. [Clover](day-two/clover.md) + 5. [Navplace viewer](day-two/navplace.md) +12. [Work Period]((day-two/configuring-viewers.md#work-period)) + +## Wednesday + + +1. [Introduction to Annotations](day-three/annotations.md) +2. [Creating Annotations in Annotorious](day-three/annotorious.md) +2. [Creating Annotations in Mirador](day-three/creating-annotations.md) +3. [Annotation Stores](day-three/annotations-stores.md) +4. [Annotation Server Install](day-three/annotations-stores-install.md) +5. [Simple annotation server](day-three/annotations-sas.md) +6. [Annonatate](day-three/annonatate.md) +7. [Storytelling editors](day-three/exhibit.md) +8. [Recogito](day-three/recogito.md) +9. [Other annotation platforms](day-three/annotation-other.md) +10. [Adding annotations to a manifest](day-three/annotation-in-manifest.md) +11. [IIIF Search API](day-three/iiif-search-api.md) +12. [Reusing Annotations in your website](day-three/annona.md) +13. More examples + +## Thursday + + + +1. [Advanced used cases](day-four/advanced-use-cases.md) +2. [Collections](day-four/collections.md) +1. [Wax](day-four/wax.md) +2. [Introduction to Jekyll and GitHub pages](day-four/github-jekyll-pages.md) + + + + diff --git a/dhsi/book.json b/dhsi/book.json new file mode 100644 index 00000000..697f3147 --- /dev/null +++ b/dhsi/book.json @@ -0,0 +1,25 @@ +{ + "title": "IIIF Online Workshop", + "plugins": [ + "include", + "theme-default", + "toggle-chapters", + "git-author", + "toggle-chapters" + ], + "gitbook": "3.2.3", + "styles": { + "website": "styles/website.css" + }, + "pluginsConfig": { + "theme-default": { + "showLevel": true + }, + "git-author": { + "position": "bottom", + "modifyTpl": "Last modified by {user} {timeStamp}", + "createTpl": "Created by {user} {timeStamp}", + "timeStampFormat": "YYYY-MM-DD HH:mm:ss" + } + } +} diff --git a/dhsi/day-five/2020.md b/dhsi/day-five/2020.md new file mode 100644 index 00000000..9be02201 --- /dev/null +++ b/dhsi/day-five/2020.md @@ -0,0 +1,55 @@ +# Project Demos - 2020 + +Demos from training sessions run in 2020. + +# November 2020 cohort demos +The 6 Participants from the November 2020 session produced the following demos of their work: + + + + +# October 2020 cohort demos +The 14 Participants from the October 2020 session produced the following demos of their work: + + + +# September 2020 cohort demos +The 13 Participants from the September 2020 session produced the following demos of their work: + + + +# June 2020 cohort demos +As part of the online workshop the participants were split into 5 tutor groups with a tutor who could provide assistance and guidance. At the end of the week each tutor worked with their group to give a presentation on their projects. The results of the projects can be seen below. + +### Dawn’s Group + + + +### Mike’s Group + + + +### Emma’s Group + +### Ben’s Group + + + +### Josh’s Group + + + +### Glen’s Group + + + +## Links to projects: + +Some working links mentioned in the above presentations: + + * [Reuniting dispersed manuscript leaves using IIIF](https://sxb891.github.io/iiifworkshop-m2/) + * [Trying out Mirador & annotations for transcription](https://ckarpinski.github.io/iiifworkshop-m2/) + * [Exploring Map Annotations using IIIF](https://iiif.archivelab.org/iiif/columbus-map/manifest.json) + * [Exploring Chicago Aerial Surveys and Annotations using IIIF](https://www.getty.edu/art/collection/static/viewers/mirador/?manifest=https://everreau.github.io/manifest.json) + * [Experiiiments in IIIF - UniversalViewer, Mirador, Compariscope, Storiiies and annotations](https://noirchivist.github.io/experiiiments/) + * [Working with Leonardo da Vinci’s writings and drawings](https://github.com/dhsi-iiif/dhsi-iiif.github.io/tree/master/2019/giudicirni) diff --git a/dhsi/day-five/2021.md b/dhsi/day-five/2021.md new file mode 100644 index 00000000..3330ae2b --- /dev/null +++ b/dhsi/day-five/2021.md @@ -0,0 +1,41 @@ +# Project Demos - 2021 + +Demos from training sessions run in 2021. + +# September 2021 cohort demos + +The participants from the September 2021 session produced the following demos of their work: + + + +# July 2021 cohort demos + +The participants from the July 2021 session produced the following demos of their work: + + + +# May 2021 cohort demos + +The participants from the May 2021 session produced the following demos of their work: + + + +# April 2021 cohort demos + +The participants from the April 2021 session produced the following demos of their work: + + + +# March 2021 cohort demos + +The participants from the March 2021 session produced the following demos of their work: + + + +# February 2021 cohort demos + +The 8 Participants from the February 2021 session produced the following demos of their work: + + + + diff --git a/dhsi/day-five/2022.md b/dhsi/day-five/2022.md new file mode 100644 index 00000000..b9bb86db --- /dev/null +++ b/dhsi/day-five/2022.md @@ -0,0 +1,60 @@ +# Project Demos - 2022 + +Demos from training sessions run in 2022. + +# December 2022 cohort demos + +The participants from the December 2022 session produced the following demos of their work: + + + +# November 2022 cohort demos + +The participants from the November 2022 session produced the following demos of their work: + + + +# October 2022 cohort demos + +The participants from the October 2022 session produced the following demos of their work: + + + +# September 2022 cohort demos + +The participants from the September 2022 session produced the following demos of their work: + + + +# June 2022 cohort demos + +The participants from the June 2022 session produced the following demos of their work: + + + + +# May 2022 cohort demos + +The participants from the May 2022 session produced the following demos of their work: + + + +# April 2022 cohort demos + +The participants from the April 2022 session produced the following demos of their work: + + + +# March 2022 cohort demos + +The participants from the March 2022 session produced the following demos of their work: + + + +# January 2022 cohort demos + +The participants from the January 2022 session produced the following demos of their work: + + + + diff --git a/dhsi/day-five/2023.md b/dhsi/day-five/2023.md new file mode 100644 index 00000000..9aa69dac --- /dev/null +++ b/dhsi/day-five/2023.md @@ -0,0 +1,45 @@ +# Project Demos - 2023 + +Demos from training sessions run in 2021. + +# December 2023 cohort demos + +The participants from the December 2023 session produced the following demos of their work: + + + +# September 2023 cohort demos + +The participants from the September 2023 session produced the following demos of their work: + + + +# July 2023 cohort demos + +The participants from the July 2023 session produced the following demos of their work: + + + +# May 2023 cohort demos + +The participants from the May 2023 session produced the following demos of their work: + + + +# April 2023 cohort demos + +The participants from the April 2023 session produced the following demos of their work: + + + +# March 2023 cohort demos + +The participants from the March 2023 session produced the following demos of their work: + + + +# February 2023 cohort demos + +The participants from the February 2023 session produced the following demos of their work: + + \ No newline at end of file diff --git a/dhsi/day-five/BL.md b/dhsi/day-five/BL.md new file mode 100644 index 00000000..39344cf9 --- /dev/null +++ b/dhsi/day-five/BL.md @@ -0,0 +1,31 @@ +# Day 5 Project work and report back +## Friday + +### Report back and demo zoom session + - **Aims**: + - Share participants work during the week + + +# March 2023 cohort demos + +The participants from the March 2023 session produced the following demos of their work: + + + +# March 2022 cohort demos + +The participants from the March 2022 session produced the following demos of their work: + + + +# January 2022 cohort demos + +The participants from the January 2022 session produced the following demos of their work: + + + +# November 2021 cohort demos + +The participants from the November 2021 session produced the following demos of their work: + + diff --git a/dhsi/day-five/Community.md b/dhsi/day-five/Community.md new file mode 100644 index 00000000..4b7f4a3e --- /dev/null +++ b/dhsi/day-five/Community.md @@ -0,0 +1,53 @@ +# Get involved + +IIIF is driven by the community and we would love to have you involved. + +## IIIF Slack +[Join here](http://bit.ly/iiif-slack) + +Join some of the other channels: + +* general - general discussion and announcements +* beginner - beginner questions lots of people to help +* iiif-in-the-classroom - ideas for IIIF in the classroom +* curators_of_awesome - become a curator of awesome by helping to curate: https://github.com/IIIF/awesome-iiif +* jobs - IIIF related Job announcements +* mirador - ask questions and see the latest developments with Mirador +* technical - ask difficult technical questions :-) +* wikimedia - Wikimedia related discussion + +## Community Calls + +Every two weeks topics include new starter implementation stories and the latest developments around certain topics. + +https://iiif.io/community/call/ + +## Join a Community Group + +We have content specific community groups which organise regular calls with demos and discussions: + + * [3D](https://iiif.io/community/groups/3d) + * [A/V](https://iiif.io/community/groups/av) + * [Archives](https://iiif.io/community/groups/archives) + * [Discovery for Humans](https://iiif.io/community/groups/D4H) + * [Manuscripts](https://iiif.io/community/groups/manuscripts) + * [Maps](https://iiif.io/community/groups/maps) + * [Museums](https://iiif.io/community/groups/museums) + * [Newspapers](https://iiif.io/community/groups/newspapers) + * [Outreach](https://iiif.io/community/groups/outreach) + +## Join a Technical Specification Group + +Want to help define the next version of the specification? Join a TSG group and give your use cases and contribute to the discussion. + + * [Discovery](https://iiif.io/community/groups/discovery) + * [Maps](https://iiif.io/community/groups/maps-tsg/) + * [Authentication](https://iiif.io/community/groups/auth-tsg) + * [Content Search](https://iiif.io/community/groups/content-search-tsg) + +## Stay informed + +* [Join the quarterly newsletter](https://iiif.io/newsletter/) +* [Join the IIIF Discuss email list](https://groups.google.com/forum/#!forum/iiif-discuss) + + diff --git a/dhsi/day-five/README.md b/dhsi/day-five/README.md new file mode 100644 index 00000000..ae914a16 --- /dev/null +++ b/dhsi/day-five/README.md @@ -0,0 +1,32 @@ +# Day 5 Project work and report back +## Friday + +### Report back and demo zoom session + - **Aims**: + - Share participants work during the week + +As well as the examples below there are also examples from previous years: + + * [2023](2023.md) + * [2022](2022.md) + * [2021](2021.md) + * [2020](2020.md) + +# December 2023 cohort demos + +The participants from the December 2023 session produced the following demos of their work: + + + +# September 2023 cohort demos + +The participants from the September 2023 session produced the following demos of their work: + + + +# July 2023 cohort demos + +The participants from the July 2023 session produced the following demos of their work: + + + diff --git a/dhsi/day-five/survey.md b/dhsi/day-five/survey.md new file mode 100644 index 00000000..2931ccbc --- /dev/null +++ b/dhsi/day-five/survey.md @@ -0,0 +1,19 @@ +# Survey + +We would be really grateful if you could fill in the following form. We hope to continue to improve this workshop for future participants and we would really appreciate your feedback. + +For those taking the course in September 2020 please fill in the following form: + +https://forms.gle/LwyyKHJEiteKhTvE7 + +For those self guided folks following these material we would be grateful if you could fill in the following: + +https://forms.gle/FgGg57VJD7oDwVyq7 + +Sections: + * Overall impressions + * Image API tasks + * Presentation API tasks + * Annotation tasks + * Support provided + * Suggestions diff --git a/dhsi/day-five/thankyou.md b/dhsi/day-five/thankyou.md new file mode 100644 index 00000000..5592cafc --- /dev/null +++ b/dhsi/day-five/thankyou.md @@ -0,0 +1,32 @@ +# A big Thank You + +Apart from myself this course has all been run by volunteers so I would like to give a big thank you to: + +## Course instructors + + * Mike Appleby + * Ben Albritton + +## Course Tutors + + * Josh Hadro + * Dawn Childress + * Emma Stanford + * Mike Appleby + * Ben Albritton + +## Guest Presenters + + * Sara & Ben Brumfield + * Andy Cummins + * Jack Reed + * Rachel Di Cresce + * Andy Irving + +## Slack helpers + + * Camille Villa + * Andy Irving + +## and all of you! + diff --git a/dhsi/day-four/README.md b/dhsi/day-four/README.md new file mode 100644 index 00000000..4beb67c9 --- /dev/null +++ b/dhsi/day-four/README.md @@ -0,0 +1,12 @@ +# Day 4 - Annotations +## Thursday + +The fourth day of the workshop will focus on the annotations. Participants may find it helpful to open the video in a separate window so they can follow the workshop web pages at the same time. + +### IIIF and Annotations - 1 hour + +Glen Robson the IIIF Technical Coordinator introduces annotations and IIIF by using an annotation server and looking into the IIIF Search API. + + + +This video is also available on [YouTube](https://youtu.be/y0I5_BW1OLQ) diff --git a/dhsi/day-four/advanced-annotations.md b/dhsi/day-four/advanced-annotations.md new file mode 100644 index 00000000..0f191d96 --- /dev/null +++ b/dhsi/day-four/advanced-annotations.md @@ -0,0 +1,19 @@ +# Advanced Annotations + +There is unlikely to be time to cover this in the session but if your interested in other ways of doing annotation there is this [google slides](https://docs.google.com/presentation/d/1StVt_Eixt9wmFXoyPRjjlq-J1VevR7b4qvVmVs7yBWg/edit?usp=sharing) presentation. The links for the different examples are available below: + + * [Georeferencer for maps](https://www.georeferencer.com/) + * [Stanford Georeference example](https://www.davidrumsey.com/view/georeferencer) + * [Final site for the Cynefin data](https://places.library.wales/) + * [Visualisation of the Shipping records data](https://medium.com/@404mike/shipping-records-73e3fd48a16e#.aqxgfeogl) + * Tribunal data + * Graphs: https://iiif.gdmrdigital.com/ww1-tribunal/index.html + * Data: https://github.com/NLW-paulm/Welsh-Tribunal-annotations + * [Video on how to configure the crowdsourcing system](https://www.youtube.com/playlist?list=PLMd2mmRYjSJlKs829X0z_kYueQemSfwDd) + * [Recogito](https://recogito.pelagios.org/) + * [From the Page](https://fromthepage.com/) + * [Indigenous Digital Archive](https://omeka.dlcs-ida.org/s/ida/page/home) + * [LibCrowds from the BL](https://www.libcrowds.com/collection/playbills) + +One of the real promises of IIIF is that once you have interoperable Images and presentation packages (Manifests) it should be easy to then take these and use them in these advanced tools. In practice once you have IIIF Images and Manifests you should be able to take them and run a crowdsourcing project using one of the tools above. + diff --git a/dhsi/day-four/advanced-use-cases.md b/dhsi/day-four/advanced-use-cases.md new file mode 100644 index 00000000..a059f373 --- /dev/null +++ b/dhsi/day-four/advanced-use-cases.md @@ -0,0 +1,11 @@ +# Advanced Use Cases +1. [Mirador Plugins](https://github.com/ProjectMirador/mirador-awesome) +2. [3-D](https://iiif.io/community/groups/3d/) +3. [NavPlace](https://iiif.io/api/extension/navplace/) +4. [Multilingual Annotations](https://preview.iiif.io/cookbook/0346-multilingual-annotation-body/recipe/0346-multilingual-annotation-body/) +5. [Wax](https://minicomp.github.io/wax/) +6. [Spotlight](https://exhibits.stanford.edu/) +7. Anything A/V +8. [Omeka](https://training.iiif.io/advanced_iiif/modules/omeka/) +9. [Spotlight and Annotations](https://spotlight.vatlib.it/humanist-library) +10. [Omeka](https://training.iiif.io/advanced_iiif/modules/omeka/) \ No newline at end of file diff --git a/dhsi/day-four/annotating.md b/dhsi/day-four/annotating.md new file mode 100644 index 00000000..1c437d50 --- /dev/null +++ b/dhsi/day-four/annotating.md @@ -0,0 +1,34 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a very recently released version of the SimpleAnnotationStore. Once we have finished annotating we are going to test viewing and searching your annotations with a public viewer. + +## Step 1 find a Manifest + +If you haven't already go back to the [Finding Manifests](basics/guides.md) guide and find a Manifest from one of the public collections. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 2 Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](images/sas/login.png) + +The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +## Step 3 Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](images/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + +![image](images/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the Manifest has, this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](images/sas/manifest.png) + +Once you have finished annotating click the Home link at the top to get back to your collections. + diff --git a/dhsi/day-four/annotation-linking.md b/dhsi/day-four/annotation-linking.md new file mode 100644 index 00000000..ed82cb2a --- /dev/null +++ b/dhsi/day-four/annotation-linking.md @@ -0,0 +1,153 @@ +# Downloading and linking your annotations + +In the last section we created a SimpleAnnotationServer (SAS) version of your manifest but now we are going to download the annotations from SAS and link them to your Workbench manifest. This is useful to create a read only copy of your annotations and you will also be able to view them using a feature of the Workbench and a tool called Annona. You will also see how annotations are connected to a manifest and how a viewer follows these links in your manifest to show annotations. + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. The overall process is as follows: + + * Step 1: Setup your environment + * Step 2: Download your annotations from SAS + * Step 3: Upload your annotations to Workbench + * Step 4: Link your manifest to the annotations + * Step 5: Exhibit your annotations with Annona + + +### Step 1: Setup your environment + +Through various iterations of this workshop we have found it easiest to save a copy of your manifest from Workbench to you computer. Make your edits to your local copy, test to make sure its working and then finally replace the Manifest on Workbench when you are happy with all of your changes. To get a copy of your Workbench manifest ready for editing: + + * Navigate to your manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the `iiif-workshop` directory you created as part of the Presentation API section and call it `manifest2.json`. If you already have a file called manifest2.json you can replace it. + * Ensure the VS Code live server is running. This should be running on port `5500` and the manifest should be available at http://127.0.0.1:5500/manifest2.json + * Open the downloaded manifest in VS Code ready for editing. + +## Step 2: Download your annotations from SAS + +Now you have finished annotating you need to download the annotations before uploading it to the Workbench. To do this you will download 1 annotation list per page or canvas. + + * Navigate back to the collections page by either clicking the Home menu item or following this link: https://dev.gdmrdigital.com/collections.xhtml + * Now click the grey "Browse Annotations" button + +![image](images/sas/browse_annos.png) + + * You should now see the canvases which have annotations. + * Click the "Download Annotations" link. + +![image](images/sas/browse_manifest.png) + +If you download this annotation file to your workshop directory. The name of the file isn't important as long as it ends in .json. + +### Step 3: Upload your annotations to Workbench + +In a new Browser tab navigate to your Workbench by going to https://workbench.gdmrdigital.com/login.xhtml and logging in. Select the project you are working on and click the Annotations section. + +![image](images/noannos.png) + +Now upload the annotations you downloaded from SAS: + +![image](images/upload_anno.png) + +Once you have uploaded your annotations you should see the screen below. + +![image](images/annos_workbench.png) + +It takes about 10mins for the Workbench to publish the annotation list to your Website but we can still copy the URL to the annotations list to move on to the next stage. To do this right click on the IIIF logo and select "Copy Link" to copy the URL of your annotations. This is what we will add to your manifest. + +![image](images/copy_annos_url.png) + +## Step 4: Link your manifest to the annotations + +To get the annotations to display you need to link them into the manifest. Open up your manifest (manifest2.json) in the `iiif-workshop` directory in VS Code. + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. Replace the URL after the `@id` with the URL you copied from Workbench. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like VS Code which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest2.json` then the link will be: + +http://127.0.0.1:5500/manifest2.json + +If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 5: Test to see if your annotations are working + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the VS Code web server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +Another method to see your annotations is with a tool using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +If you navigate to your Workbench and click the Annotations tab you should see an `Annona` button next to your annotation list: + +![image](images/sas/workbench-annoa.png) + +If you click this Annona will open in a new window. Use the arrow buttons to navigate through your annotations: + +![image](images/sas/workbench-annoa-demo.png) diff --git a/dhsi/day-four/annotation-store-download-sas1.md b/dhsi/day-four/annotation-store-download-sas1.md new file mode 100644 index 00000000..3e5ff6ad --- /dev/null +++ b/dhsi/day-four/annotation-store-download-sas1.md @@ -0,0 +1,163 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using the hosted SimpleAnnotationStore. Once we have finished annotating we are going to download the annotations created in an Annotation list and link them to the Manifest. This is a way of permanently attaching annotations to a manifest. + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. There are three options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This is the preferred option as it will save some steps later on. This option uses a combination of annotating the version of the manifest from your Workbench (see step [Publishing your Manifest](../day-three/workbench/)) and creating a copy that you can edit and test using the Chrome Web Server. For this option you need to do the following two things: + +1. Download your manifest for editing + + * Navigate to the manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the Chrome Web Server directory + * Ensure your Chrome Web server is running. This should be running on port `8887` + * Open the downloaded manifest in [Atom](https://atom.io/) ready for editing. + +2. Copy the Manifest URL + +Now go back to your manifest in the Workbench and right click on the IIIF logo again but this time select `copy link`. This will copy the Manifest URL to your clipboard. + +### Option 2 Use manifest2.json in your Chrome Web Server + +As part of the Presentation API stage you created a file called `manifest2.json` in your Chrome Web Server directory. You can use this file and the URL: `http://localhost:8887/manifest2.json` for the annotations but note there are some extra steps you will need in the next section on presenting your annotations. + + +### Option 3 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous step you can use any IIIF Manifest. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1 Load your manifest into the hosted Mirador: + * Go to http://sas.gdmrdigital.com + * Add your manifest to the addNewObject field and click load: + * If you are using the Workbench use the URL copied from the IIIF logo. + * If you are using the Chrome web server the URL is: http://localhost:8887/manifest2.json + +![image](images/annos_download_annotating.png) + +## Step 2: annotate manifest + + * Start annotating your manifest + +![image](images/annos_download_success.png) + +## Step 3: Download annotations + +Now you have finished annotating you need to download the annotations and link them to canvases in your manifest. To do this you will download 1 annotation list per page/canvas. + + * Navigate to http://sas.gdmrdigital.com/manifests.xhtml + +You will see a list of manifests that have been annotated by the class and previous classes. You will need to search for your manifest by getting the `@id` from your manifest. For example if my manifest started with: + +``` +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://d937e822-64cd-4815-a6da-bc6a79f11619", + "@type": "sc:Manifest", + "label": "Test Manifest", + "metadata": [], +``` + +I would look for `http://d937e822-64cd-4815-a6da-bc6a79f11619` in the list of Annotated Manifests. Once you have found your manifest click the link and you should see a page similar to the following: + +![image](images/anno_download_canvas.png) + +The links at the bottom of the page are annotations for each canvas (page) you have annotated. For each canvas Right click and do save as. Save the annotations to your Google Chrome Web server folder with the name `annotations1.json`, `annotations2.json` etc... Do this step for both the Workbench and `manifest2.json` options. + +![image](images/anno_download_saveas.png) + +## Step 4: Link annotations to Manifest +To get the annotations to display you need to link them into the manifest. Open up your manifest in your Chrome Web Server directory in [Atom](https://atom.io/). + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "http://localhost:8887/annotations1.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "http://localhost:8887/annotations1.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like [ATOM](https://atom.io/) which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest2.json` then the link will be: + +http://localhost:8887/manifest2.json + +If you are using the workbench then the link will be similar but the name might be different to `mainfest2.json`. If you go to: + +http://localhost:8887/ + +You should be able to see your manifest. If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 5: check the annotations are showing + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the Chrome Web Server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +It is also possible to do the above with a locally running SimpleAnnotationServer just follow the [Annotating Stores - Do it yourself](annotations-stores-install.md) part of the course. diff --git a/dhsi/day-four/annotation-store-download.md b/dhsi/day-four/annotation-store-download.md new file mode 100644 index 00000000..6da7a130 --- /dev/null +++ b/dhsi/day-four/annotation-store-download.md @@ -0,0 +1,203 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a recently released version of the SimpleAnnotationStore. Once we have finished annotating we are going to link the annotations to your Manifest. This is a way of permanently attaching annotations to a manifest. + +The major difference with this new version of the SimpleAnnotationServer is that you are asked to login and you will have a collection of Manifests that you have annotated. The previous version only had a single user so everyone could see and edit all of the annotations. In this version only you can see your annotations until you publish them. The high level process is as follows: + + * Step 1: Create your annotations + * Step 2: Upload your annotations to Workbench + * Step 3: Link your manifest to the annotations + * Step 4: Test to see if your annotations are working + +Note from this step forward the activities get more difficult and will involve editing your Manifest. These stages are optional and will give you a complete workflow for annotating and publishing your annotations. There are two options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This option uses a combination of annotating the version of the manifest from your Workbench (see step [Publishing your Manifest](../day-three/workbench/)) and creating a copy that you can edit and test using the Chrome Web Server. For this option you need to do the following two things: + +1. Download your manifest for editing + + * Navigate to your manifest in your workbench + * Right click on the IIIF logo and select `Save Link As` + * Save it in the Chrome Web Server directory and call it `manifest3.json` + * Ensure your Chrome Web server is running. This should be running on port `8887` and the manifest should be available at http://localhost:8887/manifest3.json + * Open the downloaded manifest in [Atom](https://atom.io/) ready for editing. + +2. Copy the Manifest URL + +Now go back to your manifest in the Workbench and right click on the IIIF logo again but this time select `copy link`. This will copy the Manifest URL to your clipboard. + +### Option 2 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous session you can use any IIIF Manifest. My personal favourite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1: Create your annotations + +### Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](images/sas/login.png) + +Unlike the workbench SAS doesn't write to your Google drive or GitHub account. The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +### Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](images/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + * If you are using the Workbench use the URL copied from the IIIF logo. + * If you are using the Chrome web server the URL is: http://localhost:8887/manifest2.json + +![image](images/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the manifest takes this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](images/sas/manifest.png) + +### Annotate manifest + + * Now we have the manifest loaded into your SAS account we can start annotating. + * Click the blue "Annotate in Mirador" button. + * This should open up your manifest in Mirador + * Navigate to a page you want to annotate then click the speech bubbles at the top right to start annotating. + +![image](images/sas/annotate.png) + +## Step 2: Upload your annotations to Workbench + +### Download annotations from SAS + +Now you have finished annotating you need to download the annotations before uploading it to the Workbench. To do this you will download 1 annotation list per page or canvas. + + * Navigate back to the collections page by either clicking the Home menu item or following this link: https://dev.gdmrdigital.com/collections.xhtml + * Now click the grey "Browse Annotations" button + +![image](images/sas/browse_annos.png) + + * You should now see the canvases which have annotations. + * Click the "Download Annotations" link. + +![image](images/sas/browse_manifest.png) + +If you download this annotation file to your workshop directory. The name of the file isn't important as long as it ends in .json. + +### Upload annotations to Workbench + +In a new Browser tab navigate to your Workbench by going to https://workbench.gdmrdigital.com/login.xhtml and logging in. Select the project you are working on and click the Annotations section. + +![image](images/noannos.png) + +Now upload the annotations you downloaded from SAS: + +![image](images/upload_anno.png) + +Once you have uploaded your annotations you should see the screen below. + +![image](images/annos_workbench.png) + +It takes about 10mins for the Workbench to publish the annotation list to your Website but we can still copy the URL to the annotations list to move on to the next stage. To do this right click on the IIIF logo and select "Copy Link" to copy the URL of your annotations. This is what we will add to your manifest. + +![image](images/copy_annos_url.png) + +## Step 3: Link your manifest to the annotations + +To get the annotations to display you need to link them into the manifest. Open up your manifest in your Chrome Web Server directory in [Atom](https://atom.io/). + +Then find the canvas your annotations point to then add the following: + +```json +"otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +after the images array. Replace the URL after the `@id` with the URL you copied from Workbench. A full canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like [ATOM](https://atom.io/) which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. + +Now test your edited manifest in the browser to check it looks OK. If you are using `manifest3.json` then the link will be: + +http://localhost:8887/manifest3.json + +If you are using the workbench then the link will be similar but the name might be different to `mainfest2.json`. If you go to: + +http://localhost:8887/ + +You should be able to see your manifest. If you click on your manifest you should see the JSON. If you copy the URL in the browser address bar you will have the Manifest URL for your edited manifest. + +## Step 4: Test to see if your annotations are working + + * Go to http://iiif.gdmrdigital.com/mirador/index.html. + * Load the manifest using Add new object from URL (using the manifest hosted in the Chrome Web Server) + * Click on one of the images to view the manifest + * Click on the speech bubble to show the annotations. + +![image](images/annos_download_show.png) + + * and if it all worked OK you should see your annotation. + +![image](images/annos_download_success.png) + + +Another method to see your annotations is with a tool using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +Annona is unusal in that it takes a link to the Annotation List rather than the Manifest but if you change the URL after iiif-content below to your own Annotation List URL from workbench you should be able to browse through your annotations. + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json) + diff --git a/dhsi/day-four/annotations-and-annotation-lists.md b/dhsi/day-four/annotations-and-annotation-lists.md new file mode 100644 index 00000000..dd185099 --- /dev/null +++ b/dhsi/day-four/annotations-and-annotation-lists.md @@ -0,0 +1,122 @@ +# What are annotations? + +We have seen many examples of annotations during the course and they have many uses including: + + * Transcribing documents + * Commenting or analysis of content + * Highlighting areas of the item like hand written annotations on a printed book + * Teaching or explaining content (Storiiies and Exhibit) + +and we also saw yesterday that annotations are fundamental to how a IIIF Manifests work with images and video painted on to a canvas with annotations. + +Annotations in IIIF follow the [W3C annotation model](https://www.w3.org/TR/annotation-model/) and its precursor [Open Annotations](http://www.openannotation.org/). I will go through the differences briefly later but the model is conceptionally similar: + +![Web Annotation model](https://www.w3.org/TR/annotation-model/images/intro_model.png) + +The annotation is made up of two parts. The body which is the **resource** you want to annotate **on** to something and the target which is the thing you are annotating. Examples of bodies might be: + + * Text transcription of a line + * Video giving background to a painting + * IIIF Image painted on to a canvas + +A target might be: + * A whole canvas + * A part of a canvas (maybe a line in the transcription example above) + +## Example Annotation +A simple commenting annotation looks like the following: + +```json +{ + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +This is using Open annotations and the keys map as follows: + + * Body -> resource + * Target -> on + +Other things to take note of are: + + * motivation is `commenting` + * Annotations should have an `@id` + +In this example the body or resource is the text `Zeus seated on stool-throne`. The canvas id in this example is `http://localhost:8887/coin/canvas` and the `#xywh=3706,208,522,522` denotes we are looking at a rectangle starting `3706` pixels from the left, `208` pixels from the top and with dimensions `522` pixels wide and `522` pixels high. The image mentioned in this annotation is: + +![Coin image](https://ronallo.com/iiif-workshop-new/images/coin-side-by-side.png) + +## Caveat: Open Annotations vs Web Annotations + +For this workshop we will be focusing on Open Annotations which are in the examples above. One of the changes with IIIF version 3.0 is that we are moving to the W3C Web Annotations model. The concepts are the same but the JSON is slightly different. The transcription example now looks like: + +```json +{ + "id": "http://localhost:8887/coin/list/1", + "type": "Annotation", + "motivation": "commenting", + "body": { + "type": "TextualBody", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "target": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +The changes are: + * `@id` becomes `id` + * `@type` becomes `type` and `oa:Annotation` becomes `Annotation` + * `resource` becomes `body` + * `on` becomes `target` + * The body type changes from `cnt:ContentAsText` to `TextualBody`. + +Quite a few changes but it is defiantly clearer to understand. + +## What are annotations lists? + +See Specification Chapter: [http://iiif.io/api/presentation/2.1/#annotation-list](http://iiif.io/api/presentation/2.1/#annotation-list) + +Annotation lists are ways to group annotations and are often at a Canvas or Page level. Examples might be a transcription of a page or the OCR of a single page in annotation format. We will come back to this in the exercises but for now there is an example below. Note annotation lists are usually resolvable which means if you take the `@id` and put it into a Web Browser you should get the annotation list back. + +```json +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://localhost:8887/coin/canvas/AnnotationList", + "@type": "sc:AnnotationList", + "resources": [ + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" + }, + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "commenting", + "motivation": "sc:painting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=0,208,522,522" + } + ] +} +``` + + diff --git a/dhsi/day-four/annotations-annona.md b/dhsi/day-four/annotations-annona.md new file mode 100644 index 00000000..0d5019f5 --- /dev/null +++ b/dhsi/day-four/annotations-annona.md @@ -0,0 +1,57 @@ +# Presenting your Annotations + +In this exercise we are going to create a presentation of our annotations using the [Annona Storyboard viewer](https://ncsu-libraries.github.io/annona/) by Niqui O'Neill from NC State University Libraries. This will demonstrate the interoperability of these annotations and also provide an option for the end of week projects. Annona is a powerful tool to create stories from annotations and supports a wide variety of use cases. The most important one for this lesson is to support annotations created by the SimpleAnnotationServer (SAS). + +The overall process is as follows: + + * Create your annotations in SAS + * Get the link to your annotation list for a canvas (see previous page). + * Pass the Annotation list URL to Annona: + +`http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[Annotation List URL]` + +If you took the option of annotating the Manifest in your Workbench then you can go ahead and use Annona straight away. The URL is in the following form: + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json) + +If you used the `manifest2.json` in your Chrome Web Server there are a few extra steps. + +## Step 1 Find your Manifest ID + +The cause of this issue is the value of `@id` in your manifest doesn't match the URL that you type into the address bar of your browser. For example if you open up your manifest (http://localhost:8887/manifest2.json). You will see something similar to the following: + +``` +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://3063ff10-9dcd-47c4-a687-48df47f2c245", + "@type": "sc:Manifest", + "label": "Glen's fantastic manifest", +``` + +and the issue is `@id` should be: + +``` + "@id": "http://localhost:8887/manifest2.json", +``` + +The effect of this is that SAS has been pointing the annotations to `http://3063ff10-9dcd-47c4-a687-48df47f2c245` rather than `http://localhost:8887/manifest2.json`. For most tools like Mirador, this wouldn't be a big issue but Annona is one of the few that follows the links from the AnnotationList to the Manifest rather than from the Canvas to the AnnotationList. + +The id issue is an important point to remember and applies to Manifests, Annotation lists and Collections. The `@id` should always match the URL you put in the browser to get the JSON. This self referencing id is sometimes referred to as resolvable. For example the `@id` is __resolvable__. The original id (`http://3063ff10-9dcd-47c4-a687-48df47f2c245`) was generated by the Bodleian Manifest Editor and is meant to be unique but can't be resolvable as the Manifest Editor doesn't know where you are going to put the Manifest. + +__BUT__ for the workshop we haven't asked you to change the `@id` because if you all changed it to `http://localhost:8887/manifest2.json` when you went to SAS all of the annotations would have been combined and it would have caused chaos! + +## Step 2 Fix your Annotation list + +The fix we are going to do is to do a search and replace in the Annotation list and replace all instances of the temporary manifest id (`http://3063ff10-9dcd-47c4-a687-48df47f2c245`) with the real URL to the manifest (`http://localhost:8887/manifest2.json`). + +## Step 3 Navigate through your annotations + +Once this is done you should be able to view your annotations in the Storyboard viewer by using the following URL: + +`http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[URL to your Annotations List]` + +If you named your annotations `annotations1.json` the link would be: + +[http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json](http://iiif.gdmrdigital.com/annona/index.html?iiif-content=http://localhost:8887/annotations1.json) + + diff --git a/dhsi/day-four/annotations-exercises.md b/dhsi/day-four/annotations-exercises.md new file mode 100644 index 00000000..73169473 --- /dev/null +++ b/dhsi/day-four/annotations-exercises.md @@ -0,0 +1,79 @@ +# Annotation Exercises + +In this example we are going to have a look at Annotating in Mirador 2. Mirador 3 now supports creating annotations so future workshops will probably be based on Mirador 3. + +During the session I will go through the steps and feel free to follow along although if you get lost you can follow the instructions below. + +## Step 1 - Open Mirador + + * Go to [https://deploy-preview-13--mirador.netlify.app/demo/](https://deploy-preview-13--mirador.netlify.app/demo/) + * __Note__ now Mirador 3 is released you have to use the link above as they have moved Mirador 3 to the front page of [https://projectmirador.org](https://projectmirador.org). + +### A quick intro into using Mirador: + +The image below shows a circle around the cross at the top left of the image. Use this to close one of the windows. Then click the 4 rectangles to drop down a menu where you can select **Replace Object**. Click this to view other manifests. + +![](imgs/annos_mirador.png) + +Select a Manifest by clicking on one of the rows or add your own manifest in the 'Add new object from URL'. + +![](imgs/annos_select_manifest.png) + +## Step 2 - Start annotating: +Click the speech bubble on the top left + +![](imgs/annos_toggle_annotations.png) + +Lots of options: + +![](imgs/annos_anno_options.png) + +From left to right the buttons are: + * Speech bubble - hide annotation buttons + * Pointer - to select existing annotations and change the size or edit the content + * Rectangle - Draw a rectangle annotation + * Oval - Draw a Oval annotation + * Freeform - Go free style with the shape of the annotation + * Ploygon - Create a shape with straight sides + * Pin - Drop a pin as the target of the annotation + * Thickness - change the thickness of the shape's line + * Line colour - change the colour of the shape's line + * Fill - fill the shape with a colour. + +Once you have drawn a shape on the image you get a box where you can add content for the annotation. + +![image](imgs/annos_anno_options.png) + +Again you have more buttons to choose from and these are to format the content of the annotation: + * Make the text bold + * Make the text italics + * Insert a link + * Insert an image + * Insert a video or audio file + * Clear formatting + * and change orientation of the text (left/right or right/left) + +To format the text with bold or italics, type of your text then highlight it and click the bold or italics button. + +Once you have added some text click save. You can also add a tag if you like. + +You will then see a box appear and if you put your mouse over the box you will see the text you entered: + +![image](imgs/annos_created.png) + +Take 5 minutes to play around creating annotations so you get a feel for how it works. Also think on the following questions: + + * What type of project would this be useful for? + * What might it not work so well with? + +## Where are these annotations stored? + +This version of Mirador stores the annotations in the browser local storage. This means: + + * They are only accessible on your machine + * They are not permanent and may disappear + * Its the perfect storage location for a demo site + +## How do we make these annotations more permanent? + +With an Annotation Store. diff --git a/dhsi/day-four/annotations-stores-results.md b/dhsi/day-four/annotations-stores-results.md new file mode 100644 index 00000000..9332dd97 --- /dev/null +++ b/dhsi/day-four/annotations-stores-results.md @@ -0,0 +1,114 @@ +# Results + +Feel for the volunteers who did all 1,000 pages! + +Exercises: + * Navigate to somebody else's section, do you see the annotations? + * Take the Manifest and view it in http://projectmirador.org/. The manifest is https://iiif.gdmrdigital.com/nlw/bor.json + * Do you see the annotations? + * Take the Manifest to the Universal Viewer: https://universalviewer.io/ + * What do you see? + + +## Looking at the annotation: + +``` +{ + "@id" : "http://35.177.224.176:8888/annotation/1559731764132", + "@type" : "oa:Annotation", + "dcterms:created" : "2019-06-05T10:49:24", + "resource" : [ { + "@id" : "_:b2", + "@type" : "dctypes:Text", + "http://dev.llgc.org.uk/sas/full_text" : "Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala", + "format" : "text/html", + "chars" : "

    Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala

    " + } ], + "on" : { + "@id" : "_:b0", + "@type" : "oa:SpecificResource", + "within" : "https://iiif.gdmrdigital.com/nlw/bor.json", + "selector" : { + "@id" : "_:b1", + "@type" : "oa:FragmentSelector", + "value" : "xywh=488,1543,2735,327" + }, + "full" : "https://damsssl.llgc.org.uk/iiif/2.0/4642022/canvas/4642029.json" + }, + "motivation" : [ "oa:commenting" ], + "@context" : "http://iiif.io/api/presentation/2/context.json" +} + +``` + +Looking more closely at the Annotation body: + +``` +

    + Ty.Sub.Lt. + Eric Hugh Allan + R.N.R + Bombala +

    +``` + +This uses RDF/A which is linked data hidden inside HTML. The HTML is what Mirador displays in the annotation but it can also be loaded to a Linked Data database and queried. For example this is looking at all the places listed in the book and putting them on a heat map: + +![image](images/annos_bor_stats_map.png) + +and this is looking at the numbers lost per ship: + +![image](images/annos_bor_ships_lost.png) + +and doing a bit more research I found: + +![image](images/annos_bor_sailors_lost.png) + +and a Newspaper article and blog post: + +![image](images/annos_bor_newspaper.png) + +and this can be tied together into a presentation using the Exhibit tool: + +[https://exhibit.so/exhibits/vjxZwSD0sgKKzQhU4r7i](https://exhibit.so/exhibits/vjxZwSD0sgKKzQhU4r7i) + + +A full export of the data is available at: https://github.com/NLW-paulm/BoR-annotations + +## Search + +Looking at the Manifest in the Universal Viewer: + +[https://universalviewer.io/examples/#?manifest=https://iiif.gdmrdigital.com/nlw/bor.json](https://universalviewer.io/examples/#?manifest=https://iiif.gdmrdigital.com/nlw/bor.json) + +We can see a search box. Can you search for the annotation you created? + +So how did that work? + +Lets have a look at the Manifest: https://iiif.gdmrdigital.com/nlw/bor.json + +The key part is this service definition: + +``` +"service": { + + "profile": "http://iiif.io/api/search/0/search", + "@id": "https://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search", + "@context": "http://iiif.io/api/search/0/context.json" + +}, +``` + +Which tells the UniversalViewer that there is a IIIF Search service available at the following location: + +http://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search + +SAS contains a basic search implementation but you can see the results here if you search for Cardiff: + +http://sas.gdmrdigital.com/search-api/cabbb6de5303266bd9adc6cb23fb5c1b/search?q=Cardiff + +The search API is meant to replicate the PDF type search within so the parameters you can use are limited: + +https://iiif.io/api/search/0.9/#421-query-parameters + + diff --git a/dhsi/day-four/collections.md b/dhsi/day-four/collections.md new file mode 100644 index 00000000..bc86b806 --- /dev/null +++ b/dhsi/day-four/collections.md @@ -0,0 +1,24 @@ +# Collections +Collections are a way to semantically link multiple different manifests. It allows for linking materials either through concrete or abstract groupings. + +An example can seen in the [IIIF cookbook recipe](https://iiif.io/api/cookbook/recipe/0032-collection/). + + +## Other collection examples + +1. [National Gallery, London](https://research.ng-london.org.uk/iiif-projects/json/ng-projects.json) +2. [FromThePage Jeremiah White Graves Diaries](https://fromthepage.com/iiif/collection/jeremiah-white-graves-diaries) +3. [Staedel Museum](https://iiif.manducus.net/collections/0008/collection.json) +4. [Zeppelin Museum Friedrichshafen](https://iiif.manducus.net/collections/0012/collection.json) +5. [Fotothek](https://sachsen.museum-digital.de/apis/iiif-presentation/collection/c231) +6. [The biological basis of medicine / edited by E. Edward Bittar ; assisted by Neville Bittar.](https://iiif.wellcomecollection.org/presentation/v2/b18031511) +7. [e-codices – Virtual Manuscript Library of Switzerland](https://www.e-codices.ch/metadata/iiif/collection.json) +8. [e-manuscripta](https://www.e-manuscripta.ch/i3f/v21/collection/top) +9. [e-rara](https://www.e-rara.ch/i3f/v21/collection/top) +10. [fragmentarium – International Digital Research Lab for Medieval Manuscript Fragments](https://fragmentarium.ms/metadata/iiif/collection.json) +11. [IIIF Collection for Leipzig University Library](https://iiif.ub.uni-leipzig.de/static/collections/toplevel.json) +13. [Luke Wadding Papers](https://data.ucd.ie/api/img/collection/ivrla:18726) +14. [Arabic documents](https://iiif.durham.ac.uk/manifests/trifle/collection/32150/t2c9k41zd486) +15. [We are ISU- Snapshots of Student Life](https://cdm16001.contentdm.oclc.org/iiif/info/p16001coll48/manifest.json) +16. [Air Scoop](https://digital.lib.utk.edu/assemble/collection/collections/ascoop) +17. [Collection de Charles V (roi de France, 1338-1380)](https://portail.biblissima.fr/iiif/collection/ark:/43093/coldataa9d9a2d98084b67becd2c1a78c78e4d6143e35da) diff --git a/dhsi/day-four/github-jekyll-pages.md b/dhsi/day-four/github-jekyll-pages.md new file mode 100644 index 00000000..d576869c --- /dev/null +++ b/dhsi/day-four/github-jekyll-pages.md @@ -0,0 +1,23 @@ +# Jekyll +Jekyll is a static site generator. A static site generator is a framework that allows the creation of static html pages without having to manually code them. For example, if you want your website to have a header image on every page if you were to write that in HTML you would have to add the code for the header in every page. static site generators allows you to write the code for the header image in one file and define how the page looks by layouts. + +- [NC Architects and Builders](https://ncarchitects.lib.ncsu.edu) +- [Honoring the Fallen: An Interactive Memorial Map](https://falveydigitalscholarship.github.io/honoringthefallen) +- [Annonatate](https://annonatate.github.io/annonatate/) +- [Code4Lib Conference Website](https://2024.code4lib.org/) +- [Wax](https://minicomp.github.io/wax/) + +# Jekyll Themes + Plugins +## [Themes](https://jekyllrb.com/docs/themes/) +Jekyll also provides a number of open source themes which provide a framework for a website that allows you to add your own data to a pre-exising framework without having to do a bunch of coding. "Honoring the Fallen: An Interactive Memorial Map" use a theme called Flaneur. + +## [Plugins](https://jekyllrb.com/docs/plugins/) +Jekyll also provides a way to create your own plugins or use existing plugins. They allow you create custom code for your site without having to modify the Jekyll source code. Plugins include those that provide search, pagination, and CMS graphical interface. + +# GitHub pages +GitHub pages is a static site hosting that will host any static file. We have gone over how to [enable a GitHub pages site](/day-two/github-publishing.html). If you use any static site generator other than Jekyll you will have to run the command for building the static site either in your command line or using [GitHub actions](https://docs.github.com/en/actions). GitHub actions are basically virtual environments that allow you install dependencies, run any command line arguments and write to your GitHub repository. Using a [GitHub actions](https://github.com/dnoneill/dhsi-iiif-2024/blob/main/.github/workflows/biiif.yml) was how we were able [autogenerate a manifest](/day-two/auto-generate-manifest.html). + + +# Other Static Site generators +- [Hugo](https://gohugo.io/) - Main selling point is build speed +- [Astro.js](https://astro.build/) - Allows integration of other frameworks including React, Vue.js, etc. \ No newline at end of file diff --git a/dhsi/day-four/iiif-search-api-sas1.md b/dhsi/day-four/iiif-search-api-sas1.md new file mode 100644 index 00000000..7b3a0d48 --- /dev/null +++ b/dhsi/day-four/iiif-search-api-sas1.md @@ -0,0 +1,51 @@ +# Searching Annotations + +In the last session we looked at downloading annotations so they could be linked to a manifest. In this session we are going to look at adding a Search service to the manifest so that the annotations you created can be searched using a IIIF Viewer. The procedure to achieve this is: + + * Index your manifest with the SimpleAnnotationServer + * Add a link to the Search service in your manifest + * Test with a IIIF Viewer + + +## Step 1: Index your manifest +The SimpleAnnotationServer supports the IIIF Search API but for it to be able to provide this service it needs to index the manifest so it as a list of Canvas Ids to search. To do this navigate to: + +http://sas.gdmrdigital.com/uploadManifest.xhtml + +and upload your Manifest. We have used http://localhost:8887/manifest2.json in previous examples. + +If this is successful then you will see a page similar to the following: + +![image](images/anno_search.png) + +This page gives details on how to add a link to the search service. Copy the URL circled in Red in the image above. + +## Step 2: Link Manifest to Search Service + +Now open up your Manifest in Atom and it should look like this: + +![image](images/annos_atom_pre_search.png) + +Now add the following JSON to the manifest after the `label`: + +``` +"service": { + "profile": "http://iiif.io/api/search/0/search", + "@id": "SEARCH_ID", + "@context": "http://iiif.io/api/search/0/context.json" +}, +``` + +Now replace the SEARCH_ID with the URL you copied earlier. In my example it would look like: + +![image](images/annos_search_api_atom.png) + +## Step 3: Test with a IIIF Viewer +Test your manifest with the Universal Viewer to see if has worked. + + * Open up http://universalviewer.io/ + * and paste your manifest http://localhost:8887/manifest2.json in the View a IIIF Manifest section + * Does it show a search box? + * Has it found an annotation? Note the search is case sensitive. + * If you add an annotation in Mirador does it show up in the search results in the UV? + diff --git a/iiif-5-day-workshop/images/anno_bor_finshed.png b/dhsi/day-four/images/anno_bor_finshed.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_finshed.png rename to dhsi/day-four/images/anno_bor_finshed.png diff --git a/iiif-5-day-workshop/images/anno_bor_highlight.png b/dhsi/day-four/images/anno_bor_highlight.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_highlight.png rename to dhsi/day-four/images/anno_bor_highlight.png diff --git a/iiif-5-day-workshop/images/anno_bor_start.png b/dhsi/day-four/images/anno_bor_start.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_start.png rename to dhsi/day-four/images/anno_bor_start.png diff --git a/iiif-5-day-workshop/images/anno_bor_text.png b/dhsi/day-four/images/anno_bor_text.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_text.png rename to dhsi/day-four/images/anno_bor_text.png diff --git a/iiif-5-day-workshop/images/anno_bor_typed.png b/dhsi/day-four/images/anno_bor_typed.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_typed.png rename to dhsi/day-four/images/anno_bor_typed.png diff --git a/iiif-5-day-workshop/images/anno_bor_view_anno.png b/dhsi/day-four/images/anno_bor_view_anno.png similarity index 100% rename from iiif-5-day-workshop/images/anno_bor_view_anno.png rename to dhsi/day-four/images/anno_bor_view_anno.png diff --git a/iiif-5-day-workshop/images/anno_download_add.png b/dhsi/day-four/images/anno_download_add.png similarity index 100% rename from iiif-5-day-workshop/images/anno_download_add.png rename to dhsi/day-four/images/anno_download_add.png diff --git a/dhsi/day-four/images/anno_download_canvas.png b/dhsi/day-four/images/anno_download_canvas.png new file mode 100644 index 00000000..df6ebac1 Binary files /dev/null and b/dhsi/day-four/images/anno_download_canvas.png differ diff --git a/dhsi/day-four/images/anno_download_saveas.png b/dhsi/day-four/images/anno_download_saveas.png new file mode 100644 index 00000000..aab94538 Binary files /dev/null and b/dhsi/day-four/images/anno_download_saveas.png differ diff --git a/dhsi/day-four/images/anno_search.png b/dhsi/day-four/images/anno_search.png new file mode 100644 index 00000000..649730e6 Binary files /dev/null and b/dhsi/day-four/images/anno_search.png differ diff --git a/iiif-5-day-workshop/images/annos_anno_options.png b/dhsi/day-four/images/annos_anno_options.png similarity index 100% rename from iiif-5-day-workshop/images/annos_anno_options.png rename to dhsi/day-four/images/annos_anno_options.png diff --git a/iiif-5-day-workshop/images/annos_atom_id_update.png b/dhsi/day-four/images/annos_atom_id_update.png similarity index 100% rename from iiif-5-day-workshop/images/annos_atom_id_update.png rename to dhsi/day-four/images/annos_atom_id_update.png diff --git a/iiif-5-day-workshop/images/annos_atom_prettify.png b/dhsi/day-four/images/annos_atom_prettify.png similarity index 100% rename from iiif-5-day-workshop/images/annos_atom_prettify.png rename to dhsi/day-four/images/annos_atom_prettify.png diff --git a/iiif-5-day-workshop/images/annos_bor_article.png b/dhsi/day-four/images/annos_bor_article.png similarity index 100% rename from iiif-5-day-workshop/images/annos_bor_article.png rename to dhsi/day-four/images/annos_bor_article.png diff --git a/iiif-5-day-workshop/images/annos_bor_newspaper.png b/dhsi/day-four/images/annos_bor_newspaper.png similarity index 100% rename from iiif-5-day-workshop/images/annos_bor_newspaper.png rename to dhsi/day-four/images/annos_bor_newspaper.png diff --git a/iiif-5-day-workshop/images/annos_bor_sailors_lost.png b/dhsi/day-four/images/annos_bor_sailors_lost.png similarity index 100% rename from iiif-5-day-workshop/images/annos_bor_sailors_lost.png rename to dhsi/day-four/images/annos_bor_sailors_lost.png diff --git a/iiif-5-day-workshop/images/annos_bor_ships_lost.png b/dhsi/day-four/images/annos_bor_ships_lost.png similarity index 100% rename from iiif-5-day-workshop/images/annos_bor_ships_lost.png rename to dhsi/day-four/images/annos_bor_ships_lost.png diff --git a/iiif-5-day-workshop/images/annos_bor_stats_map.png b/dhsi/day-four/images/annos_bor_stats_map.png similarity index 100% rename from iiif-5-day-workshop/images/annos_bor_stats_map.png rename to dhsi/day-four/images/annos_bor_stats_map.png diff --git a/iiif-5-day-workshop/images/annos_content.png b/dhsi/day-four/images/annos_content.png similarity index 100% rename from iiif-5-day-workshop/images/annos_content.png rename to dhsi/day-four/images/annos_content.png diff --git a/iiif-5-day-workshop/images/annos_created.png b/dhsi/day-four/images/annos_created.png similarity index 100% rename from iiif-5-day-workshop/images/annos_created.png rename to dhsi/day-four/images/annos_created.png diff --git a/iiif-5-day-workshop/images/annos_download_annotating.png b/dhsi/day-four/images/annos_download_annotating.png similarity index 100% rename from iiif-5-day-workshop/images/annos_download_annotating.png rename to dhsi/day-four/images/annos_download_annotating.png diff --git a/iiif-5-day-workshop/images/annos_download_show.png b/dhsi/day-four/images/annos_download_show.png similarity index 100% rename from iiif-5-day-workshop/images/annos_download_show.png rename to dhsi/day-four/images/annos_download_show.png diff --git a/iiif-5-day-workshop/images/annos_download_success.png b/dhsi/day-four/images/annos_download_success.png similarity index 100% rename from iiif-5-day-workshop/images/annos_download_success.png rename to dhsi/day-four/images/annos_download_success.png diff --git a/dhsi/day-four/images/annos_home.png b/dhsi/day-four/images/annos_home.png new file mode 100644 index 00000000..18cdb616 Binary files /dev/null and b/dhsi/day-four/images/annos_home.png differ diff --git a/iiif-5-day-workshop/images/annos_mirador.png b/dhsi/day-four/images/annos_mirador.png similarity index 100% rename from iiif-5-day-workshop/images/annos_mirador.png rename to dhsi/day-four/images/annos_mirador.png diff --git a/iiif-5-day-workshop/images/annos_mirador_addItem.png b/dhsi/day-four/images/annos_mirador_addItem.png similarity index 100% rename from iiif-5-day-workshop/images/annos_mirador_addItem.png rename to dhsi/day-four/images/annos_mirador_addItem.png diff --git a/iiif-5-day-workshop/images/annos_sas_download.png b/dhsi/day-four/images/annos_sas_download.png similarity index 100% rename from iiif-5-day-workshop/images/annos_sas_download.png rename to dhsi/day-four/images/annos_sas_download.png diff --git a/iiif-5-day-workshop/images/annos_sas_manifest.png b/dhsi/day-four/images/annos_sas_manifest.png similarity index 100% rename from iiif-5-day-workshop/images/annos_sas_manifest.png rename to dhsi/day-four/images/annos_sas_manifest.png diff --git a/dhsi/day-four/images/annos_search_api_atom.png b/dhsi/day-four/images/annos_search_api_atom.png new file mode 100644 index 00000000..f6fa67c9 Binary files /dev/null and b/dhsi/day-four/images/annos_search_api_atom.png differ diff --git a/iiif-5-day-workshop/images/annos_search_endpoint.png b/dhsi/day-four/images/annos_search_endpoint.png similarity index 100% rename from iiif-5-day-workshop/images/annos_search_endpoint.png rename to dhsi/day-four/images/annos_search_endpoint.png diff --git a/iiif-5-day-workshop/images/annos_select_manifest.png b/dhsi/day-four/images/annos_select_manifest.png similarity index 100% rename from iiif-5-day-workshop/images/annos_select_manifest.png rename to dhsi/day-four/images/annos_select_manifest.png diff --git a/dhsi/day-four/images/annos_share.png b/dhsi/day-four/images/annos_share.png new file mode 100644 index 00000000..73f09817 Binary files /dev/null and b/dhsi/day-four/images/annos_share.png differ diff --git a/iiif-5-day-workshop/images/annos_toggle_annotations.png b/dhsi/day-four/images/annos_toggle_annotations.png similarity index 100% rename from iiif-5-day-workshop/images/annos_toggle_annotations.png rename to dhsi/day-four/images/annos_toggle_annotations.png diff --git a/dhsi/day-four/images/annos_vscode_pre_search.png b/dhsi/day-four/images/annos_vscode_pre_search.png new file mode 100644 index 00000000..eb9d0d85 Binary files /dev/null and b/dhsi/day-four/images/annos_vscode_pre_search.png differ diff --git a/dhsi/day-four/images/annos_workbench.png b/dhsi/day-four/images/annos_workbench.png new file mode 100644 index 00000000..baf3914e Binary files /dev/null and b/dhsi/day-four/images/annos_workbench.png differ diff --git a/iiif-5-day-workshop/images/annotation.jpg b/dhsi/day-four/images/annotation.jpg similarity index 100% rename from iiif-5-day-workshop/images/annotation.jpg rename to dhsi/day-four/images/annotation.jpg diff --git a/dhsi/day-four/images/copy_annos_url.png b/dhsi/day-four/images/copy_annos_url.png new file mode 100644 index 00000000..c35d119a Binary files /dev/null and b/dhsi/day-four/images/copy_annos_url.png differ diff --git a/dhsi/day-four/images/manifest_share.png b/dhsi/day-four/images/manifest_share.png new file mode 100644 index 00000000..54ab080a Binary files /dev/null and b/dhsi/day-four/images/manifest_share.png differ diff --git a/dhsi/day-four/images/mirador_annos.png b/dhsi/day-four/images/mirador_annos.png new file mode 100644 index 00000000..80686a46 Binary files /dev/null and b/dhsi/day-four/images/mirador_annos.png differ diff --git a/dhsi/day-four/images/noannos.png b/dhsi/day-four/images/noannos.png new file mode 100644 index 00000000..2911b8f6 Binary files /dev/null and b/dhsi/day-four/images/noannos.png differ diff --git a/dhsi/day-four/images/sas/add_manifest.png b/dhsi/day-four/images/sas/add_manifest.png new file mode 100644 index 00000000..186298e1 Binary files /dev/null and b/dhsi/day-four/images/sas/add_manifest.png differ diff --git a/dhsi/day-four/images/sas/annotate.png b/dhsi/day-four/images/sas/annotate.png new file mode 100644 index 00000000..923e5640 Binary files /dev/null and b/dhsi/day-four/images/sas/annotate.png differ diff --git a/dhsi/day-four/images/sas/browse_annos.png b/dhsi/day-four/images/sas/browse_annos.png new file mode 100644 index 00000000..0a3fa55b Binary files /dev/null and b/dhsi/day-four/images/sas/browse_annos.png differ diff --git a/dhsi/day-four/images/sas/browse_annos_page.png b/dhsi/day-four/images/sas/browse_annos_page.png new file mode 100644 index 00000000..d9be578c Binary files /dev/null and b/dhsi/day-four/images/sas/browse_annos_page.png differ diff --git a/dhsi/day-four/images/sas/browse_manifest.png b/dhsi/day-four/images/sas/browse_manifest.png new file mode 100644 index 00000000..165e5a94 Binary files /dev/null and b/dhsi/day-four/images/sas/browse_manifest.png differ diff --git a/dhsi/day-four/images/sas/collections.png b/dhsi/day-four/images/sas/collections.png new file mode 100644 index 00000000..32f4141c Binary files /dev/null and b/dhsi/day-four/images/sas/collections.png differ diff --git a/dhsi/day-four/images/sas/download_anno.png b/dhsi/day-four/images/sas/download_anno.png new file mode 100644 index 00000000..7f1a4cdd Binary files /dev/null and b/dhsi/day-four/images/sas/download_anno.png differ diff --git a/dhsi/day-four/images/sas/empty_collection.png b/dhsi/day-four/images/sas/empty_collection.png new file mode 100644 index 00000000..48cbd881 Binary files /dev/null and b/dhsi/day-four/images/sas/empty_collection.png differ diff --git a/dhsi/day-four/images/sas/login.png b/dhsi/day-four/images/sas/login.png new file mode 100644 index 00000000..cf2423f2 Binary files /dev/null and b/dhsi/day-four/images/sas/login.png differ diff --git a/dhsi/day-four/images/sas/manifest-search.png b/dhsi/day-four/images/sas/manifest-search.png new file mode 100644 index 00000000..2de85f02 Binary files /dev/null and b/dhsi/day-four/images/sas/manifest-search.png differ diff --git a/dhsi/day-four/images/sas/manifest.png b/dhsi/day-four/images/sas/manifest.png new file mode 100644 index 00000000..5fea0f70 Binary files /dev/null and b/dhsi/day-four/images/sas/manifest.png differ diff --git a/dhsi/day-four/images/sas/search-url.png b/dhsi/day-four/images/sas/search-url.png new file mode 100644 index 00000000..513f0871 Binary files /dev/null and b/dhsi/day-four/images/sas/search-url.png differ diff --git a/dhsi/day-four/images/sas/search-vscode.png b/dhsi/day-four/images/sas/search-vscode.png new file mode 100644 index 00000000..cbb62b03 Binary files /dev/null and b/dhsi/day-four/images/sas/search-vscode.png differ diff --git a/dhsi/day-four/images/sas/share-annos-page.png b/dhsi/day-four/images/sas/share-annos-page.png new file mode 100644 index 00000000..a5200742 Binary files /dev/null and b/dhsi/day-four/images/sas/share-annos-page.png differ diff --git a/dhsi/day-four/images/sas/share-annos.png b/dhsi/day-four/images/sas/share-annos.png new file mode 100644 index 00000000..346fafd9 Binary files /dev/null and b/dhsi/day-four/images/sas/share-annos.png differ diff --git a/dhsi/day-four/images/sas/workbench-annoa-demo.png b/dhsi/day-four/images/sas/workbench-annoa-demo.png new file mode 100644 index 00000000..b5f078db Binary files /dev/null and b/dhsi/day-four/images/sas/workbench-annoa-demo.png differ diff --git a/dhsi/day-four/images/sas/workbench-annoa.png b/dhsi/day-four/images/sas/workbench-annoa.png new file mode 100644 index 00000000..3ddfb060 Binary files /dev/null and b/dhsi/day-four/images/sas/workbench-annoa.png differ diff --git a/dhsi/day-four/images/upload_anno.png b/dhsi/day-four/images/upload_anno.png new file mode 100644 index 00000000..8757b132 Binary files /dev/null and b/dhsi/day-four/images/upload_anno.png differ diff --git a/dhsi/day-four/images/uv_annos.png b/dhsi/day-four/images/uv_annos.png new file mode 100644 index 00000000..d1585399 Binary files /dev/null and b/dhsi/day-four/images/uv_annos.png differ diff --git a/dhsi/day-four/images/wb-annos.png b/dhsi/day-four/images/wb-annos.png new file mode 100644 index 00000000..eaa8216d Binary files /dev/null and b/dhsi/day-four/images/wb-annos.png differ diff --git a/dhsi/day-four/images/workbench-replace.png b/dhsi/day-four/images/workbench-replace.png new file mode 100644 index 00000000..fc6c99fd Binary files /dev/null and b/dhsi/day-four/images/workbench-replace.png differ diff --git a/dhsi/day-four/images/workbench_iiif_link.png b/dhsi/day-four/images/workbench_iiif_link.png new file mode 100644 index 00000000..e887339a Binary files /dev/null and b/dhsi/day-four/images/workbench_iiif_link.png differ diff --git a/dhsi/day-four/niqui-links.md b/dhsi/day-four/niqui-links.md new file mode 100644 index 00000000..70b6881d --- /dev/null +++ b/dhsi/day-four/niqui-links.md @@ -0,0 +1,7 @@ +https://www.dickensnotes.com/ + +https://www.lib.ncsu.edu/news/special-collections/exploring-graphic-novels-and-comic-books-visual-literature + +https://static.artmuseum.princeton.edu/asian-art/china/viewers/coffin-panel-viewer/ + +https://www.digitalexhibitions.manchester.ac.uk/s/demonstration-and-templates/page/iiif-and-annona-views \ No newline at end of file diff --git a/dhsi/day-four/sharing.md b/dhsi/day-four/sharing.md new file mode 100644 index 00000000..6dfd2229 --- /dev/null +++ b/dhsi/day-four/sharing.md @@ -0,0 +1,23 @@ +# Sharing your Annotations + +Now you have created your annotations you want to share them with others. To do this make sure you are back on your Collections screen and have the collection with your Manifest selected. + +![SAS Home screen](images/annos_home.png) + +Now click the share link: + +![SAS share button](images/annos_share.png) + +Opening the Share screen will create a copy of the original Manifest and add links to the Annotations and to a IIIF Search service. The share screen gives you a link to the copied Manifest and also two large buttons to open the Manifest in Mirador and the Universal Viewer. + +![Share Manifest Screen](images/manifest_share.png) + +If you click on the Mirador link you will be taken to a public copy of Mirador. Once you navigate to the page you have annotated you should be able to click the 'hamburger' symbol to open up the left hand panel. Once open you can click on either the Annotations panel or Search Panel. + +![Mirador Annotations](images/mirador_annos.png) + +If you go back to the Share screen and click on the Universal Viewer link you will be taken to the following screen: + +![UV Annotations](images/uv_annos.png) + +Note the Universal Viewer doesn't support annotations in the same way as Mirador. To view the annotations you have to search for them using the search bar at the bottom. diff --git a/dhsi/day-four/wax.md b/dhsi/day-four/wax.md new file mode 100644 index 00000000..eed0bede --- /dev/null +++ b/dhsi/day-four/wax.md @@ -0,0 +1,10 @@ +# Wax +Wax is a project for creating digital exhibits website similar to Omeka/CollectiveAccess. One of the nice things about Wax is that it allows your collections to be uploaded via a CSV and it will create embeddable IIIF surrogates which are used in the [Wax website](https://minicomp.github.io/wax/). + +![wax workflow](https://minicomp.github.io/wax/img/wax_workflow.jpg) + + +# Wax and Annonatate +Wax requires three ruby tasks to be run in the command line along with a couple of YAML files to be updated to work properly. This can sometimes cause users dependency troubles. Annonatate provides an interface that will update your YAML files based on the fields in your CSV files and run the wax processes. It will also set up your Wax website to run via GitHub pages. + +![](https://annonatate.github.io/images/wax-6.png) \ No newline at end of file diff --git a/dhsi/day-four/workbench.md b/dhsi/day-four/workbench.md new file mode 100644 index 00000000..fbfbeb8b --- /dev/null +++ b/dhsi/day-four/workbench.md @@ -0,0 +1,16 @@ +# Publishing your annotated Manifest + +Now you have finished editing your manifest and tested it is working you can upload it to your Workbench so you can share it with others. The reason we have been developing with the Chrome Web Server version is that GitHub caches all of the Website files and so it takes a while for the changes you make to appear on the Website. + +To update the manifest in Workbench click the replace button highlighted below: + +![image](images/workbench-replace.png) + +This will ask you to upload a new version of the Manifest and then will wait for the website to be updated. When you see the links to Mirador and the UV appear it should be OK to view the latest version of the manifest. You not see your changes due to the caching issue mentioned earlier so if this is the case open up a new private window or click Shift and refresh to get the latest copy. + +You should now be able to see your annotations and search service in the following places: + + * Mirador 3: https://projectmirador.org/ + * Universal Viewer: http://universalviewer.io/ + * Annona: http://iiif.gdmrdigital.com/annona/index.html?iiif-content=[annotations_url] + diff --git a/dhsi/day-one/cantaloupe.md b/dhsi/day-one/cantaloupe.md new file mode 100644 index 00000000..e9cec9ad --- /dev/null +++ b/dhsi/day-one/cantaloupe.md @@ -0,0 +1,296 @@ + +## Launching Your Own Image Server + +So, far we've seen some ways to get our images online and IIIF accessible with minimal effort. This is great for small or personal projects. + +At the same time, we also need to think about solutions that scale. If you're working on a project with thousands of images or you're working at a large institution with a large repository of images, we need to think about different solutions. + +Setting up your own image server means a little more set up time and it means that you're responsible for keeping this server running and maintained. + +But it has the advantage of being scalable. Once set up, it allows you to serve thousands of images and easily add more. + +In this section, we're going to see what it looks like to set up such server. You may or may not be responsible for setting up such a server, but it's good to see how it is done. This will help you work with project partners and help you see that setting up such a server isn't actually that difficult. :) + +First let's just take a look at the [Cantaloupe Landing Page](https://cantaloupe-project.github.io/) to get a glimpse of what it can do. + +We can notice things here like: + +* authorization policy +* watermarking +* customizable images sources (e.g. AWS S3, etc) + +Again, if you're going to be responsible for serving images at scale or at the institutional level, then familiarity with images servers like Cantaloupe is important. + +## Installing Cantaloupe + +So in this exercise, we're going to walk through setting up and running Cantaloupe. + +There actually aren't that many steps to getting it up and running. But we can also look at few of the configuration properties to see how it can be modified and customized to meet various needs. + + + +### Running Cantaloupe on Your Local Computer + +To start you need to download the Cataloupe build. [Download Cantaloupe v5.0.6](https://github.com/cantaloupe-project/cantaloupe/releases/download/v5.0.6/cantaloupe-5.0.6.zip) + +Once downloaded, go to your downloads folder. + +Unzip the download and you should have a new folder called `cantaloupe-5.0.6`. + +Open `cantaloupe-5.0.6` in vscode. + +In this folder, there should be a file called `cantaloupe.properties.sample`. Create a copy of this, called `cantaloupe.properties` + +We will modify some properties here later, but the default properties should be enough to get the instance working. + +In vscode go to the terminal and run: + +Mac +`$ java -Dcantaloupe.config=./cantaloupe.properties -Xmx2g -jar Cantaloupe-5.0.6.jar` + +Windows +`$ java -Dcantaloupe.config=.\cantaloupe.properties -Xmx2g -jar cantaloupe-5.0.6.jar` + +Now navigate to [http://127.0.0.1:8182](http://127.0.0.1:8182) in your browser. + +### Running Cantaloupe in Code Spaces + +Via github code spaces, I've configured a computer that already has Cantaloupe downloaded and installed. + +You can find that link here [https://github.com/jeffreycwitt/cantaloupe-container](https://github.com/jeffreycwitt/cantaloupe-container) + +Click the "Launch in Code Space" button and give the Code Space time to set up. + +And then run cantaloupe. + +In the browser based vscode, go to the terminal and run: + +In this folder, there should be a file called `cantaloupe.properties.sample`. Create a copy of this, called `cantaloupe.properties` + +Then in the terminal run + +`$ java -Dcantaloupe.config=./cantaloupe.properties -Xmx2g -jar Cantaloupe-5.0.6.jar` + +Change the port visibility to "public" and then follow the Code Space prompts to view your working instance in browser. + + +## Configuring Cantaloupe + +We won't explore all the ways you can configure Cantaloupe, but let's make a few changes so we can get a sense of what's possible. + +Most of the configuration we're going to explore consists of enabling or disabling various configuration properties. + +We've already created this configuration file, called `cantaloupe.properties` + +### Adding Your Own Images + +Let's hook up cantaloupe to your own images. + +#### On your local computer + +Find or create a new directory of images somewhere on your computer and call it `myImages`. + +Now you just need to get the full path to this image directory. + +* In Terminal, navigate to the folder and type `$pwd` +* In vscode, right click on the directory and select `copy path` +* In Finder, right click a file within the target folder, select `Get Info`, and then copy the value of the "Where" property +* In windows explorer, do something similar. + +Now in the `FilesystemSource` section of the properties file, we want to change the value of `FilesystemSource.BasicLookupStrategy.path_prefix` to something that looks like this: + +`FilesystemSource.BasicLookupStrategy.path_prefix = /path/to/myImages/` + +As the comments note, make sure there is a trailing slash. + +http://localhost:8182/iiif/3//full/max/0/default.jpg + +#### In Code Space + +In Code Space, I've already created an images folder with a demo images, so you should change this to... + +`FilesystemSource.BasicLookupStrategy.path_prefix = ./images/` + +As the comments note, make sure there is a trailing slash. + +In Code Space you should be able to see your sample image here: + +/iiif/3/vangough.jpg/full/max/0/default.jpg + +To add your own images right click on `images` and select `upload` + +### Enabling the admin dashboard + +Now that we've edited the properties file, let's enable the admin dashboard so we have a more user friendly way to configure the server. + +Scroll down to the block that says: + +`# Enables the Control Panel, at /admin.` + +change the value of `.enabled` to true and add temporary password like `test` + +``` +endpoint.admin.enabled = true +endpoint.admin.username = admin +endpoint.admin.secret = test +``` + +Now head over to [http://localhost:8182/admin](http://localhost:8182/admin) and use the credential to log in + +Now you can continue configuring either by editing the properties file or in the web GUI. + +### Overlays and Water Marks + +Let's add some overlays and water marks. It might be the case that your institution has sensitive data that needs a watermark or some kind attribution statement. + +In the web GUI, head down to "overlays" + +#### String Overlay + +Make sure `Basic Strategy Enabled` is checked. + +Navigate down to "Basic Strategy (String)" and type the string that you want overlayed. + +Maybe something like "My DHSI Images 2024" + +Now take a look at any of your served images, and you should see the overlay. + +Using the other properties you can experiment with the font size, position. + +#### Image Overlay + +You can just easily overlay an image, perhaps as institutional logo that you want to accompany an image. + +This can be done by changing the BasicStrategy.Type from 'String' to 'Image' + +Then you need to add a .png to the Cantaloupe working directory and indicate that file path in the "Image File" property. + +So here you should change `overlay-sample.png` to `name-of-your-overlay.png` after depositing that file in the working directory. + +#### Redaction + +Notice at the bottom that if you had more advanced needs, like redacting certain parts of the image, this is possible as well. You would need to enable redaction and then write the instructions for which part of which image needs to be redacted. + +That's an advanced use case but it's nice to know its there. + +### Serving HTTP images. + +And pretty cool feature of Cataloupe is that we can serve images from other locations: for example from some web location. + +This means that if your images are already published somewhere on-line, but not yet available via the IIIF protocols, you can leave them where they are and point them at a web location. + +Cantaloupe will request those images, and then re-serve them in a IIIF compliant way. + +To see this, we need to navigate the "Source" section, and change the `StaticSource` from `FilesystemSource` to `HttpSource` + +Then under `HttpSource` set the URL Prefix to a `http` url where images can be found. + +Here's an example you can use. + +Here's a path to a bunch of flag images: `https://www.graphicmaps.com/r/w250/images/flags/` + +At this location, several images of flags can be accessed. For example `ht-flag.jpg`, `us-flag.jpg`, `ca-flag.jpg`, `de-flag.jpg` etc. But they are not accessible via iiif. + +Instead of downloading all these images and then uploading them to my cantaloupe server, I could just point Cantaloupe at the containing url location, namely: `https://www.graphicmaps.com/r/w250/images/flags/` + +So take this url as the value of the `URL Prefix` property, and hit save. + +Now check out the canadian flag served as a IIIF image. + +Try rotating in 90 degrees. +[http://localhost:8182/iiif/3/ca-flag.jpg/full/max/90/default.jpg](http://localhost:8182/iiif/3/ca-flag.jpg/full/max/90/default.jpg) + +Try requesting it as gray scale +[http://localhost:8182/iiif/3/ca-flag.jpg/full/max/90/gray.jpg](http://localhost:8182/iiif/3/ca-flag.jpg/full/max/0/gray.jpg) + +Try requesting ias a thumbnail +[http://localhost:8182/iiif/3/ca-flag.jpg/full/50,/90/default.jpg](http://localhost:8182/iiif/3/ca-flag.jpg/full/50,/0/default.jpg) + +Try looking at other flags, by changing the two letter country code in the image name to the country of your choice. (With a little guess work about the right two letter prefix, you can usually find your way to the country flag of interest.) + +### AWS S3 Connection + +An even better, scalable, approach is to point cataloupe at an AWS S3 bucket. This is very similar to the HTTP location approach but allows you to point to AWS S3 bucket. + +AWS S3 is a very cost effective way to store and serve large amounts of static content, like images. + +If you have S3 bucket, this is a great way to store your image content. + +You can then point your Cantaloupe server to the S3 bucket and re-serve those images in a IIIF compliant way. + +In this case you need to change the Static Source to `S3Source` + +Then in the S3Source tab, you need to supply: + +* The name of your S3 Bucket +* Your Access Key ID +* Your Secret Key + +### Basic Auth + +While a driving goal of IIIF is openness, sometimes institutions have sensitive information that needs to be restricted. + +In such cases, an enterprise level server like Cantaloupe can help you with these issues. + +We won't implement anything in detail here, but it's important to have a sense of how it works and how you could take it further. + +Different institutions will have different authorization and authentication needs, so this a place that each institution will like implement its own policy. + +But Cantaloupe comes with a way to implement custom rules and policies, namely through its CustomDelegate Class. + +In this case we're going to implement a very simple authentication procedure called basic auth. + +To do this, we first need to enable the delegate script as follows: + +`delegate_script.enabled = true` + +or navigate to Application, Delegate Script, and check enabled in the web ui. + +When you downloaded Cantaloupe it came with a file called `delgates.rb.sample`. We're going to make a copy of this and name it `delegates.rb` + +At the top of this file were going to add: + +`require 'base64'` + +And then at the bottom of the `CustomDelegate Class` declaration (before the very last `end`), we going to add a few class methods that implement basic auth. + +```ruby +def pre_authorize(options = {}) + header = context['request_headers'] + .select{ |name, value| name.downcase == 'authorization' } + .values.first + return true if authenticate_basic(header) + return { + 'status_code' => 401, + 'challenge' => 'Basic realm="MyRealm" charset="UTF-8"' + } + end + + def authorize(options = {}) + true + end + + def authenticate_basic(header) + if header&.start_with?('Basic ') + encoded = header[6..header.length - 1] + creds = Base64.decode64(encoded).split(':') + if creds.length > 1 + return (creds[0] == 'my_user' and creds[1] == 'my_secret') + end + end + false + end +``` + +As implemented here, 'my_user' will be the user name and `my_secret` will be the password. + +Now the next time you request an image, your browser will be prompted to ask you for the username and password. Once supplied, your browser will re-request the image using the supplied authentication information. + +Basic Auth is not a strong security protocol, so in full production you'll probably want to implement a more secure policy. That's a more complicated endeavor, but the `delegates.rb` file is the place where you would implement such a policy. + +Have a look at the other comments in this `delegates.rb` files as it gives several examples of other kinds of customizations that can be implemented via the `CustomDelegate` class + + diff --git a/dhsi/day-one/custom-viewer-demos/example1.html b/dhsi/day-one/custom-viewer-demos/example1.html new file mode 100644 index 00000000..908b8efa --- /dev/null +++ b/dhsi/day-one/custom-viewer-demos/example1.html @@ -0,0 +1,37 @@ + + + +

    Table of contents

    + + + \ No newline at end of file diff --git a/dhsi/day-one/custom-viewer-demos/image1.html b/dhsi/day-one/custom-viewer-demos/image1.html new file mode 100644 index 00000000..6e5b9bf8 --- /dev/null +++ b/dhsi/day-one/custom-viewer-demos/image1.html @@ -0,0 +1,243 @@ + + + + + +

    Image 1 Example

    + +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    + +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    + +
    + + +``` \ No newline at end of file diff --git a/dhsi/day-one/custom-viewer-demos/image1viaAnnotations.html b/dhsi/day-one/custom-viewer-demos/image1viaAnnotations.html new file mode 100644 index 00000000..1d45b9ed --- /dev/null +++ b/dhsi/day-one/custom-viewer-demos/image1viaAnnotations.html @@ -0,0 +1,473 @@ + + + + + + + +

    Image 1 Example

    + +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    + +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    + +
    + + +``` \ No newline at end of file diff --git a/dhsi/day-one/custom-viewer-demos/image2.html b/dhsi/day-one/custom-viewer-demos/image2.html new file mode 100644 index 00000000..36f5a63d --- /dev/null +++ b/dhsi/day-one/custom-viewer-demos/image2.html @@ -0,0 +1,242 @@ + + + + + +

    Image 2 Example

    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    +
    +

    Descriptions

    +

    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

    +
    + +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit +
    +
    +
    + +
    + +
    + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
    +
    + +
    + + +``` \ No newline at end of file diff --git a/dhsi/day-one/image-api.md b/dhsi/day-one/image-api.md new file mode 100644 index 00000000..842ae1f0 --- /dev/null +++ b/dhsi/day-one/image-api.md @@ -0,0 +1,153 @@ +# Image API + +## Introduction + + * What is it? A contract (a set of "rules") between the server and a viewing client + * Its the foundation of all of the IIIF APIs. They all build on top of the Image API. + * Luckily its one of the easiest to implement + * because others have written servers you can install which provide the service + +## Terminology + * __API__ - Application Programming Interface. In this case an agreed standard between the Image API Server and the Image API Client. + * __Client__- The software which allows you to view a IIIF Image. As Web Browsers don't support the Image API Natively there are many Javascript viewers that live on webpages that can allow you to view IIIF Images. Examples include OpenSeaDragon, Mirador and Universal Viewer. + * __Viewer__ - also known as a IIIF Viewer. This is the same as a Client and lets you view IIIF Images. Examples include OpenSeaDragon, Mirador and Universal Viewer. + * __Server__ - Software that runs on a machine at all times and is assessable over the Web. For this workshop I will mostly be referring to Image API Servers but there are other types of servers including Web servers or Email servers. Sometimes they are also know as Services e.g. Image API service, Web Service or Mail Service. + * __Image API__ - the agreed standard and specification which forms the contract between Client and Server + * __Image API Server__ - the running software that provides access to images using the Image API. Sometimes shortened in this context to Image Servers. + * __IIIF Image__ - an Image that is made available through a IIIF Image API Server. + +## History + +IIIF really started out of the study of Medieval Manuscripts and the difficulty in using Digitised versions. Ben Albritton has written a great blog on the difficulties of working with images at that time and the promise IIIF gives in [Fellow Travelers: The Canterbury Tales and IIIF](https://blalbrit.github.io/2015/07/14/fellow-travelers-the-canterbury-tales-and-iiif). + +Testimonial for Glen Robson on the challenges of serving images at scale before IIIF + +> From a more personal perspective and also from a perspective of an institution providing these digital images. When I started work at the National Library of Wales, Manuscripts were digitised and three images were created per page. + +> 1. A thumbnail: +> +> ![Example thumbnail](https://damsssl.llgc.org.uk/iiif/2.0/image/4628571/full/90,/0/default.jpg) + +> 2. A Web or reference sized image: + +> ![Example web copy of image](https://damsssl.llgc.org.uk/iiif/2.0/image/4628571/full/300,/0/default.jpg) + +> 3. and a high quality archival Tiff that was only available on request. + +>These were made available through a viewer allowing you to browse around the Manuscript and switch between Thumbnail and Web view: + +> ![Image of a historical digital viewer](img/Chaucer_viewer.png) + +> As screens got bigger and the internet got faster the limited size of the Web images became a real barrier to use. Although the Archival Tiff was too big to put on the web, we needed some way to allow access to large images and support new methods of access like mobile browsers and the new uses scholars were making of the collection. The solution many institutions moved to, was to create Zooming viewers like [Zoomify](http://www.zoomify.com/) and [Microsoft's DZI](https://en.wikipedia.org/wiki/Deep_Zoom). These viewers tended to use Flash which was unsupported on Mobile and required proprietary file formats to support. Around this time the JPEG2000 file format started to gain traction as an open file format that could support Zoomable viewers. + +> Enter: + +> ![IIIF Logo](img/logo.png) + +> Provides: + > * A standard URL structure for accessing images (easy to support) + > * Enough information to drive a zoom viewer + > * Human hackable URLs + > * Cacheable and Scalable URLs + + +## The Image Request API + +Before practicing we should spend a little time with the "rules" themselves. + +These rules can be found on the IIIF web page here [https://iiif.io/api/image/3.0/](https://iiif.io/api/image/3.0/) + +There's a lot here, so let's not get overwhelmed. + +Let's look first at the most important section: [section 2.1: Image Request URI Syntax](https://iiif.io/api/image/3.0/#21-image-request-uri-syntax) + +Notice that there are 5 main parameters that the user can specify when making a request. + +* Region +* Size +* Rotation +* Quality +* Format + +Once we see, this much of the remaining documentation make sense. If we're interesting in specifying a certain region, then we can scroll down the [Region](https://iiif.io/api/image/3.0/#41-region) section and learn how to request the specific region we want in a way that the IIIF server understands. + +* Question: What is the "square" parameter? +* Question: Why do think the "square" parameter exists? What's a use case you can imagine for it. + +## Example: + +Perhaps the easiest was to learn the basic of the Image API is to practice manipulating images. + +So let's do that here, use the demo to play around with the images in a controlled environment. + +
    +
    + + + + +Here's another controlled demo where you can experiment: [https://www.learniiif.org/image-api/playground](https://www.learniiif.org/image-api/playground) + +Once you're demo playing around with the controlled demo, start playing around with a live image. + +Place the following base url in browser: + +`https://ids.lib.harvard.edu/ids/iiif/47174896/` + +Question: Why doesn't this url work by itself? What else needs to be added? + +Question: How could we modify this url so that it shows us a picture that is... + +* is 512px wide +* is upside down +* is gray scale +* has a format of .png + +For help, consult the [IIIF Image API documentation](https://iiif.io/api/image/3.0/) + +## Image Information Requests + +We can spend less time here, but it's important to note that the Image API provides rules not just for how to return the image itself, but how to return information about the image. + +In some cases, a viewing application my want to get prior information about the image before displaying it so that it can decide the best way to display it. + +First the API describes how that information should be requested, namely with a `info.json` appended to the image base url. + +For example: [https://ids.lib.harvard.edu/ids/iiif/47174896/info.json](https://ids.lib.harvard.edu/ids/iiif/47174896/info.json) + +If you open this link, you will a response of json data. (If your browser isn't showing this to you in a nice way consier install a browser extension for viewing json data like this [json chrome extension](https://chromewebstore.google.com/detail/json-viewer/gbmdgpbipfallnflgajpaliibnhdgobh)) + +The structure of that json data, what kind of properties it has and what kind of values can be supplied is governed by the [IIIF Image API: Image Information Request](https://iiif.io/api/image/3.0/#5-image-information) + +Take a moment to look at the response above and compare it to the documentation. See if you can answer the following questions + +* What does the `maxWidth` property mean? +* What does the `qualities` property tell the client? +* Finally, what does the `sizes` tell the client? \ No newline at end of file diff --git a/dhsi/day-one/image-hosting.md b/dhsi/day-one/image-hosting.md new file mode 100644 index 00000000..75329e68 --- /dev/null +++ b/dhsi/day-one/image-hosting.md @@ -0,0 +1,19 @@ +## Introduction to Image Hosting + +This section will go over some of the ways we can create and host images using IIIF image API standards. + +Please make sure you have a [GitHub account](https://github.com) created. + +## Methods for Image Hosting + +1. [IIIF workbench](workbench.html) +2. [Level 0 Static](level-0-static.html) +3. [Cantaloupe](cantaloupe.html) + +## Exercise + +However you've succeeded in getting your images hosted, it's time to turn back to you `myViewer` project. + +Let's start updating your viewer to use your own images, served from your own image server. + +We'll walk around to help and troubleshoot! \ No newline at end of file diff --git a/dhsi/day-one/image-viewer-exercise.md b/dhsi/day-one/image-viewer-exercise.md new file mode 100644 index 00000000..4c90fd6e --- /dev/null +++ b/dhsi/day-one/image-viewer-exercise.md @@ -0,0 +1,177 @@ + +## Exercise + +Now that we've had a chance to talk about the image API, we're going to start building. + +The goal here is to use simple `html` to build a web page(s) that display your images and provide your user with a way to navigate those images. + +### Capturing Some Demo Images + +Since we haven't yet placed any of our images on a IIIF server, we're going to use some demo image to start with. + +For the time being, pick 5 images from the following that you want to use as your demo images: + +* https://iiif.archive.org/image/iiif/3/100-3222%2F100_3222.jpg/full/max/0/default.png +* https://loris2.scta.info/sorb/S100r.jpg/full/full/0/default.jpg/full/full/0/default.jpg +* https://iiif.archive.org/image/iiif/3/GadoImages63465%2Ftoupload.jpg/full/max/0/default.png +* https://iiif.archive.org/image/iiif/3/PLAN-PIA00123%2FPIA00123.jpg/full/max/0/default.png +* https://ids.lib.harvard.edu/ids/iiif/43182083/full/full/0/default.jpg +* https://iiif.bodleian.ox.ac.uk/iiif/image/e58b8c60-005c-4c41-a22f-07d49cb25ede/full/full/0/default.jpg +* https://iiif.irht.cnrs.fr/iiif/France/Ch%C3%A2teauroux/Bibliotheque_municipale/B360446201_MS0005/DEPOT/B360446201_MS0005_0008/full/full/0/default.jpg +* https://iiif.durham.ac.uk/iiif/trifle/32150/t1/m4/q7/t1m4q77fr328/ad595a0a804a6eba1a7428f8ad89cfb3.jp2/full/256,/0/default.jpg +* https://iiif.archive.org/image/iiif/3/dr_atlantic-ocean-00104014%2F00104014.jpg/full/max/0/default.png +* https://iiif.archive.org/image/iiif/3/3110282571_8297688a9c_o%2F3110282571_8297688a9c_o.jpg/full/max/0/default.jpg +* https://iiif.archive.org/image/iiif/3/5530700036_ce54cf64b6_o%2F5530700036_ce54cf64b6_o.jpg/full/max/0/default.jpg +* https://iiif.archive.org/image/iiif/3/5229658490_619b3580ed_o%2F5229658490_619b3580ed_o.jpg/full/max/0/default.jpg + +Once we've put our own images on a IIIF server, you can replace the URLs for these demo images with your own. + +* Advanced Pro Tip + +Every image on archive.org is available via IIIF. See [https://iiif.io/guides/guides/archive.org/](https://iiif.io/guides/guides/archive.org/). + +If you're interested in using an image from archive.org, find the resource ID in the URL (see the example ID in bold below) + +https://archive.org/details/**dr_atlantic-ocean-00104014** + +Take that ID and insert it into the following url pattern + +https://iiif.archive.org/iiif/3/**dr_atlantic-ocean-00104014**/manifest.json + +In the json response, scroll down to find the item service block and copy the value of the id property. In the example below, the relevant image base url is: **https://iiif.archive.org/image/iiif/3/dr_atlantic-ocean-00104014%2F00104014.jpg** + + +``` +"service": [ + { + "id": "https://iiif.archive.org/image/iiif/3/dr_atlantic-ocean-00104014%2F00104014.jpg", + "type": "ImageService3", + "profile": "level2" + } + ], +``` + +(We will learn how to navigate this file in more detail tomorrow, so don't worry if this is confusing right now. That's with this method is a "advanced pro tip") + +### 1. Creating an Image Table of Contents Page + +1. Let's create a folder called `myProject` +2. Open this folder in vscode +3. Inside this folder create a file called `index.html` +4. Inside `index.html` let's add some dummy content to make sure things are working. Like so: + ```html + + + + +

    Hello world. Welcome to my custom image viewer.

    + + + ``` +5. To see that this is working, open the index.html page in your browser. + 1. (You can right click on the file in vscode, copy full path, and then past that path in your browser). +6. Your index page is going to be your inventory, catalogue, or table of contents page. + * From here your users can get an overview of the collection and then navigate to other pages dedicated to each picture. +7. So let's start modifying our index page with a simple list of our images + ```html + +

    Table of contents

    +
      +
    • Image1
    • +
    • Image2
    • +
    • Image3
    • +
    • Image4
    • +
    • Image5
    • +
    + + ``` +8. Right away we can use the IIIF image API and our understanding of the URL schema to send our users directly to our images by adding link tags with a target url. + ```html + +

    Table of contents

    + + + ``` +9. After adding links, refresh your browser page. Do you see the list of links? When you click on the link, are you taken to the IIIF image? If so great! +10. Let's start thinking about how we can do more. + 1. Before a user leaves an index page, it's nice to give them a preview of where the link takes them. + 2. In this case, it might be nice to give them a preview of the image before they decide to use leave the main index page. + 3. This a great use case for the IIIF Image API. + 4. So instead of just providing links, let's provide image thumbnails. +11. As we add the image element inside the link, notice that we need to change the image size. We don't want the user have to load the entire image from the server just to see a tiny preview. Instead let's just request size we need. + ```html +
  • + + + Image1 + +
  • + ``` +12. If you want to view a working example at this point, see my index example + +That's a great start. There's a ton more we can do here, but let's pause and create a pages to display our individual images. + +### 2. Creating an Image Table of Contents Page + +1. In the same `myProject` directory, let's create a file called `image1.html` + 1. This is meant to be something like the "resource" page where user can learn about or experience the object the selected from the index page. +2. Let's set it up similar to the way we did before. + ```html + + + + +

    Image 1

    + + + + ``` +3. That was easy! Now we've got a page with a title that embeds the IIIF Image. +4. But now let's reflect a bit. How could you make this a more interesting and engaging page? + 1. Could you offer multiple perspectives on this image? + 2. Could you include multiple images that focus in on various parts of the image? + 3. What other information do you need to add *besides images* to help your user navigate and get the most out of this page? +5. Get to work. + 1. Use the IIIF Image API url parameters to create lots of version of the same image, offering your users lots of perspectives. + 2. Add labels and descriptions that you think will help your user. + 3. Are there any navigation links you need to add here? (E.g. "Next", "Previous", "Home") + 4. See my image 1 example or image 2 example for inspiration. +6. Once you've finished one page, do a "save as" and make a new file called `image2.html` and then modify to display image 2. Do this for all five of your images. + +### 3. Reflection + +* What kind of NON-image data do you need to make your “viewer” work? +* What kind of labels and descriptions do you need? +* What kind of data relationships are needed in order to make it work? + * (For example sequence: what comes first, what comes last, what comes next?) +* What were the pain points of making an image viewer this way? + * What felt repetitive? + * Were there features you built that you wanted to re-use but couldn't? How come? + + diff --git a/dhsi/day-one/img/Chaucer_viewer.png b/dhsi/day-one/img/Chaucer_viewer.png new file mode 100644 index 00000000..fbc766f1 Binary files /dev/null and b/dhsi/day-one/img/Chaucer_viewer.png differ diff --git a/dhsi/day-one/img/apis.png b/dhsi/day-one/img/apis.png new file mode 100644 index 00000000..0c9a0fcf Binary files /dev/null and b/dhsi/day-one/img/apis.png differ diff --git a/dhsi/day-one/img/getty_view_gri.png b/dhsi/day-one/img/getty_view_gri.png new file mode 100644 index 00000000..88a57375 Binary files /dev/null and b/dhsi/day-one/img/getty_view_gri.png differ diff --git a/dhsi/day-one/img/guides.png b/dhsi/day-one/img/guides.png new file mode 100644 index 00000000..0e54da07 Binary files /dev/null and b/dhsi/day-one/img/guides.png differ diff --git a/dhsi/day-one/img/img_5813.jpg b/dhsi/day-one/img/img_5813.jpg new file mode 100644 index 00000000..81dec653 Binary files /dev/null and b/dhsi/day-one/img/img_5813.jpg differ diff --git a/dhsi/day-one/img/logo.png b/dhsi/day-one/img/logo.png new file mode 100644 index 00000000..9fb6f947 Binary files /dev/null and b/dhsi/day-one/img/logo.png differ diff --git a/dhsi/day-one/img/mirador-add-manifest.png b/dhsi/day-one/img/mirador-add-manifest.png new file mode 100644 index 00000000..2d76f96f Binary files /dev/null and b/dhsi/day-one/img/mirador-add-manifest.png differ diff --git a/dhsi/day-one/img/mirador-add-resource.png b/dhsi/day-one/img/mirador-add-resource.png new file mode 100644 index 00000000..a8f76db8 Binary files /dev/null and b/dhsi/day-one/img/mirador-add-resource.png differ diff --git a/dhsi/day-one/img/mirador-start.png b/dhsi/day-one/img/mirador-start.png new file mode 100644 index 00000000..fec8ffd4 Binary files /dev/null and b/dhsi/day-one/img/mirador-start.png differ diff --git a/dhsi/day-one/img/mirador_close.png b/dhsi/day-one/img/mirador_close.png new file mode 100644 index 00000000..1ac21fdb Binary files /dev/null and b/dhsi/day-one/img/mirador_close.png differ diff --git a/dhsi/day-one/img/otto_ege.png b/dhsi/day-one/img/otto_ege.png new file mode 100644 index 00000000..047d8c25 Binary files /dev/null and b/dhsi/day-one/img/otto_ege.png differ diff --git a/dhsi/day-one/img/uv_manifest.png b/dhsi/day-one/img/uv_manifest.png new file mode 100644 index 00000000..7bee6670 Binary files /dev/null and b/dhsi/day-one/img/uv_manifest.png differ diff --git a/dhsi/day-one/img/view_manifest.png b/dhsi/day-one/img/view_manifest.png new file mode 100644 index 00000000..10ef954e Binary files /dev/null and b/dhsi/day-one/img/view_manifest.png differ diff --git a/dhsi/day-one/img/viewers.png b/dhsi/day-one/img/viewers.png new file mode 100644 index 00000000..02a2c4ba Binary files /dev/null and b/dhsi/day-one/img/viewers.png differ diff --git a/dhsi/day-one/img/workbench-1.png b/dhsi/day-one/img/workbench-1.png new file mode 100644 index 00000000..4d22ecda Binary files /dev/null and b/dhsi/day-one/img/workbench-1.png differ diff --git a/dhsi/day-one/img/workbench-2.png b/dhsi/day-one/img/workbench-2.png new file mode 100644 index 00000000..566defc8 Binary files /dev/null and b/dhsi/day-one/img/workbench-2.png differ diff --git a/dhsi/day-one/img/workbench-3.png b/dhsi/day-one/img/workbench-3.png new file mode 100644 index 00000000..e831e2ec Binary files /dev/null and b/dhsi/day-one/img/workbench-3.png differ diff --git a/dhsi/day-one/img/workbench-4.png b/dhsi/day-one/img/workbench-4.png new file mode 100644 index 00000000..582eeef3 Binary files /dev/null and b/dhsi/day-one/img/workbench-4.png differ diff --git a/dhsi/day-one/img/workbench-5.png b/dhsi/day-one/img/workbench-5.png new file mode 100644 index 00000000..283e6670 Binary files /dev/null and b/dhsi/day-one/img/workbench-5.png differ diff --git a/dhsi/day-one/img/workbench-6.png b/dhsi/day-one/img/workbench-6.png new file mode 100644 index 00000000..b1cc8eb9 Binary files /dev/null and b/dhsi/day-one/img/workbench-6.png differ diff --git a/dhsi/day-one/img/workbench-7.png b/dhsi/day-one/img/workbench-7.png new file mode 100644 index 00000000..961cf4ac Binary files /dev/null and b/dhsi/day-one/img/workbench-7.png differ diff --git a/dhsi/day-one/introductions.md b/dhsi/day-one/introductions.md new file mode 100644 index 00000000..bcec1590 --- /dev/null +++ b/dhsi/day-one/introductions.md @@ -0,0 +1,9 @@ + +# Class Introductions + +- Name +- Institution +- Professional Role +- Why you are in the class? +- Do you have any IIIF experience? +- What's something interesting about you? \ No newline at end of file diff --git a/dhsi/day-one/level-0-static.md b/dhsi/day-one/level-0-static.md new file mode 100644 index 00000000..640b391c --- /dev/null +++ b/dhsi/day-one/level-0-static.md @@ -0,0 +1,47 @@ +# Creating static tiled images + +There are a couple of command line libraries that will create static images. They are often listed with dynamic iiif servers or api libraries in the [Awesome IIIF readme] (https://github.com/IIIF/awesome-iiif?tab=readme-ov-file). + + +1. [iiif_s3](https://github.com/cmoa/iiif_s3) - Ruby library for generating a static IIIF level 0 Image and Presentation API server on Amazon S3. +2. [iiif](https://github.com/zimeon/iiif) - Python library providing a reference implementation of the Image API. Also includes a test server and static tile generator. +3. [iiif-tiler](https://github.com/glenrobson/iiif-tiler) - Java library for generating static IIIF tiles (compliant with the V2.1 and 3.0 of the IIIF Image API). +4. [iiif-static-choices](https://github.com/bodleian/iiif-static-choices) (not in readme). + + +# Automating the process +1. https://github.com/dnoneill/dhsi-iiif-2024/blob/main/day1/images_to_iiif.py + +The script above allows pdf, png, jpg, jp2, and tif files to be dumped into a folder, the script to be run and all files in the folder will be created into level 0 IIIF images. It uses the iiif library (#2) to create these tiled images. + +It also preserves the file structure of the files you have dumped. For example, if you have two folders (cat-photos and dog-photos) in images, the output directory will keep that folder structure. + +## Install and running steps +1. Create fork of https://github.com/dnoneill/dhsi-iiif-2024 +2. Clone your fork locally: `git clone https://github.com/[yourusername]/dhsi-iiif-2024` +3. Change directory into your fork `git clone dhsi-iiif-2024` +2. Make sure python with pip is installed +3. Create virtual environment. `python3 -m venv [nameofenv]` +4. Activate virtual environment. `source [nameofenv]/bin/activate` +5. Install dependencies `pip3 install -r requirements.txt` +6. Dump files you want to convert into the `images` folder. +7. Move to the script directory `cd day1` +8. Run the script `python3 images_to_iiif.py` +9. View your images in the `iiif` folder + +## If the above doesn't work +1. Create fork of https://github.com/dnoneill/dhsi-iiif-2024 +2. Clone your fork locally: `git clone https://github.com/[yourusername]/dhsi-iiif-2024` +3. add your images to the `images` folder. +4. add your images to the repository `git add images` +5. create a commit message `git commit -m "add images"` +6. push to your repository `git push origin main` +7. Wait for the script to run, you can view the progress here: https://github.com/[yourusername]/dhsi-iiif-2024/actions +8. When it's green you should have files in the iiif folder. + + +# Thoughts? +- Look at the files we have created. What can you tell about them. How do you think these are used? +- Do they differ from the Workbench? +- What are some limitations of this method? +- What are some positivies? \ No newline at end of file diff --git a/dhsi/day-one/viewer.js b/dhsi/day-one/viewer.js new file mode 100644 index 00000000..a268bcbc --- /dev/null +++ b/dhsi/day-one/viewer.js @@ -0,0 +1,591 @@ +infoJsons = {}; + +/* + * Config: + * { + * # identifer for div + * div: "div_id", + * # IIIF Images to use + * images: [ + * 'http://example.com/image1' + * ], + * # Optional regions to use + * regions: [ + 'full', + 'square' + * ], + # Optional sizes + sizes: [ + '500,' + ], + # Optional rotations + rotations: [ + '45', + '90' + ], + # Optional qualities + qualities: [ + 'default', + 'gray' + ] + * } + */ +function addViewer(config) { + let iiifContent = getURLParameter("iiif-content"); + if (iiifContent != null) { + config.images.unshift(iiifContent); + } + if (typeof addExtraImages == 'function') { + addExtraImages(config); + } + Promise.all(config.images.map(url => fetch(url + "/info.json").then(resp => cacheInfoJson(config, url, resp)))).then(addParams(config)); +} + +async function addParams(config) { + console.log('Running addParams') + let foundAll = false; + let maxCount = 1000; + let count = 0; + while (!foundAll) { + foundAll = true; + for (var i = 0; i < config.images.length; i++) { + if (config.images[i] in infoJsons) { + console.log('Awaiting ' + config.images[i]); + await infoJsons[config.images[i]]; + } else { + console.log('Not found: ' + config.images[i]); + foundAll = false; + } + } + if (count++ > maxCount) { + console.log('Failed to load images'); + return; + } + await new Promise(r => setTimeout(r, 1000)); + } + var div = document.getElementById(config.div); + + var ul = createElementStyle('ul', 'demo'); + div.appendChild(ul) + + addIdentifiers(ul, config); + addRegion(ul, config); + addSizes(ul, config); + addRotation(ul, config); + addQuality(ul, config); + addFormats(ul, config); + + var linkDiv = document.createElement('div'); + linkDiv.setAttribute('style', 'margin-bottom:20px'); + div.appendChild(linkDiv); + + var aLink = createElementStyle('a', 'centre'); + aLink.id = "link"; + aLink.setAttribute('target', '_blank'); + aLink.setAttribute('rel', 'noopener noreferrer'); + linkDiv.appendChild(aLink); + + var imgDiv = createElementStyle('div', 'iiif-image-api text-center'); + div.appendChild(imgDiv); + + var img = createElementStyle('img', 'centre'); + img.id = config.div + '_iiif-image-api-img'; + imgDiv.appendChild(img); + showImage(config.div,null); +} + +function cacheInfoJson(config, identifier, response) { + console.log('Running cache info json', identifier); + if (!(identifier in infoJsons)) { + if (!response.ok) { + console.error("Error: (" + response.status + ") " + response.statusText); + + console.log('Removing: ', identifier); + config.images.splice(config.images.indexOf(identifier), 1); + } + response.json().then((data) => { + infoJsons[identifier] = data; + }); + } +} + +function addIdentifiers(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('identifier')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Identifier')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','identifier'); + select.id = 'identifier_' + config.div; + select.onchange = function(){ showImage(config.div,'identifier'); }; + div.appendChild(select); + + addOptions('identifier_' + config.div, config.images, '', ''); +} + +function addRegion(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('region')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Region')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','region'); + select.id = 'region_' + config.div; + select.onchange = function(){ showImage(config.div,'region'); }; + div.appendChild(select); + + var regions = null; + if ('regions' in config) { + // Use supplied regions + regions = config.regions; + } + updateRegion(config.div, regions); +} + +function clearSelect(select) { + var i, L = select.options.length - 1; + for(i = L; i >= 0; i--) { + select.remove(i); + } +} + +function updateRegion(uuid, suppliedRegions) { + if (suppliedRegions) { + var regions = suppliedRegions; + } else { + var regions = ['full']; + if (supports(getCurrentImage(uuid), 'regionSquare')) { + regions.push('square'); + } + var infoJson = infoJsons[getCurrentImage(uuid)]; + if (infoJson.width > 1500 && infoJson.height > 1500) { + centerX = Math.floor(infoJson.width / 2); + centerY = Math.floor(infoJson.height / 2); + regions.push((centerX - 500) + "," + (centerY - 500) + ",1000,1000"); + } + + } + addOptions('region_' + uuid, regions, '', ''); +} +function addSizes(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('size')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Size')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','size'); + select.id = 'size_' + config.div; + select.onchange = function(){ showImage(config.div,'size'); }; + div.appendChild(select); + + if ('sizes' in config) { + // Use supplied sizes + var sizes = config.sizes; + } else { + var sizes = ['250,', '500,', '1000,']; + if (serviceVersion(getCurrentImage(config.div)) == '2') { + sizes.push('full'); + } else { + sizes.push('max'); + } + } + + addOptions('size_' + config.div, sizes, '', ''); +} + +function addRotation(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('rotation')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Rotation')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','rotation'); + select.id = 'rotation_' + config.div; + select.onchange = function(){ showImage(config.div,'rotation'); }; + div.appendChild(select); + + var rotations = null; + if ('rotations' in config) { + // Use supplied rotations + rotations = config.rotations; + } + updateRotation(config.div, rotations); +} + +function updateRotation(uuid, suppliedRotations) { + if (suppliedRotations) { + var rotations = suppliedRotations; + } else { + var rotations = ['0']; + if (supports(getCurrentImage(uuid), 'rotationBy90s')) { + rotations.push('90'); + rotations.push('180'); + rotations.push('270'); + } + if (supports(getCurrentImage(uuid), 'rotationArbitrary')) { + rotations.push('45'); + rotations.push('135'); + } + if (supports(getCurrentImage(uuid), 'mirroring')) { + rotations.push('!0'); + rotations.push('!180'); + } + } + addOptions('rotation_' + uuid, rotations, '', ''); +} + +function addOptions(identifier, options, prepend, append, selected=null) { + var select = document.getElementById(identifier); + clearSelect(select); + for (var i = 0; i < options.length; i++) { + var optionValue = options[i]; + option = document.createElement('option'); + option.text = prepend + optionValue + append; + option.value = optionValue; + + select.appendChild(option); + } + if (selected != null) { + select.value = prepend + selected + append; + } +} + +function addQuality(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('quality')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Quality')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','quality'); + select.id = 'quality_' + config.div; + select.onchange = function(){ showImage(config.div,'quality'); }; + div.appendChild(select); + + var qualities = null; + if ('qualities' in config) { + // Use supplied qualities + qualities = config.qualities; + } + updateQuality(config.div, qualities); +} + +function updateQuality(uuid, suppliedQualities) { + var select = document.getElementById('quality_' + uuid); + clearSelect(select); + if (suppliedQualities) { + var qualities = suppliedQualities; + } else { + var qualities = getImageQualities(uuid); + } + addOptions('quality_' + uuid, qualities, '', '', 'default'); +} + +function addFormats(ul, config) { + var li = document.createElement('li'); + if ('highlight' in config && config.highlight.includes('format')) { + li.setAttribute('class', 'highlight'); + } + ul.appendChild(li); + li.appendChild(createDescription('Format')); + + var div = createElementStyle('div', 'attr2'); + li.appendChild(div); + + var select = createElementStyle('select','format'); + select.id = 'format_' + config.div; + select.onchange = function(){ showImage(config.div,'format'); }; + div.appendChild(select); + + var formats = null; + if ('formats' in config) { + // Use supplied formats + formats = config.formats; + } + updateFormats(config.div, formats); +} + +function updateFormats(uuid, suppliedFormats) { + var select = document.getElementById('format_' + uuid); + clearSelect(select); + if (suppliedFormats) { + var formats = suppliedFormats; + } else { + var formats = getImageFormats(uuid); + } + addOptions('format_' + uuid, formats, '.', ''); +} + +function serviceVersion(image) { + var version = '2'; + if (image in infoJsons) { + var infoJson = infoJsons[image]; + if ('type' in infoJson && infoJson['type'] == "ImageService3") { + version = '3'; + } + } + return version; +} + +function getImageFormats(uuid) { + var image = getCurrentImage(uuid); + var infoJson = infoJsons[image]; + + var version = serviceVersion(image); + var formats = ['jpg']; + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object') { + if ('formats' in infoJson.profile[i]) { + for (var j = 0; j < infoJson.profile[i]['formats'].length; j++) { + if (!formats.includes(infoJson.profile[i]['formats'][j])) { + formats.push(infoJson.profile[i]['formats'][j]); + } + } + } + } else { + if (infoJson.profile[i] == "http://iiif.io/api/image/2/level2.json" && !(formats.includes('png'))) { + formats.push('png'); + } + } + } + } + } else { + if (infoJson['profile'] == 'level2') { + formats.push('png'); + } + if ('extraFormats' in infoJson) { + for (var i = 0; i < infoJson['extraFormats']; i++) { + if (!formats.includes(infoJson['extraFormats'][i])) { + formats.push(infoJson['extraFormats'][i]); + } + } + } + } + return formats; +} + +function getImageQualities(uuid) { + var image = getCurrentImage(uuid); + var infoJson = infoJsons[image]; + + var version = serviceVersion(image); + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object' && 'qualities' in infoJson.profile[i]) { + let qualities = infoJson.profile[i]['qualities']; + if (!qualities.includes("default")) { + qualities.unshift("default"); + } + return qualities; + } + } + } + return ['default']; + } else { + if ('extraQualities' in infoJson) { + return infoJson['extraQualities'] + } else { + return ['default']; + } + } +} + +function supports(image, feature) { + var infoJson = infoJsons[image]; + var version = serviceVersion(image); + if (version == '2') { + if ('profile' in infoJson) { + for (i = 0; i < infoJson.profile.length; i++) { + if (typeof infoJson.profile[i] === 'object' && 'supports' in infoJson.profile[i]) { + return infoJson.profile[i]['supports'].includes(feature); + } + } + } + return false; + } else { + if ('extraFeatures' in infoJson) { + return infoJson['extraFeatures'].includes(feature); + } + return false; + } +} + +function getCurrentImage(ident) { + var select = document.getElementById('identifier_' + ident); + return select.options[select.selectedIndex].value; +} + +function createDescription(text) { + var div = document.createElement('div'); + div.setAttribute('class', 'attr'); + div.innerHTML = text; + + return div; +} + +function createElementStyle(element, style) { + var el = document.createElement(element); + el.setAttribute('class', style); + + return el; +} + + /*
  • +
    Region
    +
    + +
    +
  • +
  • +
    Size
    + +
    +
  • +
  • +
    Rotation
    +
    + +
    +
  • +
  • +
    Quality
    +
    + +
    +
  • +
  • +
    Format
    +
    + +
    +
  • + + +
    + + +
    +
    + +
    */ + + + +function showImage(uuid, source) { + if (source == 'identifier') { + updateRegion(uuid, null); + updateRotation(uuid, null); + updateQuality(uuid, null); + updateFormats(uuid, null); + } + var identifier = getSelected(uuid, 'identifier'); + var region = getSelected(uuid, 'region'); + var size = getSelected(uuid, 'size'); + var rotation = getSelected(uuid, 'rotation'); + var quality = getSelected(uuid, 'quality'); + var format = getSelected(uuid, 'format'); + + var url = identifier + "/" + region + "/" + size + "/" + rotation + "/" + quality + "." + format; + + var link = document.getElementById('link'); + link.href = url + link.innerHTML = url + + //var img = document.getElementById('iiif-image-api-div'); + //img.style.backgroundImage = "url(" + identifier + "/full/" + size + "/0/" + quality + format + ")"; + + /*var highlight = document.getElementById('highlight'); + if (region.indexOf(',') != -1) { + coords = region.split(','); + highlight.style.top = coords[0] + "px"; + highlight.style.left = coords[1] + "px"; + highlight.style.width = coords[2] + "px"; + highlight.style.height = coords[3] + "px"; + } else if (region == "full") { + highlight.style.top = "0px"; + highlight.style.left = "0px"; + highlight.style.width = img.offsetWidth; + highlight.style.height = img.offsetHeight; + }*/ + + var img = document.getElementById(uuid + '_iiif-image-api-img'); + img.src = url; +} + +function getSelected(uuid, ident) { + var select = document.getElementById(ident + '_' + uuid); + return select.options[select.selectedIndex].value; +} + +function getURLParameter(param) { + if(typeof(param) == "string" && param.length > 0) { + if(typeof(window.location.search) == "string" && window.location.search.length > 0) { + var _results = new RegExp(param + "=([^&]*)", "i").exec(window.location.search); + if(typeof(_results) == "object" && _results !== null && typeof(_results.length) == "number" && _results.length > 0 && _results[1]) { + if(typeof(_results[1]) == "string" && _results[1].length > 0) { + return unescape(_results[1]); + } + } + } + } + return null; +} diff --git a/dhsi/day-one/week-overview.md b/dhsi/day-one/week-overview.md new file mode 100644 index 00000000..1cec2469 --- /dev/null +++ b/dhsi/day-one/week-overview.md @@ -0,0 +1,36 @@ +# Week Overview + +## Day 1 Goals + +* Introductions +* The "Why" Behind IIIF +* Introduction to the IIIF Image API +* Build Projects with the IIIF Image API + +## Day 2 Goals + +* Review the IIIF Image +* Based on our previous work, reflect the on the benefits if the Image API and think about what else is needed +* Transition to the IIIF Presentation API +* Generate Manifests +* Publishing Manifests +* Using and Configuring IIIF Viewers in our own Projects + + +## Day 3 Goals + +* Focus on more advanced use cases +* Creating and Publishing Annotations +* IIIF search API as a way to Search Annotations +* Keep building your projects and integrating IIIF components + +## Day 4 Goals + +* Show and Tell of Some Advanced Use Cases from Niqui and Jeff +* Learn to use Wax and Jekkyll to create a polished and maintainable website that can integrate and display IIIF resources +* Keep working and polishing week projects + +## Day 5 Goals + +* Class Show and Tell. +* Show us what you've been working on all week. \ No newline at end of file diff --git a/dhsi/day-one/whatisiiif.md b/dhsi/day-one/whatisiiif.md new file mode 100644 index 00000000..9807943f --- /dev/null +++ b/dhsi/day-one/whatisiiif.md @@ -0,0 +1,162 @@ +# What is IIIF? + +IIIF stands for the International Image Interoperability Framework and is best described by looking at the acronym. Broadly it is two things: + +
    IIIF is a globally-adopted open source standardized model for delivering many types of image-based resources on the web in many different formats so that audiences can interact with them. It provides a lot of benefits to the institutions that use it, and when implemented across many institutions provides additional benefits across institutional boundaries.
    +
    +
    But, IIIF is more than a standard: it is also an open, global community of software developers, librarians, researchers, educators, museums, universities, creative agencies, and more that work together to develop open APIs, implement them in software, and expose images and A/V files. It’s a grassroots effort between many different institutions to solve their shared problems with delivering, managing, sharing, and working with their resources."
    + +## Community Resources +- [Listserv](https://groups.google.com/g/iiif-discuss) +- [Slack](http://bit.ly/iiif-slack) +- [Newsletter](https://iiif.io/newsletter) +- [Group Calls](https://iiif.io/community/groups/) +- [Zenodo](https://zenodo.org/communities/iiif/) +- [Awesome-IIIF](https://github.com/IIIF/awesome-iiif/) +- [GitHub](https://github.com/IIIF/) + +## International + +IIIF has been implemented internationally and is not based in one country. It has been implemented by places like: + + * National Institutions: + * Österreichische Nationalbibliothek (Austrian National Library), + * [BnF](https://guides.iiif.io/guides/gallica.bnf.fr/), + * [Library of Congress](https://guides.iiif.io/guides/loc.gov/) and + * the British library. + * Aggregators: + * Artstore, + * ContentDM, + * Internet Archive and + * Europeana + * Universities & Research Institutions: + * [Göttingen University Collections](https://guides.iiif.io/guides/gdz.sub.uni-goettingen.de/), + * [Leiden University](https://guides.iiif.io/guides/universiteitleiden.nl/) and + * [Stanford University](https://guides.iiif.io/guides/searchworks.stanford.edu/) + * Museums & Galleries: + * British Museum, + * [National Gallery of Art (US)](https://guides.iiif.io/guides/nga.gov/) and + * [J. Paul Getty Trust](https://guides.iiif.io/guides/search.getty.edu/), + +For a fuller list of institutions who advertise their IIIF resources please see the [IIIF guides](https://guides.iiif.io/) site. + + + +## Image* + +First and foremost IIIF started with the problem of making large images available on the Web. This means allowing users to zoom into large images in way that is scaleable and allows quick zooming without visual lag on large images. + +One of the examples of this is with the Japanese Tax Map below. In the image Wayne Vanderkuil, the Stanford lead photographer is shown next to the map for a sense of scale. Wayne is 6' 4" (1.93m) tall. The map is so big that it had to be photographed in separate sections and stitched together using Photoshop. If you click on the image below you will be taken to the IIIF image which allows you to zoom around this massive map. + + + +For details on how this map was scanned, there is a blog post [here](https://web.archive.org/web/20230527005027/https://library.stanford.edu/blogs/digital-library-blog/2015/11/adventures-oversized-imaging-digitizing-omi-kuni-ezu-jin-jiang). + +* the star next to the image is because IIIF now also supports Audio Visual resources but it was too late to change the name... + +Here is an example of a video with table of contents shown in the [Universal Viewer](https://uv-v3.netlify.app/#?c=&m=&s=&cv=&manifest=https%3A%2F%2Fiiif.io%2Fapi%2Fcookbook%2Frecipe%2F0003-mvm-video%2Fmanifest.json) + +## Interoperability + +Interoperability can be though of in different ways and there are a few examples below on how IIIF achieves this interoperability. + +### Interoperable Viewers + +First because IIIF provides a standard way of exposing images and metadata it is possible to switch viewers to view the same content. Users might want to do this for a number of reasons: + + * A Library provides content in a general purpose Viewer like the UniversalViewer + * A user might want to take that manuscript and annotate it Mirador + * A user might want to run some AI tools using the Curation IIIF image viewer + +![Same IIIF manifest in UV and Mirador](img/viewers.png) + + * [Manuscript in NLW using the UniversalViewer](http://hdl.handle.net/10107/4574752) + * [Same Manuscript in Mirador 3](https://projectmirador.org/embed/?iiif-content=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + * [Tify](https://demo.tify.rocks/demo.html?manifest=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + * [IIIF Curation Viewer](http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/?manifest=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + * [Annona](https://ncsu-libraries.github.io/annona/tools/#/display?url=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json&viewtype=iiif-storyboard&settings=%7B%22fullpage%22%3Atrue%7D) + * [Clover](https://samvera-labs.github.io/clover-iiif/docs/viewer/demo?iiif-content=https://damsssl.llgc.org.uk/iiif/2.0/4574752/manifest.json) + +For instructions on how to take content from one viewer to another there is this [medium post](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013). We will also be covering this in the workshop. + +### Interoperable Images + +The second way IIIF does interoperability is by allowing remote distributed images to be reunited in new digital editions. The manuscript below is one that was owned by the infamous biblioclast Otto Ege. In the early 20th century he split the manuscript and sold individual pages to institutions across the US. Using IIIF these images have been reconstructed in the following way: + +![Image showing how the manuscript was constructed with remote images](img/otto_ege.png) + +The full manuscript can be viewer [here](https://projectmirador.org/embed/?iiif-content=https://dms-data.stanford.edu/data/manifests/Stanford/ege1/manifest.json). + +Another example of a reconstructed manuscript is the one below from the BnF. Instead of brining together full images only the illustrations have been cut out and these are overlaid onto the original manuscript. In this example the illustrations are held by on institution and the manuscript by another. + + + +The full demo of this manuscript can be found on the [Biblissima website](https://demos.biblissima.fr/chateauroux/demo/). + +There is also a IIIF Cookbook [recipe](https://iiif.io/api/cookbook/recipe/0036-composition-from-multiple-images/) for this example which supports version 3. + + +### Interoperable Collections + +As well as brining distributed images together it is also possible to compare different collections in a single viewer. The Mirador viewer allows side by side comparison and using the techniques discussed earlier its possible for users to collect manifests from different locations and then compare them side by side. The example we are going to use here is from a [blog by Ben Albritton of Stanford University](https://blalbrit.github.io/2015/07/14/fellow-travelers-the-canterbury-tales-and-iiif). It shows two copies of Chaucer's Canterbury Tales one from the National Library of Wales based in the UK and one from the Huntington Library in Los Angeles. + + + + + + +
    + + + +## Framework + +The last part of the acronym is Framework and this is for the different standards that IIIF provides to ensure viewers and publishers all agree on sharing compatible data. These standards are known as [APIs](https://en.wikipedia.org/wiki/API) and the two main APIs are: + +![Image and Presentation APIs](img/apis.png) + +These two APIs will be covered in detail in the rest of the workshop. As well as these APIs there are a number of other APIs defined by IIIF including: + + * [Content Search API](https://iiif.io/api/search/1.0) - to search annotations, a bit like a searching within a PDF file + * [Authentication API](https://iiif.io/api/auth/1.0) - for protecting resources by username or giving lower quality images to unauthenticated users + * [Change Discovery API](https://iiif.io/api/discovery/) - for Aggregators like Europeana to harvest IIIF data + * [Content State API](https://iiif.io/api/content-state/) - to improve the method of taking content from one viewer to another + * [Maps Extension](https://iiif.io/api/extension/navplace/) - to link a Geographical place to a IIIF object. Could be used to Georeference a map or photograph. + diff --git a/dhsi/day-one/whyiiif.md b/dhsi/day-one/whyiiif.md new file mode 100644 index 00000000..93a73d51 --- /dev/null +++ b/dhsi/day-one/whyiiif.md @@ -0,0 +1,15 @@ +# Why use IIIF? + +## Interoperability +- Interoperability provides the ability to mix and match tools +- Allows developers to create open tools not wedded to closed standards +- Excel vs. CSV + +## Storage implications +- No longer have to create small, medium, large derivatives + +## High quality images +- Allows for zooming with high quality images without lag time + +## Reusable +- Format of IIIF apis allow easy sharing, embedding \ No newline at end of file diff --git a/dhsi/day-one/workbench.md b/dhsi/day-one/workbench.md new file mode 100644 index 00000000..7a43a03a --- /dev/null +++ b/dhsi/day-one/workbench.md @@ -0,0 +1,25 @@ +# IIIF training workbench +The IIIF training workbench that is often used in IIIF training workshops like this. It allows for creating IIIF views via a browser. We are going to be using it to create some IIIF images. + +1. Open https://workbench.gdmrdigital.com/login.xhtml +2. Click on the Login with GitHub button +![](img/workbench-1.png) +3. Click "Create project" button +![](img/workbench-2.png) +4. Name your project and click create +![](img/workbench-3.png) +5. Click on the upload button in the upper right hand corner. +![](img/workbench-4.png) +6. Click on browse and choose image from your computer. +7. Provide a name for the image and choose IIIF version +![](img/workbench-5.png) +8. Wait for the image to process +![](img/workbench-6.png) +9. Look at the links that are provided when the process is finished running. +![](img/workbench-7.png) + + +# Thoughts? +- What are some of the limitations of this approach? +- What are some of the positives of this approach? +- Any other thoughts? \ No newline at end of file diff --git a/dhsi/day-three/BL-Audio/README.md b/dhsi/day-three/BL-Audio/README.md new file mode 100644 index 00000000..7dd363f9 --- /dev/null +++ b/dhsi/day-three/BL-Audio/README.md @@ -0,0 +1,293 @@ +# Deep dive into the BL sound collection + +The British Library has kindly provided a number of [examples](examples.md) of audio content to look at. We are going to analyse one of these Manifests and then look at creating our own Manifest by re-using the recordings from other manifests. + +The example we are going to use is the "Sal's Got A Sugar Lip/Driftwood" recording which can be viewed here: + +https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006 + +The viewer which is used to play this recording is known as the Universal Viewer mini player. It shares a lot of code with the Universal Viewer that we've seen for images but is customised to hide things like the metadata and the canvas list. This mini player looks like this: + +![Mini player screenshot](imgs/audio_website.png) + +Unforunately there isn't a link to the IIIF Manifest on this page but this is included in the [examples](examples.md) page and is available below: + +https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/manifest.json + +you can also discover the Manifest by opening up the Network developer tab in your browser and searching for `manifest.json`. + +There are a number of interesting features of this Manifests and before we start customising it we are going to take a look at the Manifest in detail. + +### Canvases + +This particular example contains two canvases and according to the Metadata this particular item is a [7" vinyl record](https://www.vectis.co.uk/vinyl/a-guide-to-record-sizes-and-speeds). There is one canvas for one side of the disk and another for the reverse. + +***Note:*** the JSON in the examples below has been collapsed to focus on the main items. Collapsed items are contained in the `[...]` and can be seen expanded in the full [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/manifest.json). + +``` +items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004", + "type": "Canvas", + "label": { + "en": [ "Disc 1 Side 1" ] + }, + "duration": 182.88, + "items": [ ... ], + "thumbnail": [ ... ] + }, + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000005", + "type": "Canvas", + "label": { + "en": [ "Disc 1 Side 2" ] + }, + "duration": 168.80000000000001, + "items": [...], + "thumbnail": [...] + } +], +``` + +The duration is measured in seconds and is approximately `182 seconds` for the first canvas and `168 seconds` for the second canvas. Interestingly you will note in the [website](https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006) that the two recordings linked below the mini player are called "Sal's Got A Sugar Lip/Driftwood" and "Chesapeake bay/Botsford". You might expect the names of these recordings would come from the canvas label so be "Disc 1 Side 1" and "Disc 1 Side 2". The labels are actually coming from the structure or table of contents explained below. + +### Structure + +You can see in the example below that the label for the files in the [website](https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006) is coming from the range. I believe this is done so that the Manifest can show two different orderings of the content. The first in the sequence that matches the physical layout on disk. The second order is provided in the structures element and is a logical ordering of the recording. In this example the physical layout exactly matches the logical layout so the range targets the full canvas duration. + +You can imagine other scenarios particularly with tapes where the sequence would contain two canvases, one for each side of the tape. The structures element would split the recording into logical units like individual interviews and these could cross between canvases or tape sides so would need to be combined in a range. + +``` +structures": [ + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000006", + "type": "Range", + "label": { + "en": [ "Sal's Got A Sugar Lip/Driftwood" ] + }, + "metadata": [...], + "requiredStatement": {...}, + "rendering": [...], + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004#t=00.00,182.88", + "type": "Canvas" + } + ] + }, + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000008", + "type": "Range", + "label": { + "en": [ "Chesapeake bay/Botsford" ] + }, + "metadata": [...], + "requiredStatement": {...}, + "rendering": [ ... ], + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000005#t=00.00,168.80", + "type": "Canvas" + } + ] + } + ] +] +``` + +## Canvas deep dive + +The canvas is a core feature of IIIF. For images the canvas is usually equivalent to a page in a book. For AV material the distinction can be more complicated. It is sometimes thought of as a empty powerpoint slide where images or audio are `painted` on to the slide at particular positions. + +In the image below you can see the canvas has a height and a width. The example image is `painted` on to the full canvas so that the canvas width and height match the image width and height. This is the most common use case for IIIF images. + +![Diagram showing painting of an image on to a canvas.](imgs/IIIF_AV_EuropeanWorkingGroup1.png) + +In the following example you can see two images are painted onto one canvas. One image is the background manuscript and the second image is the illustration. The background manuscript image is `painted` on to the canvas and matches the canvas height and width. The Illustration is `painted` on to a particular region of the canvas so that it appear in the correct place. + +![Alt text](imgs/IIIF_AV_EuropeanWorkingGroup2.png) + +The support for AV in IIIF entailed the addition of duration to the canvas. Now a canvas can have a height, width and duration. Different dimensions are needed for different content types i.e: + + * Images required width and height + * Audio only files require duration + * Video files required width, height and duration + +![Alt text](imgs/IIIF_AV_EuropeanWorkingGroup3.png) + +With the canvas example below we have an canvas duration of 10 seconds. We can now `paint` an image on to the canvas and set it for a duration of 10 seconds so it will show for the full duration of the canvas. + +![Alt text](imgs/IIIF_AV_EuropeanWorkingGroup4.png) + +We can also `paint` a video on to the canvas and in the example below it is painted on a particular region of the canvas and set to play starting at second 4 and finishing at second 7. + +![Alt text](imgs/IIIF_AV_EuropeanWorkingGroup5.png) + +You can keep on adding images, videos and text to create a complicated canvas. The examples above where developed during the discussions on adding AV and a prototype presentation of this canvas can be seen at the following URL: + +https://tomcrane.github.io/fire/ + +The method for `painting` an image, audio or video resource on to a IIIF canvas is done through an annotation. If we look at the following example where we can assume the body of the annotation is an audio recording. We can see the `target` points to the canvas ID and adds `#t=00.00,182.88` to the end of the canvas id. This means the body (audio resource) is painted on to the canvas from the start (second 00.00) to the end (second 182.88). In this case the `target` points to the full duration of the canvas so the addition of the `#t=00.00,182.88` isn't necessary as if the target points to the canvas id then it is assumed to cover the full duration of the canvas. + +``` +{ + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004/anno1/1", + "type": "Annotation", + "motivation": "painting", + "target": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004#t=00.00,182.88", + "body": [ ... ] +} +``` + +Note if the audio resource in the body is longer than the time specified in the canvas it should be played faster and if the audio resource is shorter than the target region then it should be played slower to fit the desired duration. + +The full first canvas for the example is shown below. + +``` +{ + + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004", + "type": "Canvas", + "label": { + "en": [ + "Disc 1 Side 1" + ] + }, + "duration": 182.88, + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004/anno1", + "type": "AnnotationPage", + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004/anno1/1", + "type": "Annotation", + "motivation": "painting", + "target": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000004#t=00.00,182.88", + "body": [ + { + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100140656320.0x00000e/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound", + "service": [ ... ] + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100140656320.0x00000e/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound", + "service": [...] + } + ] + } + ], + "seeAlso": [...] + } + ] + } + ], + "thumbnail": [ ... ] +}, +``` + +### Providing access to different audio formats + +Another interesting aspect of this Manifest is the `choice` that is present in the annotation body. Usually you would just see a link to the audio resource as in this [IIIF Cookbook recipe](https://iiif.io/api/cookbook/recipe/0002-mvm-audio/). With the choice in the body you are providing the IIIF Viewer with the option to choose one of the formats. It maybe that the viewer only support one type and so would select that one. The two formats available are [MPEG-Dash](https://en.wikipedia.org/wiki/Dynamic_Adaptive_Streaming_over_HTTP) and [HTTP live Streaming](https://en.wikipedia.org/wiki/HTTP_Live_Streaming). It appears both formats are similar streaming formats but are supported by different devices: + +___"Both HLS and MPEG-DASH offer adaptive streaming and similar levels of quality and latency. But HLS is best for live streaming, while MPEG-DASH is best for on-demand streaming. HLS is more compatible with Apple devices, while MPEG-DASH is more compatible with other devices."___ + +From: https://www.gumlet.com/learn/hls-vs-dash/ + +``` +"body": [ + { + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100140656320.0x00000e/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound", + "service": [ ... ] + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100140656320.0x00000e/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound", + "service": [...] + } + ] + } +], +``` + +### Waveform image + +When you view the example audio file on the [website](https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006) you will see a Waveform which can be used to visualize the audio recording. This is achieved by adding a `seeAlso` to the canvas pointing to the Waveform. The `seeAlso` property is used to point to machine readable metadata and in this case points to a generated Waveform presumably using the [BBC tools](https://waveform.prototyping.bbc.co.uk/). Viewers won't necessarily support the Waveform profile but in this case the UV will show an image of the Waveform to enable easier browsing through a recording. + +``` +seeAlso": [{ + "id": "https://api-beta.bl.uk/waveform/vdc_100140656320.0x000010", + "type": "Dataset", + "format": "application/octet-stream", + "profile": "http://waveform.prototyping.bbc.co.uk" +}] +``` + +### Accompanying canvas + +This can't be seen in the BL sound website but there is an image associated with the Manifest which should be shown to the user while the audio is playing. Having this accompanying canvas allows the viewer to show something if it they can't process the Waveform profile. The supplied image is of the original vinyl: + +![Alt text](https://api-beta.bl.uk/image/static/ark:/81055/vdc_100140656320.0x000011?vdc_100140656320.0x000002) + +An Accompanying Canvas is a special type of Canvas which is played while the main content is also playing. There is a [Cookbook recipe](https://iiif.io/api/cookbook/recipe/0014-accompanyingcanvas/) on accompanying canvas with further details on it's use. + +``` +"accompanyingCanvas": { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/c/poster", + "type": "Canvas", + "label": { + "en": [ "Illustration" ] + }, + "width": 1440, + "height": 1434, + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/c/a1", + "type": "AnnotationPage", + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/c/a1/a1", + "type": "Annotation", + "motivation": "painting", + "target": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/c/poster", + "body": [ + { + "id": "https://api-beta.bl.uk/image/static/ark:/81055/vdc_100140656320.0x000011?vdc_100140656320.0x000002", + "type": "Image", + "width": 1440, + "height": 1434, + "format": "image/jp2" + } + ] + } + ] + } + ] + +}, +``` + +### View Manifest in full UV + +To see some of the hidden functionality we can have a look at the Manifest in the regular Universal Viewer: + +https://uv-v4.netlify.app/#?manifest=https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/manifest.json + +You will notice a number of differences with the mini player. For example: + +* The accompanying canvas image is showing. +* The canvas labels for each side of the disk can be seen in the Thumbnails tab on the left hand side. +* The Range is shown by switching the Thumbnails tab to Index. diff --git a/dhsi/day-three/BL-Audio/RemixAudio.md b/dhsi/day-three/BL-Audio/RemixAudio.md new file mode 100644 index 00000000..3a8f87d6 --- /dev/null +++ b/dhsi/day-three/BL-Audio/RemixAudio.md @@ -0,0 +1,224 @@ +# Remix an audio file + +For this exercise we are going to take the "Rough sea with heavy surf, England, 1996" recording from the following item: + +https://sounds.bl.uk/sounds/rough-sea-with-heavy-surf-england-1996-1001429387280x000028 + +We are then going to create a new Manifest and add a table of contents using the Indiana University Timeliner tool. + +## Step 1: Find the information about the recording + +The manifest for the above recording is available at: + +https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/manifest.json + +and searching for the label "Rough sea with heavy surf, England, 1996" we find the following range: + +``` +{ + + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000028", + "type": "Range", + "label": { + "en": [ + "Rough sea with heavy surf, England, 1996" + ] + }, + "metadata": [...], + "rights": "https://creativecommons.org/licenses/by/4.0", + "requiredStatement": {...}, + "rendering": [...], + items": [{ + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/canvas/node-id-000040#t=00.00,112.00", + "type": "Canvas" + }] +} +``` + +Using the canvas id in the `items` part of the range we can find the canvas that we want. + +``` +{ + + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/canvas/node-id-000040", + "type": "Canvas", + "label": { + "en": [ + "[No Title]" + ] + }, + "duration": 112.0, + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/canvas/node-id-000040/anno20", + "type": "AnnotationPage", + "items": [ + { + "id": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/canvas/node-id-000040/anno20/1", + "type": "Annotation", + "motivation": "painting", + "target": "https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/canvas/node-id-000040#t=00.00,112.00", + "body": [ + { + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound", + "service": [ + { + "id": "https://api-beta.bl.uk/auth/iiif/login", + "type": "AuthCookieService1" + }, + { + "id": "https://api-beta.bl.uk/media/dash/ark:/81055/vdc_100142938728.0x000056/probe.json", + "type": "AuthProbeService1", + "profile": "http://iiif.io/api/auth/1/probe" + } + ] + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound", + "service": [ + { + "id": "https://api-beta.bl.uk/auth/iiif/login", + "type": "AuthCookieService1" + }, + { + "id": "https://api-beta.bl.uk/media/hls/ark:/81055/vdc_100142938728.0x000056/probe.json", + "type": "AuthProbeService1", + "profile": "http://iiif.io/api/auth/1/probe" + } + ] + } + ] + } + ], + "seeAlso": [ + { + "id": "https://api-beta.bl.uk/waveform/vdc_100142938728.0x000056", + "type": "Dataset", + "format": "application/octet-stream", + "profile": "http://waveform.prototyping.bbc.co.uk" + } + ] + } + ] + } + ], + "thumbnail": [ + { + "id": "https://api-beta.bl.uk/hub-logo/audio-tape.png", + "Type": "Image" + } + ] + +}, +``` + +The bits we are interested in are the duration and the links to the files: + +``` + "duration": 112.0, +``` + +``` + "body": [ + { + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound" + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound" + } + ] + } + ], +``` + +Note the authorization services have been removed. As this content is open access the authentication service doesn't function for this resource so to simplifying things it can be removed. + +## Step 2: Use the cookbook example and insert new recording + +Download the JSON-LD from the Audio cookbook by right clicking on the JSON-LD link and clicking "Save Link As": + +https://iiif.io/api/cookbook/recipe/0002-mvm-audio/ + +Save the manifest.json to your `iiif-workshop` directory and called it `av-manifest.json`. + +Edit the duration field to `112.00` and copy in the body from the code sample above. You should have a manifest that looks like [manifest-single-recording.json](manifest-single-recording.json). + +Now test that this manifest works before we go any further. Ensure you have the VS Code Live Server running then you should be able to click on the following link to view your Manifest: + +https://uv-v4.netlify.app/#?manifest=http://127.0.0.1:5500/av-manifest.json&c=&m=&s=&cv=&xywh= + +## Step 3: Load Manifest to Timeliner + +Now you have the manifest working you need to make a slight change to the manifest so that it will open in the Timeliner. This is to do with the order of the different audio files as Timeliner currently has a problem with MPEG-Dash files. In the av-manifest.json file swap the different files so the index.m3u8 one is first: + +``` +"type": "Choice", +"items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound" + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound" + } +] +``` + +Now navigate to the Timeliner and add the link to your manifest: + +https://timeliner.dlib.indiana.edu/app/index.html# + +![Alt text](imgs/timeliner-open.png) + +To break the recording up into chapters click on the thin line highlighted in the image below. Then click the + button to create a new section. You can edit the name and colour of your section by clicking the pencil next to the section name. + +![Alt text](imgs/timeliner-gtk.png) + +Create three or four chapters by repeating the steps above. + +## Step 4: Test table of contents + +You can now export your work from the Timeliner application. The export will create a new manifest which contains your original audio resource and also the added structures element. To do this click the Download this timeline button highlighted below. + +![Download manifest button](imgs/timeliner-export.png) + +Now we can test to see if the changes you made work in the Universal Viewer. + +Unfortunately the UV doesn't support HLS and the Timeliner doesn't support MPEG dash so in step 3 above we had to re-organise the order of derivatives and now we have to do the reverse so that MPEG dash is first. + +``` + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound" + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/index.m3u8", + "format": "application/vnd.apple.mpegURL", + "type": "Sound" + }, + ] +``` + +Once you have done this change you should be able to open your manifest in the UV and see the table of contents included. + +https://uv-v4.netlify.app/#?manifest=http://127.0.0.1:5500/av-manifest.json&c=&m=&s=&cv=&xywh= \ No newline at end of file diff --git a/dhsi/day-three/BL-Audio/bl_examples.csv b/dhsi/day-three/BL-Audio/bl_examples.csv new file mode 100644 index 00000000..2566232f --- /dev/null +++ b/dhsi/day-three/BL-Audio/bl_examples.csv @@ -0,0 +1,40 @@ +Sounds Website URLs,Shelfmark,Title,IIIF +Skiffle,,, +https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006,1SE0039342,Lonnie Donegan and his Skiffle Group: Sal's Got A Sugar Lip/Driftwood,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/manifest.json +https://sounds.bl.uk/sounds/grey-gooseleadbetter-1001406510460x000006,"1CS0042552,1CS0042295",Ken Colyer's Skiffle Group: The grey goose / I can't sleep,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140651046.0x000002/manifest.json +https://sounds.bl.uk/sounds/they-cant-take-that-away-from-megershwin-1001406513750x000006,1CS0042419,Dickie Bishop and The Sidekicks: They can't take that away from me / Jumpin' Judy,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140651375.0x000002/manifest.json +,,, +Wildlife,,, +https://sounds.bl.uk/sounds/brent-goose-england-1981-1001429387280x000008,WA 2022/001/002,Coast and sea,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/manifest.json +https://sounds.bl.uk/sounds/british-chaffinch-england-1988-1001429413870x000006,WA 2022/001/005,"Home, garden and farm",https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142941387.0x000001/manifest.json +https://sounds.bl.uk/sounds/common-chiffchaff-england-1990-1000828534710x000005,"W1CDR0000135,W2CDR0000135",Wildlife CD-R recordings,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100082853471.0x000002/manifest.json +https://sounds.bl.uk/sounds/common-raven-england-1971-1001429417600x000008,WA 2022/001/006,Moorland and mountain,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142941760.0x000001/manifest.json +https://sounds.bl.uk/sounds/strong-breeze--around-force-6-wales-1989-1001429387280x00002c,WA 2022/001/002,Coast and sea,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/manifest.json +,,, +Mechanical sounds,,, +https://sounds.bl.uk/sounds/synthesised-handbells-1000944111840x000006,ULMA019/54,Whitechapel Bell Foundry: Test run of the first tune programme,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100094411184.0x000002/manifest.json +https://sounds.bl.uk/sounds/the-bells-of-wells-cathedral-2-1001041072260x000007,C522/1,Bells of Wells Cathedral,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100104107226.0x000002/manifest.json +,,, +Environment,,, +https://sounds.bl.uk/sounds/atmosphere-palearctic-woodland-engtland-1998-1001316350200x000005,WA 2010/017/547,British wildlife WA 2010/017: Woodland,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131635020.0x000002/manifest.json +https://sounds.bl.uk/sounds/witherslack-dawn-chorus-england-1985-1001316341820x000005,WA 2010/017/447,"British wildlife WA 2010/017: Dawn chorus, Witherstack",https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131634182.0x000002/manifest.json +https://sounds.bl.uk/sounds/thunderstorm-heavy-rain-england-1983-1001316342600x00000d,WA 2010/017/448,British wildlife WA 2010/017: Country effects,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131634260.0x000002/manifest.json +,,, +World and Traditional Music,,, +https://sounds.bl.uk/sounds/nepalese-folk-song-1-1000817470380x000005,C30/1,Roger Waldron Collection: Three Nepali folk songs,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100081747038.0x000002/manifest.json +https://sounds.bl.uk/sounds/staten-island-or-burns-hornpipe-1001519493120x000015,C1002/36,Keith Summers Collection: Fred Whiting / Harkie Nesling - A & B,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100151949312.0x000002/manifest.json +https://sounds.bl.uk/sounds/prsentation-sanankoro-jazz-1001279656480x000002,C1583/2/7,Endangered Archives Programme: Guinea's Syliphone Archives: [No Title],https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100127965648.0x000001/manifest.json +https://sounds.bl.uk/sounds/douga-1001314843010x000002,C1583/3/210,Endangered Archives Programme: Guinea's Syliphone Archives: [No Title],https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131484301.0x000001/manifest.json +,,, +Jazz,,, +https://sounds.bl.uk/sounds/bells-of-monterey-1000874914790x000016,C361/1,R. J. Geluk Dutch Radio recordings 1935,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100087491479.0x000002/manifest.json +,,, +Poetry,,, +https://sounds.bl.uk/sounds/the-eighth-sea-1001197727030x00000a,C1163/386,"Dutton, Paul: Fugitive forms",https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100119772703.0x000002/manifest.json +https://sounds.bl.uk/sounds/white-cliffs-of-dover-king-lear--shakespeare-1001321378530x000010,1CS0011604,English Landscape Through Poets' Eyes,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132137853.0x000002/manifest.json +https://sounds.bl.uk/sounds/highwaymannoyes-1001321600940x000008,"9CS0006569,1CS0005288,1CS0005289",Alfred Noyes reads 'The Highwayman' from 'Collected Poems,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132160094.0x000002/manifest.json +,,, +Spoken English,,, +https://sounds.bl.uk/sounds/essential-english--lesson-9-1001321472040x000032,1CL0005081,Essential English,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132147204.0x000002/manifest.json +https://sounds.bl.uk/sounds/punch-and-judy-on-november-the-fifth-1001321365120x000008,1CS0011577,English Playlets,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132136512.0x000002/manifest.json +https://sounds.bl.uk/sounds/john-peel-1001321366850x000022,1CS0011580,English Songs,https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132136685.0x000002/manifest.json \ No newline at end of file diff --git a/dhsi/day-three/BL-Audio/csv2markdown.py b/dhsi/day-three/BL-Audio/csv2markdown.py new file mode 100644 index 00000000..fcf71e95 --- /dev/null +++ b/dhsi/day-three/BL-Audio/csv2markdown.py @@ -0,0 +1,16 @@ + +import csv + +with open('bl_examples.csv', newline='') as csvfile: + data = csv.reader(csvfile) + first=True + for row in data: + if not first: + if row[0] and not row[1]: + print (f'### {row[0]}') + elif row[0] and row[1]: + print (f' * [{row[2]}]({row[0]}) - [manifest.json]({row[3]})') + else: + print('') + else: + first=False diff --git a/dhsi/day-three/BL-Audio/examples.md b/dhsi/day-three/BL-Audio/examples.md new file mode 100644 index 00000000..9746e5ff --- /dev/null +++ b/dhsi/day-three/BL-Audio/examples.md @@ -0,0 +1,55 @@ +# Example content + +The British library have kindly provided the following examples from their collections. + +## British Library sound collections + +* https://sounds.bl.uk/recommendations/wildlife-cd-library +* https://www.bl.uk/collections/endangered-archives-programme-guineas-syliphone-archives +* https://www.bl.uk/collections/eap115-collection-and-digitisation-of-old-music-in-pre-literate-micronesian-society +* https://www.bl.uk/collections/sounds-of-water-wa-2020003 +* https://www.bl.uk/collections/sounds-of-weather-wa-2020004 +* https://www.bl.uk/collections/listen-to-nature + + +## Examples Manifests + +### Skiffle + * [Lonnie Donegan and his Skiffle Group: Sal's Got A Sugar Lip/Driftwood](https://sounds.bl.uk/sounds/sals-got-a-sugar-lipdriftwood-1001406563200x000006) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140656320.0x000002/manifest.json) + * [Ken Colyer's Skiffle Group: The grey goose / I can't sleep](https://sounds.bl.uk/sounds/grey-gooseleadbetter-1001406510460x000006) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140651046.0x000002/manifest.json) + * [Dickie Bishop and The Sidekicks: They can't take that away from me / Jumpin' Judy](https://sounds.bl.uk/sounds/they-cant-take-that-away-from-megershwin-1001406513750x000006) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100140651375.0x000002/manifest.json) + +### Wildlife + * [Coast and sea](https://sounds.bl.uk/sounds/brent-goose-england-1981-1001429387280x000008) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/manifest.json) + * [Home, garden and farm](https://sounds.bl.uk/sounds/british-chaffinch-england-1988-1001429413870x000006) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142941387.0x000001/manifest.json) + * [Wildlife CD-R recordings](https://sounds.bl.uk/sounds/common-chiffchaff-england-1990-1000828534710x000005) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100082853471.0x000002/manifest.json) + * [Moorland and mountain](https://sounds.bl.uk/sounds/common-raven-england-1971-1001429417600x000008) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142941760.0x000001/manifest.json) + * [Coast and sea](https://sounds.bl.uk/sounds/strong-breeze--around-force-6-wales-1989-1001429387280x00002c) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100142938728.0x000001/manifest.json) + +### Mechanical sounds + * [Whitechapel Bell Foundry: Test run of the first tune programme](https://sounds.bl.uk/sounds/synthesised-handbells-1000944111840x000006) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100094411184.0x000002/manifest.json) + * [Bells of Wells Cathedral](https://sounds.bl.uk/sounds/the-bells-of-wells-cathedral-2-1001041072260x000007) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100104107226.0x000002/manifest.json) + +### Environment + * [British wildlife WA 2010/017: Woodland](https://sounds.bl.uk/sounds/atmosphere-palearctic-woodland-engtland-1998-1001316350200x000005) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131635020.0x000002/manifest.json) + * [British wildlife WA 2010/017: Dawn chorus, Witherstack](https://sounds.bl.uk/sounds/witherslack-dawn-chorus-england-1985-1001316341820x000005) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131634182.0x000002/manifest.json) + * [British wildlife WA 2010/017: Country effects](https://sounds.bl.uk/sounds/thunderstorm-heavy-rain-england-1983-1001316342600x00000d) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131634260.0x000002/manifest.json) + +### World and Traditional Music + * [Roger Waldron Collection: Three Nepali folk songs](https://sounds.bl.uk/sounds/nepalese-folk-song-1-1000817470380x000005) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100081747038.0x000002/manifest.json) + * [Keith Summers Collection: Fred Whiting / Harkie Nesling - A & B](https://sounds.bl.uk/sounds/staten-island-or-burns-hornpipe-1001519493120x000015) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100151949312.0x000002/manifest.json) + * [Endangered Archives Programme: Guinea's Syliphone Archives: [No Title]](https://sounds.bl.uk/sounds/prsentation-sanankoro-jazz-1001279656480x000002) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100127965648.0x000001/manifest.json) + * [Endangered Archives Programme: Guinea's Syliphone Archives: [No Title]](https://sounds.bl.uk/sounds/douga-1001314843010x000002) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100131484301.0x000001/manifest.json) + +### Jazz + * [R. J. Geluk Dutch Radio recordings 1935](https://sounds.bl.uk/sounds/bells-of-monterey-1000874914790x000016) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100087491479.0x000002/manifest.json) + +### Poetry + * [Dutton, Paul: Fugitive forms](https://sounds.bl.uk/sounds/the-eighth-sea-1001197727030x00000a) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100119772703.0x000002/manifest.json) + * [English Landscape Through Poets' Eyes](https://sounds.bl.uk/sounds/white-cliffs-of-dover-king-lear--shakespeare-1001321378530x000010) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132137853.0x000002/manifest.json) + * [Alfred Noyes reads 'The Highwayman' from 'Collected Poems](https://sounds.bl.uk/sounds/highwaymannoyes-1001321600940x000008) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132160094.0x000002/manifest.json) + +### Spoken English + * [Essential English](https://sounds.bl.uk/sounds/essential-english--lesson-9-1001321472040x000032) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132147204.0x000002/manifest.json) + * [English Playlets](https://sounds.bl.uk/sounds/punch-and-judy-on-november-the-fifth-1001321365120x000008) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132136512.0x000002/manifest.json) + * [English Songs](https://sounds.bl.uk/sounds/john-peel-1001321366850x000022) - [manifest.json](https://api-beta.bl.uk/metadata/iiif/ark:/81055/vdc_100132136685.0x000002/manifest.json) \ No newline at end of file diff --git a/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup1.png b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup1.png new file mode 100644 index 00000000..6b063d0e Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup1.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup2.png b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup2.png new file mode 100644 index 00000000..53234baf Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup2.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup3.png b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup3.png new file mode 100644 index 00000000..51e7f2a7 Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup3.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup4.png b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup4.png new file mode 100644 index 00000000..f34570e4 Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup4.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup5.png b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup5.png new file mode 100644 index 00000000..bc1ad244 Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/IIIF_AV_EuropeanWorkingGroup5.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/audio_website.png b/dhsi/day-three/BL-Audio/imgs/audio_website.png new file mode 100644 index 00000000..d505eff3 Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/audio_website.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/timeliner-export.png b/dhsi/day-three/BL-Audio/imgs/timeliner-export.png new file mode 100644 index 00000000..6ce7bb65 Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/timeliner-export.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/timeliner-gtk.png b/dhsi/day-three/BL-Audio/imgs/timeliner-gtk.png new file mode 100644 index 00000000..5089c03f Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/timeliner-gtk.png differ diff --git a/dhsi/day-three/BL-Audio/imgs/timeliner-open.png b/dhsi/day-three/BL-Audio/imgs/timeliner-open.png new file mode 100644 index 00000000..31f52a0b Binary files /dev/null and b/dhsi/day-three/BL-Audio/imgs/timeliner-open.png differ diff --git a/dhsi/day-three/BL-Audio/manifest-single-recording.json b/dhsi/day-three/BL-Audio/manifest-single-recording.json new file mode 100644 index 00000000..19b939b3 --- /dev/null +++ b/dhsi/day-three/BL-Audio/manifest-single-recording.json @@ -0,0 +1,46 @@ +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/manifest.json", + "type": "Manifest", + "label": { + "en": [ + "Simplest Audio Example 1" + ] + }, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas", + "type": "Canvas", + "duration": 112.0, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas/page", + "type": "AnnotationPage", + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas/page/annotation", + "type": "Annotation", + "motivation": "painting", + "body": { + "type": "Choice", + "items": [ + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/index.m3u8", + "type": "Sound", + "format": "application/vnd.apple.mpegURL" + }, + { + "id": "https://api-beta.bl.uk/media/iiif/ark:/81055/vdc_100142938728.0x000056/manifest.mpd", + "format": "application/dash+xml", + "type": "Sound" + } + ] + }, + "target": "https://iiif.io/api/cookbook/recipe/0002-mvm-audio/canvas" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/dhsi/day-three/README.md b/dhsi/day-three/README.md new file mode 100644 index 00000000..26aa8363 --- /dev/null +++ b/dhsi/day-three/README.md @@ -0,0 +1,17 @@ +# Day Three - IIIF Presentation API +## Wednesday + +### Presentation API + +This day will focus on the IIIF Presentation API. This session will focus on [version 2.1](https://iiif.io/api/presentation/2.1/) of API and core concepts of IIIF Presentation for 2D images. The session for today is split into two videos. The first one gives a background to the IIIF Presentation API and the second one is a practical hands on session taking you through creating your first manifest. + +Prerequisite video: + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=98z9YNFiUqU) + +Main video: + + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=u63jHDH3pDM) diff --git a/dhsi/day-three/annona.md b/dhsi/day-three/annona.md new file mode 100644 index 00000000..161e9df6 --- /dev/null +++ b/dhsi/day-three/annona.md @@ -0,0 +1,21 @@ +# Annona for annotations +Annona was originally built as a viewer specifically for annotations. As such, annotations that aren't tied to manifests can be viewed in Annona. Not the manifest/image does need to referenced in the annotation or it will not work. + +# View annotations +Annona is built to determine the type of item material being passed in. The storyboard viewer will work with Manifests, collections, or annotations. The image viewer will only work with annotations. + +1. Go to [https://ncsu-libraries.github.io/annona/tools/#/tag-builder](https://ncsu-libraries.github.io/annona/tools/#/tag-builder) +2. Click on the `Example with tags` link. +3. You can see it is in a storyboard viewer similar to what we saw earlier with a manifest. This is embeddable in any site. +![](imgs/1-annona.png) +4. Select the image viewer from the dropdown next to the `Add annotation url` button. +![](imgs/2-annona.png) +5. As you can see the annotations which are in JSON are displayed in an embeddable, reusable view. +![](imgs/3-annona.png) +6. If you wanted to change the view, you can check some of the checkboxes. In the image below, the first, second and last checkboxes are checked, which gives a table with the image section, content, and tags. +![](imgs/4-annona.png) + +# Comparing annotations to annotations or images +Annona also provides a multistoryboard view. An example of this can be seen on the [mulistoryboard view page.](https://ncsu-libraries.github.io/annona/multistoryboard/#defaults) + + diff --git a/dhsi/day-three/annonatate.md b/dhsi/day-three/annonatate.md new file mode 100644 index 00000000..0006e30a --- /dev/null +++ b/dhsi/day-three/annonatate.md @@ -0,0 +1,26 @@ +# Annontate +Annontate is a web application that serves as an Annotation server. Instead of writng annotations to a database it writes them to a GitHub repository that also hosts your images and manifests. Go to [https://annonatate.github.io/](https://annonatate.github.io/) for more documentation about the functionality of Annonatate. + +## Getting Started +1. Go to [https://annonatate.fly.dev/](https://annonatate.fly.dev/) +2. Click the `login with GitHub button` +![](https://annonatate.github.io/images/started-1.png) +3. Log in +![](https://annonatate.github.io/images/started-2.png) +4. You should see the homepage +![](https://annonatate.github.io/images/started-3.png) +5. Click on the Add Image button in the My Images section. +![](https://annonatate.github.io/images/create-1.png) +6. Click on the Use external image button. If you want to mess around without a specific image, click on one of the demo images in the section below. +![](https://annonatate.github.io/images/create-2.png) +7. Add the URL of the image or manifest you want. +![](https://annonatate.github.io/images/create-3.png) +8. Choose from one the options that appears. + Add to My Images: it will add the image to My Images so it will continue to appear so you can use it. + Make Copy: (This only appears if the URL is a manifest): This will create a copy of the manifest in your workspace. This is handy if you want your annotations list URLs added to your manifest automatically. + View: will allow you to view the image in the annotation viewer without adding it to the My Images section. +![](https://annonatate.github.io/images/create-4.png) +9. After you click on any of the three buttons the pop up will disappear and the My Images section will collapse. Click on the + icon to expand the My Images section. Click on one of the shapes in the toolbar. +![](https://annonatate.github.io/images/create-5.png) +10. Drag your mouse over the section of the image you want to annotate. Enter any text, georeferencing and/or tags you want to sent and click Save. +![](https://annonatate.github.io/images/create-6.png) diff --git a/dhsi/day-three/annotation-in-manifest.md b/dhsi/day-three/annotation-in-manifest.md new file mode 100644 index 00000000..1bb2e133 --- /dev/null +++ b/dhsi/day-three/annotation-in-manifest.md @@ -0,0 +1,79 @@ +# Adding annotations to a manifest +In order for **SOME** viewers to be able to view annotations you need to add them to your manifest. This is done manually. + +# How to link your manifest to annotations +Open up your manifest in VS Code. + +Then find the canvas your annotations point to then add the following: + +## For V2 Manifest +```json +"otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } +] +``` + +## For V3 Manifest +```json +"annotations": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0269-embedded-or-referenced-annotations/annotationpage.json", + "type": "AnnotationPage" + } +] +``` + +after the images array. Replace the URL after the `@id` with the URL of your annotation. A full V2 canvas example is below: + +```json +{ + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", + "@type": "sc:Canvas", + "label": "1r", + "height": 5584, + "width": 3744, + "images": [ + { + "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", + "@type": "oa:Annotation", + "motivation": "sc:painting", + "resource": { + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", + "@type": "dctypes:Image", + "format": "image/jpeg", + "service": { + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", + "profile": "http://iiif.io/api/image/2/level1.json" + }, + "height": 5584, + "width": 3744 + }, + "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" + } + ], + "otherContent": [ + { + "@id": "https://iiif-test.github.io/BLJan2022/annotations/ce1d6509b5ec52275691847dd08d36b5.json", + "@type": "sc:AnnotationList", + "label": "My fantastic annotations" + } + ] +}, + +``` + +Save the manifest. Watch out for JSON typing errors. Common JSON issues include: + + * Make sure that all the brackets match up + * Lines that are not the last line in a list or array must have a `,` at the end of the line. + +To make this easier you may want to use a JSON aware editor like VS Code which will tell you if you are missing brackets or commas. You can also copy and paste your JSON to: + +https://jsonlint.com/ + +which will tell you if the JSON is valid and if not where the error is. diff --git a/dhsi/day-three/annotation-other.md b/dhsi/day-three/annotation-other.md new file mode 100644 index 00000000..edc8a5cb --- /dev/null +++ b/dhsi/day-three/annotation-other.md @@ -0,0 +1,14 @@ +# Crowdsourcing transcriptions +1. [Cratylus](https://apps.bowdoin.edu/cratylus/) - a crowd-sourced art tagging toolset. +2. [FromThePage](https://fromthepage.com/landing) - a crowdsourcing platform for archives and libraries where volunteers transcribe, index, and describe historic documents. +3. [Madoc](https://madoc.digirati.com/) - a flexible crowdsourcing, research and teaching platform for digitised collections. +3. [Zooniverse](https://github.com/zooniverse/iiif-annotations) - A proof-of-concept, annotating a IIIF manifest with Zooniverse classification data. See also [Importing images into Zooniverse with a IIIF manifest: introducing an experimental feature](https://blogs.bl.uk/digital-scholarship/2022/04/importing-images-into-zooniverse-with-a-iiif-manifest-introducing-an-experimental-feature.html) and [Fun with IIIF](https://blog.zooniverse.org/2022/04/20/fun-with-iiif/) on the ability to use IIIF to import media into the Zooniverse project builder. + +# CMS integrations +1. [IIIF Toolkit](https://github.com/utlib/IiifItems) - IIIF Toolkit by University of Toronto Libraries is a plugin for Omeka Classic (2.3+) that integrates Mirador with a built-in annotator, a manifest generator, Simple Pages shortcodes and Exhibit Builder blocks for a rich presentation experience. + +# Maps +1. [AllMaps](https://allmaps.org/) - Georeference manifest images with annotations. + +# ALTO +1. [ALTO to annotation list](https://github.com/glenrobson/iiif_stuff/tree/master/alto2annotations) \ No newline at end of file diff --git a/dhsi/day-three/annotations-sas.md b/dhsi/day-three/annotations-sas.md new file mode 100644 index 00000000..07153b03 --- /dev/null +++ b/dhsi/day-three/annotations-sas.md @@ -0,0 +1,77 @@ +# Creating and downloading Annotations + +In this tutorial we are going to annotate an image from your own manifest using a recently released version of the SimpleAnnotationServer. Once we have finished annotating we are going to view the annotations in a viewer which isn't connected to the annotation server. + +The major difference with this new version of the SimpleAnnotationServer is that you are asked to login and you will have a collection of Manifests that you have annotated. The previous version only had a single user so everyone could see and edit all of the annotations. In this version only you can see your annotations until you publish them. The high level process is as follows: + + * Step 1: Load your manifest into the Annotation server + * Step 2: Create your annotations + * Step 3: Share your annotations + +There are two options for getting a Manifest to Annotate. + +### Option 1 use the Workbench + +This option uses the Manifest you uploaded to the workbench in the [Publishing your Manifest](../day-three/workbench/) guide. To use this manifest you need to copy the manifest URL by going to Workbench, Manifests tab and right clicking on the IIIF logo and select `Copy link`. This will copy the Manifest URL to your clipboard. + +![image](imgs/workbench_iiif_link.png) + +### Option 2 Use any public IIIF manifest + +If you didn't manage to get a manifest in the previous session you can use any IIIF Manifest. My personal favorite is: + +https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json + +## Step 1: Load your manifest into the Annotation server + +### Login to SAS + * Navigate to https://dev.gdmrdigital.com/ and click the Log in / Sign Up link. + * This will take you to the following screen where you can choose to either login using your Google or Github accounts + +![image](imgs/sas/login.png) + +Unlike the workbench SAS doesn't write to your Google drive or GitHub account. The GitHub/Google methods are purely used to provide authentication to SAS with all of the data being stored on the SAS server. + +### Load your manifest into SAS: +Once you have logged in you will be presented with the following collection screen: + +![image](imgs/sas/empty_collection.png) + + * Now click the Add IIIF manifest (URL) link and enter the URL to your manifest as below. + * If you are using the Workbench use the URL copied from the IIIF logo. + +![image](imgs/sas/add_manifest.png) + + * Then click Add. Depending on how many pages the manifest takes this might take a minute or two to index. + * Once your manifest is loaded you should see it appear in your default Collection: + +![image](imgs/sas/manifest.png) + +## Step 2: Create your annotations + + * Now we have the manifest loaded into your SAS account we can start annotating. + * Click the blue "Annotate in Mirador" button. + * This should open up your manifest in Mirador + * Navigate to a page you want to annotate then click the speech bubbles at the top right to start annotating. + +![image](imgs/sas/annotate.png) + +## Step 3: Share your annotations + +Once you have finished annotating return to the collections screen by clicking the `Home` link. We are now going to generate a copy of your Manifest with links to your annotations. The SimpleAnnotationServer provides this functionality by clicking on the Share button. + +![image](imgs/sas/share-annos.png) + +Once you click on the Share link the SimpleAnnotationServer will retrieve a copy of your manifest from the Workbench, add links to the annotation lists per canvas and add a link to the Search service. It will then story a copy of this new manifest in SAS for you to use. Once it has generated this new manifest you should see the screen below: + +![image](imgs/sas/share-annos-page.png) + +Click on the UV link or Mirador link to see your annotations in these viewers which aren't connected to an annotation server. The annotations that these viewers are reading come from the manifest. + +## Review + +Using these instructions you have a manifest which points to annotation lists and a search service that is hosted by the Simple Annotation Server (SAS). If you add more annotations using SAS they will instantly appear in the new manifest that SAS created. The newly created manifest can be shared with others and will be available as long as the SAS server is running. + +In the next section we will look at extracting the Annotations we created using SAS so they can be linked to from your original Workbench manifest. This will create a read only version of the annotations and they will be available through the workbench. + + diff --git a/dhsi/day-three/annotations-stores-install.md b/dhsi/day-three/annotations-stores-install.md new file mode 100644 index 00000000..c2048467 --- /dev/null +++ b/dhsi/day-three/annotations-stores-install.md @@ -0,0 +1,81 @@ +# Installing an Annotation Server (Advanced) + +We are now going to attempt to install an Annotation Server locally. This is useful if you want to try out your own annotations and keep them private. This exercise will need you to run some command line commands. + +A summary of the commands we will be using are: + +| Command | Description | +| --- | --- | +| `cd` | Change directory | +| `ls` | list directory | +| `pwd` | to show you where you are (Print Working Directory) | + +For this you will need: + +## Prerequisites + +### Java + +If you followed the Cantaloupe or Static Images exercise as part of the Image API session you may already have this. If not you will need Java 11 installed. + + - [Downloading Java 11](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) + +To verify you have the correct package installed, you can run the following command from a terminal or command prompt: + +```sh +$ java -version +# java version "1.11.0_102" +``` + +You should see version `1.11.x`. + +## Step 1: + * Download the `sas.zip` file from the latest SimpleAnnotationServer release: + +[https://github.com/glenrobson/SimpleAnnotationServer/releases](https://github.com/glenrobson/SimpleAnnotationServer/releases) + +![image](imgs/annos_sas_download.png) + +## Step 2: + * Extract the zip file into a `iiif-workshop` directory. + * __On windows__ make sure it is extracted by right click on the file and uncompressing. + * __Note__: this doesn't need to be in your Chrome Web server directory + +## Step 3: + * In your terminal window `cd` into the sas directory which should have been created in the last step. + +``` +MacBook-Pro:tmp gmr$ cd sas +MacBook-Pro:sas gmr$ ls +dependency simpleAnnotationStore.war +``` + +## Step 4: + * Run the SimpleAnnotationStore: + +```java -jar dependency/jetty-runner.jar --port 8888 simpleAnnotationStore.war``` + +## Step 5: + * Navigate to http://localhost:8888/index.html + * And you should see Mirador + * Navigate to an item and make an annotation. Does it save? If not ask for help + +## Step 6: + * Now add your manifest + * Go to http://localhost:8888/index.html + * Go to the list of manifests (click the big plus sign or if you are viewing a manifest click the four boxes at the top left and select 'newObject'). + * In the list of manifests paste the link to your manifest http://127.0.0.1:5500/manifest.json into the addNewObject text field and click `load`. + * You should now see: + +![image](imgs/annos_mirador_addItem.png) + +## Step 7: + * Click on your manifest in the list + * Add some annotations to this manifest. Do they save? + * You should now be able to use the SimpleAnnotationServer to save and search annotations. + +Extras: + + * [Loading a Newspaper example with OCR](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/PopulatingAnnotations.md) + * [Download annotations](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/DownloadAnnotations.md) + * Note as well as storing Static Images you can also host manifests and annotation lists using GitHub pages. For details on loading content to Github see the [Publishing your annotated Manifest](workbench.html). diff --git a/dhsi/day-three/annotations-stores.md b/dhsi/day-three/annotations-stores.md new file mode 100644 index 00000000..828ac325 --- /dev/null +++ b/dhsi/day-three/annotations-stores.md @@ -0,0 +1,14 @@ +# Annotation Stores + +Annotation stores are basically applications with a database you can send an API call to and it will save and store an annotation. + +So Mirador or Annotorious will send a POST request with the contents of the annotation to an annotation store and it will recieve the annotation and write it to some kind of storage. + +Like image servers there are a number to choose from: + +https://github.com/IIIF/awesome-iiif#annotations + +Popular ones include: + * annotot - Simple IIIF annotations mounted in a Ruby on Rails applications by Jack Reed + * Elucidate - Java and Postgres annotation server by Digirati + * SimpleAnnotationServer - Java annotation server backed by an Apache Jena triple store, Elastic Search, or Solr. - developed while working at the NLW \ No newline at end of file diff --git a/dhsi/day-three/annotations.md b/dhsi/day-three/annotations.md new file mode 100644 index 00000000..7a3aff89 --- /dev/null +++ b/dhsi/day-three/annotations.md @@ -0,0 +1,151 @@ +# What are annotations? + +Annotations have multiple use cases when used in conjunction with IIIF: + + * Transcribing documents + * Commenting or analysis of content + * Highlighting areas of the item like hand written annotations on a printed book + * Teaching or explaining content + * Captions for A/V materials + +Also as we have seen annotations are fundamental to how a IIIF Manifests work with images and video painted on to a canvas with annotations. + +Annotations in IIIF follow the [W3C annotation model](https://www.w3.org/TR/annotation-model/) and its precursor [Open Annotations](http://www.openannotation.org/). I will go through the differences briefly later but the model is conceptionally similar: + +![Web Annotation model](https://www.w3.org/TR/annotation-model/images/intro_model.png) + +The annotation is made up of two parts. The body which is the **resource** you want to annotate **on** to something and the target which is the thing you are annotating. Examples of bodies might be: + + * Text transcription of a line + * Video giving background to a painting + * IIIF Image painted on to a canvas + +A target might be: + * A whole canvas + * A part of a canvas (maybe a line in the transcription example above) + +## Example Annotation +A simple commenting annotation looks like the following: + +```json +{ + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +This is using Open annotations and the keys map as follows: + + * Body -> resource + * Target -> on + +Other things to take note of are: + + * motivation is `commenting` + * Annotations should have an `@id` + +In this example the body or resource is the text `Zeus seated on stool-throne`. The canvas id in this example is `http://localhost:8887/coin/canvas` and the `#xywh=3706,208,522,522` denotes we are looking at a rectangle starting `3706` pixels from the left, `208` pixels from the top and with dimensions `522` pixels wide and `522` pixels high. The image mentioned in this annotation is: + +![Coin image](https://ronallo.com/iiif-workshop-new/images/coin-side-by-side.png) + +## Open Annotations vs Web Annotations + One of the changes with IIIF version 3.0 is that we are moving to the W3C Web Annotations model. The concepts are the same but the JSON is slightly different. The transcription example now looks like: + +```json +{ + "id": "http://localhost:8887/coin/list/1", + "type": "Annotation", + "motivation": "commenting", + "body": { + "type": "TextualBody", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "target": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" +} +``` + +The changes are: + * `@id` becomes `id` + * `@type` becomes `type` and `oa:Annotation` becomes `Annotation` + * `resource` becomes `body` + * `on` becomes `target` + * The body type changes from `cnt:ContentAsText` to `TextualBody`. + * Moving of type (oa:Tag) to purpose for individual annotations + + ```json + + { + "@context": "http://www.w3.org/ns/anno.jsonld", + "id": "http://example.org/anno15", + "type": "Annotation", + "motivation": "bookmarking", + "body": [ + { + "type": "TextualBody", + "value": "readme", + "purpose": "tagging" + }, + { + "type": "TextualBody", + "value": "A good description of the topic that bears further investigation", + "purpose": "describing" + } + ], + "target": "http://example.com/page1" +} + + ``` + +Quite a few changes but it is defiantly clearer to understand. + +## What are annotations lists? + +See Specification Chapter: +- [V2 Annotation List](http://iiif.io/api/presentation/2.1/#annotation-list) +- [V3 Annotation Page](https://iiif.io/api/presentation/3.0/#55-annotation-page) + +Annotation lists/pages are ways to group annotations and are often at a Canvas or Page level. Examples might be a transcription of a page or the OCR of a single page in annotation format. We will come back to this in the exercises but for now there is an example below. Note annotation lists are usually resolvable which means if you take the `@id` and put it into a Web Browser you should get the annotation list back. + +Additionally, you should never have an Annotation Page/List that has annotations on multiple images. They should only refer to a single image. To tie multiple image annotations together you use the manifest (we will show how to do this later in the workshop) or using an [Annotation Collection](https://iiif.io/api/presentation/3.0/#58-annotation-collection). + +```json +{ + "@context": "http://iiif.io/api/presentation/2/context.json", + "@id": "http://localhost:8887/coin/canvas/AnnotationList", + "@type": "sc:AnnotationList", + "resources": [ + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "oa:Annotation", + "motivation": "commenting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" + }, + { + "@id": "http://localhost:8887/coin/list/1", + "@type": "commenting", + "motivation": "sc:painting", + "resource": { + "@type": "cnt:ContentAsText", + "format": "text/plain", + "chars": "Zeus seated on stool-throne" + }, + "on": "http://localhost:8887/coin/canvas#xywh=0,208,522,522" + } + ] +} +``` + + diff --git a/dhsi/day-three/annotorious-embed.html b/dhsi/day-three/annotorious-embed.html new file mode 100644 index 00000000..4c90e8b6 --- /dev/null +++ b/dhsi/day-three/annotorious-embed.html @@ -0,0 +1,31 @@ + + + + + + + + + + +
    +
    + + \ No newline at end of file diff --git a/dhsi/day-three/annotorious.md b/dhsi/day-three/annotorious.md new file mode 100644 index 00000000..c2ec8b66 --- /dev/null +++ b/dhsi/day-three/annotorious.md @@ -0,0 +1,45 @@ +# Annotorious +Annotorious is a JS library you can easily build into a browser. Slightly different from Mirador because it doesn't save annotations to the localStorage (however it can be set to up to do so if you want). The JS library assumes you are going to set up your own way of saving annotations. + +## Using Annotorious +This view is making use of three plugins (toolbar, georeference and extended shapes beyond polygon and rectangle). Configuration is VERY well documented for the [out of the box Annotorious](https://annotorious.github.io/api-docs/osd-plugin/) including configuration and custom events and the [plugins](https://annotorious.github.io/plugins/). + + + +``` + + + + + + + + + +
    +
    + + +``` +Annotorious page + + + +In this workshop we are going to take you through creating a Manifest using a Manifest Editor. This works well for a small number of manifests and to give you an idea of what a Manifest contains. If you are going to create thousands or millions of manifests then you would need to look at automating this process. In the 2023 community survey we asked what people are using to generate manifests and the results can be seen below: + +![Chart showing manifest tool usage](imgs/presi-usage.svg) + +As you can see there isn't one solution and most people build their own tools using some shared libraries like iiif-prezi3. + +Generally the data required to create a manifest generator are as follows: + + * Accessible IIIF Images + * Structural data on how the images relate to each other. For example the order of the pages in a manuscript + * Descriptive metadata for example: + * Title - Name of the item this is called a `label` in IIIF + * Description (optional) + * Rights or licensing (optional) + * Metadata useful for discovery (optional) - this will be explained later + +Generally the format of the incoming metadata means that often these manifest generation tools are custom to each institution although there are the following libraries that can assist in the process: + + * [biiif](https://github.com/edsilv/biiif/) Organise your files according to a simple naming convention to generate IIIF v3 manifests. + * [demetsiiify](https://github.com/jbaiter/demetsiiify) - Web service for creating IIIF manifests from METS/MODS documents. + +## Presentation API Libraries + * [IIIF Manifest Generator](https://github.com/yale-web-technologies/IIIF-Manifest-Generator) - PHP library for generating IIIF manifests. + * [iiif-apis](https://github.com/dbmdz/iiif-apis) - Java IIIF API libraries. + * [iiif-prezi3](https://github.com/iiif-prezi/iiif-prezi3) - Python library providing a reference implementation for IIIF v3. + * [iiif-prezi](https://github.com/IIIF/iiif-prezi) - Python library providing a reference implementation. + * [O'Sullivan](https://github.com/IIIF/osullivan) - Ruby API for creating IIIF manifests. + * [Swiiift](https://github.com/mejackreed/Swiiift) - IIIF presentation API library for Swift. + * [tabula-rasa](https://www.npmjs.com/package/tabula-rasa) - npm module for creating and manipulating IIIF manifests. + * [ViewDir](https://iiif-commons.github.io/) - Documentation on IIIF-related libraries and components. + +Once the Manifests are generated they can be stored on any Web Server and don't need a specific server like the Image API. + +## Important Considerations + +When publishing manifests there are a couple of considerations you need to take in account. + +### http/https issue + +With the Web more generally moving to https if you publish your manifests as http it means they will no longer work in many of the online viewers and tools. Previously this was encouraged but now with the number of https sites it is almost impossible to use a http manifest. + +### CORS issues + +Another requirement for IIIF is to enable CORS headers. CORS headers tell the browser that its OK to open this JSON on a website which doesn't match the location of your Manifest. For example it says projectMirador.org can open a manifest from the Library of Congress. Without CORS headers being set then you will only be able to open your manifest on your website. For more details see: + +https://enable-cors.org/ + +### JSON issues + +Finally if you are hand editing JSON documents it is very easy to miss required commas and brackets so the following tool is useful to validate your JSON: + + * [JSONLint](https://jsonlint.com/) + +If your Manifest is valid JSON but its not working in a viewer there is a IIIF Validator which will let you know if the JSON has fields that are not part of the IIIF specifications: + + * [IIIF Presentation Validator](https://iiif.io/api/presentation/validator/service/) diff --git a/dhsi/day-three/prezi-intro.md b/dhsi/day-three/prezi-intro.md new file mode 100644 index 00000000..0c21073b --- /dev/null +++ b/dhsi/day-three/prezi-intro.md @@ -0,0 +1,9 @@ +# Presentation API + +This part is about the IIIF Presentation API. This session will focus on [version 2.1](https://iiif.io/api/presentation/2.1/) of API and core concepts of IIIF Presentation for 2D images. The session for today is split into two videos. The first one gives a background to the IIIF Presentation API and the second one is a practical hands on session taking you through creating your first manifest. + +Prerequisite video: + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=98z9YNFiUqU) + diff --git a/dhsi/day-three/ranges/README.md b/dhsi/day-three/ranges/README.md new file mode 100644 index 00000000..d5fcc917 --- /dev/null +++ b/dhsi/day-three/ranges/README.md @@ -0,0 +1,45 @@ +# Add Structure to a Manifest + +It is possible to provide information about the structure of the content within the Manifest. For instance, you might want to group Canvases depicting pages of a book by chapter, or of a play by act and scene. The [Range](https://iiif.io/api/presentation/2.1/#range) is the Presentation API mechanism for describing this type of structure. In this exercise we will add Range-based navigation to your Manifest. + +## Gather Canvas Identifiers + +Find the `@id` of each Canvas you created in your Manifest. Your structural mapping will reference the Canvases by their `@id`s. + +## Create the Structures + +1. Copy the JSON below into your Manifest (`manifest.json`) +1. Replace `$YOUR_CANVAS_ID` with the `@id` of your first Canvas +1. Save the file + +``` +"structures": [ + { + "@id": "http://example.org/iiif/book1/range/top", + "@type": "sc:Range", + "label": "Table of Content", + "viewingHint": "top", + "ranges": [ + "http://example.org/iiif/book1/range/intro" + ] + }, + { + "@id": "http://example.org/iiif/book1/range/intro", + "@type": "sc:Range", + "label": "Introduction", + "canvases": [ + "$YOUR_CANVAS_ID" + ] + } +] +``` + +## Verify in the Universal Viewer + +Open the Manifest in the [Universal Viewer](http://universalviewer.io). Assuming you named your Manifest `manifest.json` , your Manifest URL will be http://127.0.0.1:5500/manifest2.json + +## Table of contents notes + +Note Table of Contents in IIIF version 2, as is discussed in this course has been simplified in version 3. You can see an example version 3 table of contents in a book [here](https://iiif.io/api/cookbook/recipe/0024-book-4-toc/) and in a AV resource [here](https://iiif.io/api/cookbook/recipe/0026-toc-opera/). + +The table of contents (TOC) shown above should work in the latest copy of the Universal Viewer and Mirador but the version 2 of the specification allows a number of different ways to structure a table of contents. For a more in-depth investigation on the ways you can work with structures, including a multi level hierarchical table of contents please see this [note](https://glenrobson.github.io/iiif_stuff/toc/). diff --git a/dhsi/day-three/recogito.md b/dhsi/day-three/recogito.md new file mode 100644 index 00000000..0f1c38c7 --- /dev/null +++ b/dhsi/day-three/recogito.md @@ -0,0 +1,9 @@ +# Recogito + +1. Go to [https://recogito.pelagios.org/](https://recogito.pelagios.org/) +2. Create an account and log in. + + +[https://recogito.pelagios.org/help/tutorial](https://recogito.pelagios.org/help/tutorial) + +3. Annotations aren't viewable but are downloadable. \ No newline at end of file diff --git a/dhsi/day-three/v3-changes/README.md b/dhsi/day-three/v3-changes/README.md new file mode 100644 index 00000000..e69de29b diff --git a/dhsi/day-two/README.md b/dhsi/day-two/README.md new file mode 100644 index 00000000..8081f3dc --- /dev/null +++ b/dhsi/day-two/README.md @@ -0,0 +1,13 @@ +# Day 2 - Image API +## Tuesday + +The second day of the workshop will focus on the IIIF Image API. Participants may find it helpful to have the video open at the same time as the workshop webpages as the video takes you through these pages. + +### Image API session - 1 hour +Glen Robson the IIIF Technical Coordinator will introduce you to the IIIF Image API starting with the background before going into showing examples of how it works. + +During the call participants will be given a guided hands on task to create their own IIIF images. At a minimum by the end of this topic participants should have their own images available through the Internet Archive. These images will then be used in the next stage with the Presentation API. + + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=1-8hT9YARiY) diff --git a/dhsi/day-two/annona.md b/dhsi/day-two/annona.md new file mode 100644 index 00000000..d4ef178e --- /dev/null +++ b/dhsi/day-two/annona.md @@ -0,0 +1,62 @@ +# Annona +Annona only works with images. It also works with IIIF collections and annotations. + +## Creating/Embedding an Annona page +1. Create a file called `annona.html` +2. Copy the code into file +``` + + + Annona viewer + + + + + + + + +``` + + + + +3. Open in the browser + +## Embedding with a URL +1. Copy the code below into your `annona.html` file + +``` + +``` + +1. Go to [https://ncsu-libraries.github.io/annona/tools/#/tag-builder?url=&viewtype=&manifesturl=&settings=%7B%7D](https://ncsu-libraries.github.io/annona/tools/#/tag-builder?url=&viewtype=&manifesturl=&settings=%7B%7D) +2. Enter your manifest url. https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json +3. Select storyboard +4. Click on the Copy URL button +5. Replace replacewithmanifesturl with that copied url +``` + +``` + + + + +## Configuring +1. Go to [https://ncsu-libraries.github.io/annona/tools/#/tag-builder?url=&viewtype=&manifesturl=&settings=%7B%7D](https://ncsu-libraries.github.io/annona/tools/#/tag-builder?url=&viewtype=&manifesturl=&settings=%7B%7D) +2. Enter your manifest url. https://iiif.bodleian.ox.ac.uk/iiif/manifest/748a9d50-5a3a-440e-ab9d-567dd68b6abb.json +3. Select storyboard +4. Update the view to reflect how you would like the page to load. +5. Click Copy Tag (reating/Embedding an Annona page) or Copy URL button (iframe option) and embed. + +``` + +``` + + + +## String Manifests +Annona allows you to enter your manifests or annotations in [base64 encoded data uri or as raw json.](https://ncsu-libraries.github.io/annona/nourls/) + +Additionally the tag builder will take your raw JSON entered into the form element with the value `Annotation JSON to be used instead of annotation URL; Will convert to data URI.` and will take your raw JSON and convert it into base64 encoded dataURI. + diff --git a/dhsi/day-two/auto-generate-manifest.md b/dhsi/day-two/auto-generate-manifest.md new file mode 100644 index 00000000..0d8afa9b --- /dev/null +++ b/dhsi/day-two/auto-generate-manifest.md @@ -0,0 +1,50 @@ +# Autogenerating manifests + +Do we think all of these institutions with manifests autogenerate them? No they are generated multiple different ways. Often they are tied the a metadata or DAMS system that retrieves the metadata and image info from the systems. + +## Minimal computing ways to autogenerate manifests +1. [wax](https://github.com/minicomp/wax) - a minimal computing project for producing digital exhibitions focused on longevity, low costs, and flexibility. Provides a way to create manifests via csv. +2. [biiif](https://github.com/IIIF-Commons/biiif) - Organise your files according to a simple naming convention to generate IIIF v3 manifests. +3. [biiif-cli](https://github.com/IIIF-Commons/biiif-cli) - biiif terminal tool +3. [iiif-producer](https://github.com/ubleipzig/iiif-producer) - A CLI tool that generates IIIF Presentation 2.1 Manifests from METS/MODS (produced by Kitodo). +4. [Leiden's Islandora IIIF Manifest Generator](https://github.com/LeidenUniversityLibrary/islandora_iiif_manifests) - A module to generate IIIF Manifest for Islandora. +5. [Presentation API libraries](https://github.com/IIIF/awesome-iiif?tab=readme-ov-file#presentation-api-libraries) - Libraries that will help create manifests in a script. +6. [Wax tasks](https://github.com/minicomp/wax_tasks) - Library for taking csv formated data and creating tiles + manifests + +## biiif-cli +1. Go to your dhsi-iiif-2024 folder. +2. In the images folder create an `info.yml` file. +3. Fill out some metadata to match the format below. +![Screenshot of https://github.com/IIIF-Commons/biiif?tab=readme-ov-file#metadata](imgs/biiif-manifest.png). + +### Local Machine +1. Install [Node](https://nodejs.org/en) +2. After installation is finished install biiif-cli `npm i biiif-cli -g` +3. Run the biiif command. +``` +biiif [folder] -u [url manifest/info] +biiif images -u 'https://[yourgithubusername].github.io/dhsi-iiif-2024' +``` +4. Add you files and send to your GitHub repository +5. `git add images` +6. `git commit -m "create manifest and tiles"` +7. `git push origin main` + +### Using GitHub action +4. Upload to your dhsi-iiif-2024 fork +5. `git add images/info.yml` +6. `git commit -m "create info.yml file"` +7. `git push origin main` +8. Look in the images folder. What do you see? + +You can create move complex forms with this tool. +![Screenshot of https://github.com/IIIF-Commons/biiif?tab=readme-ov-file#examples](imgs/biiif-filestructure.png). + + + + +## Reflections +1. Based on what we know what if anything is wrong with this method? +2. Is there anything we can do to fix it? +3. What method (does not need to include something on this page) would you want for generating manifests? +4. Why aren't there more auto generation tools. \ No newline at end of file diff --git a/dhsi/day-two/bodleian-editor/README.md b/dhsi/day-two/bodleian-editor/README.md new file mode 100644 index 00000000..6568e86c --- /dev/null +++ b/dhsi/day-two/bodleian-editor/README.md @@ -0,0 +1,71 @@ +# Create a IIIF Manifest using the Bodleian Manifest Editor + +## Gather images +First, assemble a list of IIIF `info.json` URLs for your content. + * Here is a sample image at [Klokan](http://free.iiifhosting.com/iiif/f9a02a80bf76333f50ffcf0f0c17aa58f9ebf6a1510c9801bde50f565ac0a936/info.json) + * Here is a sample image at the [Yale Center for British Art](https://images.collections.yale.edu/iiif/2/ycba:9e08d901-a26b-4acb-a768-28f90a062adf/info.json) + +## Use the Bodleian Manifest Editor to create a manifest + +Navigate to the editor. If *any* of your `info.json` URLs begin with HTTP, use the HTTP version. See the [Note on Mixed Content](#note-on-mixed-content) section below for more information. + +- HTTP version at [text and bytes](http://iiif-manifest-editor.textandbytes.com/) +- HTTPS version at [the Bodleian](https://digital.bodleian.ox.ac.uk/manifest-editor/) + +### Note on Mixed Content +The links above to Universal Viewer use the HTTP version of the site to avoid Mixed Content errors. Likewise, you will need to use version of the Bodleian Manifest Editor served over HTTP if any of your IIIF images are served via HTTP. See this article on [Mixed Content](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content) for an explanation of the issue. + +## Steps to create your Manifest + +### Step 1 +Click on the create New Manifest button. + +![New manifest option](imgs/bod_new_manifest.png) + +### Step 2 + +Click the Add Canvas button + +![Add Canvas button](imgs/bod_add_canvas.png) + +Select the Canvas Metadata on the right hand side of the screen. + +***Note***: the Empty canvas thumbnail on the left will keep on spinning until you add an image. If you use a level 0 image this thumbnail will keep on spinning as Manifest editors does not support level 0 images as thumbnails. The main image should work OK for a level 0 image. + +![Select canvas metadata](imgs/bod_select_canvas_metadata.png) + +Now click the Add Image to Canvas button. + +***Note:*** again the thumbnail will still be spinning and there is also another spinning circle above the button which will disappear when an image is selected. The main image also says it can't load `/img/empty-canvas-large.png` but ignore this too as it will disappear when an image has been loaded. + +![Add image to canvas](imgs/bod_add_image_to_canvas.png) + +In the following dialog select the 'From info.json URI' option and enter your info.json into the text box. Then click Submit URI. + +![Enter info.json](imgs/bod_add_info_json.png) + +Once the image is loaded you should see something similar to the screenshot below. Note it may take a few minutes for the image to load if you are using the Internet Archive. You should see the thumbnail at the bottom and above the Add Image to canvas button. + +Now edit the Canvas label by clicking into the highlighted box. + +![Image added](imgs/bod_added_image.png) + +Now repeat these steps to add a second canvas to your manifest. + +### Step 3 + +We are now going to edit the Manifest metadata to change the label. First click the Manifest Metadata panel to reveal the fields you can edit in the Manifest and then click the highlighted Label box to add a label. + +![Edit label](imgs/bod_edit_label.png) + +### Step 4 + +Now we are going to save and download the Manifest for the next stage. Click the Save Manifest button at the top right of the screen and then click the download button. + +***Note:*** it is best to keep the Manifest Editor open as although the Manifest Editor allows you to import a Manifest for editing it is not very successful at doing this and often it will refuse to load a manifest so it is safer to keep the tab open until you are sure that you have finished with it. + +![Download manifest](imgs/bod_download_manifest.png) + +### Step 5 + +You should now create a directory to store all of the manifests and other things we create during the course. We suggest you call it `iiif-workshop` and you move the downloaded Manifest to this directory and call it `manifest.json`. \ No newline at end of file diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_add_canvas.png b/dhsi/day-two/bodleian-editor/imgs/bod_add_canvas.png new file mode 100644 index 00000000..a941988e Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_add_canvas.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_add_image_to_canvas.png b/dhsi/day-two/bodleian-editor/imgs/bod_add_image_to_canvas.png new file mode 100644 index 00000000..bd6af111 Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_add_image_to_canvas.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_add_info_json.png b/dhsi/day-two/bodleian-editor/imgs/bod_add_info_json.png new file mode 100644 index 00000000..88dc1342 Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_add_info_json.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_added_image.png b/dhsi/day-two/bodleian-editor/imgs/bod_added_image.png new file mode 100644 index 00000000..b40adc6f Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_added_image.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_download_manifest.png b/dhsi/day-two/bodleian-editor/imgs/bod_download_manifest.png new file mode 100644 index 00000000..96a28076 Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_download_manifest.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_edit_label.png b/dhsi/day-two/bodleian-editor/imgs/bod_edit_label.png new file mode 100644 index 00000000..4b3367c3 Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_edit_label.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_new_manifest.png b/dhsi/day-two/bodleian-editor/imgs/bod_new_manifest.png new file mode 100644 index 00000000..bf7f3349 Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_new_manifest.png differ diff --git a/dhsi/day-two/bodleian-editor/imgs/bod_select_canvas_metadata.png b/dhsi/day-two/bodleian-editor/imgs/bod_select_canvas_metadata.png new file mode 100644 index 00000000..5963787c Binary files /dev/null and b/dhsi/day-two/bodleian-editor/imgs/bod_select_canvas_metadata.png differ diff --git a/dhsi/day-two/canvas_finder.js b/dhsi/day-two/canvas_finder.js new file mode 100644 index 00000000..f50e950a --- /dev/null +++ b/dhsi/day-two/canvas_finder.js @@ -0,0 +1,371 @@ + +function loadManifest(event) { + event.preventDefault(); + let manifest_uri = document.getElementById('manifest_uri').value; + + let target_div = document.getElementById('manifest_content'); + + if (manifestOK(manifest_uri, target_div)) { + fetch(manifest_uri) + .then(response => { + if (!response.ok) { + throw new Error(response.statusText); + } + return response.json(); + }) + .then(data => { + if ("@type" in data) { + if (data["@type"] != 'sc:Manifest') { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a @type of sc:Manifest but has a type of: ' + data["@type"]); + } else { + loadv2(data, target_div); + } + } else if ("type" in data) { + if (data["type"] != 'Manifest') { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a type of Manifest but has a type of: ' + data["type"]); + } else { + loadv3(data, target_div); + } + } else { + showMessage(target_div, 'Manifest Format Error', 'The JSON for this Manifest doesnt look like a Manifest. It should have either a @type or type value of Manifest'); + } + }) + .catch(error => { + showMessage(target_div, 'Manifest retrieval error', 'I was unable to get the Manifest you supplied due to: ' + error); + }); + + } +} + +function clearManifest(event) { + event.preventDefault(); + let target_div = document.getElementById('manifest_content'); + target_div.innerHTML = ''; +} + +function isObject(variable) { + return typeof variable === 'object' && !Array.isArray(variable) && variable !== null +} + +function filter(event) { + var source = event.target || event.srcElement; + console.log(source.value); + let canvases = document.getElementsByClassName("canvasDiv"); + for (const canvas of canvases) { + if (source.value == null || source.value.length === 0 || canvas.dataset.label.toLowerCase().includes(source.value.toLowerCase())) { + canvas.style.display = "flex"; + } else { + canvas.style.display = "none"; + } + } +} + +function fallbackCopyTextToClipboard(text) { + var textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + var successful = document.execCommand('copy'); + var msg = successful ? 'successful' : 'unsuccessful'; + console.log('Fallback: Copying text command was ' + msg); + } catch (err) { + console.error('Fallback: Oops, unable to copy', err); + } + + document.body.removeChild(textArea); +} +function copyTextToClipboard(text, success) { + if (!navigator.clipboard) { + fallbackCopyTextToClipboard(text); + return; + } + navigator.clipboard.writeText(text).then(success, function(err) { + console.error('Async: Could not copy text: ', err); + }); +} + +function copyURL(event) { + event.preventDefault(); + var source = event.target || event.srcElement; + copyTextToClipboard(source.dataset.link, function () { + source.innerHTML = ' Copied!'; + setTimeout(function () { + source.innerHTML = ' Copy Image URL'; + }, 1000) + }); +} + +function loadv2(manifest, target_div) { + if ('sequences' in manifest) { + let sequences = manifest.sequences; + if (isObject(sequences)) { + sequences = [ sequences ]; + } + let foundCanvas = false; + let filterDiv = document.createElement('div'); + filterDiv.style="display: flex; justify-content: flex-end; padding-top: 5px; padding-bottom: 5px;" + filterDiv.innerHTML = ''; + + let textBox = document.createElement('input'); + textBox.style = "margin-left:10px;"; + textBox.id = 'filter'; + textBox.type="text"; + textBox.placeholder="Filter canvas label"; + textBox.addEventListener('input',filter); + filterDiv.appendChild(textBox); + target_div.appendChild(filterDiv); + + for (const sequence of sequences) { + if ('canvases' in sequence) { + foundCanvas = true; + for (const canvas of sequence.canvases) { + let canvasDiv = document.createElement('div'); + canvasDiv.style = "border: 1px black solid; padding: 5px;margin-top: 5px;"; + canvasDiv.className = 'canvasDiv'; + canvasDiv.dataset.label = canvas.label; + + let thumbnail = document.createElement('img'); + thumbnail.src = getCanvasThumbnail(canvas, 150,150); + thumbnail.className = 'thumbnail'; + let thumbDiv = document.createElement('div'); + thumbDiv.style="display: inline-block;"; + thumbDiv.appendChild(thumbnail); + + let contentDiv = document.createElement('div'); + contentDiv.style="width: 70%; display: inline-block;position: relative; padding-left: 20px;" + let label = document.createElement('p'); + label.innerHTML = 'Page Label: ' + canvas.label; + + var iiifURL = canvas.images[0].resource.service["@id"]; + + let link = document.createElement('a'); + link.href = iiifURL; + link.innerHTML = iiifURL; + + let pLink = document.createElement('p'); + pLink.innerHTML = 'IIIF Image URL:
    '; + pLink.appendChild(link); + + let button = document.createElement('button'); + button.style = "cursor: pointer; background-color: #0069d9; color: #fff; border-color: #0062cc; font-weight: 400; text-align: center; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; -webkit-appearance: button;text-transform: none; overflow: visible; margin: 0; font-family: inherit;box-sizing: border-box; "; + button.innerHTML = ' Copy Image URL'; + button.addEventListener('click', copyURL); + button.dataset.link = link; + + contentDiv.appendChild(label); + contentDiv.appendChild(pLink); + contentDiv.appendChild(button); + canvasDiv.appendChild(thumbDiv); + canvasDiv.appendChild(contentDiv); + + target_div.appendChild(canvasDiv); + } + } else { + if (!foundCanvas) { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no canvases so there are no images to show.'); + } + } + } + } else { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no sequence so there are no images to show.'); + } +} + +function loadv3(manifest, target_div) { + if ('items' in manifest) { + let canvases = manifest.items; + let foundCanvas = false; + let filterDiv = document.createElement('div'); + filterDiv.style="display: flex; justify-content: flex-end; padding-top: 5px; padding-bottom: 5px;" + filterDiv.innerHTML = ''; + + let textBox = document.createElement('input'); + textBox.style = "margin-left:10px;"; + textBox.id = 'filter'; + textBox.type="text"; + textBox.placeholder="Filter canvas label"; + textBox.addEventListener('input',filter); + filterDiv.appendChild(textBox); + target_div.appendChild(filterDiv); + + let canvasLabel = ""; + foundCanvas = true; + for (const canvas of canvases) { + let canvasDiv = document.createElement('div'); + canvasDiv.style = "border: 1px black solid; padding: 5px;margin-top: 5px;"; + canvasDiv.className = 'canvasDiv'; + canvasLabel = getLangString(canvas.label); + canvasDiv.dataset.label = canvasLabel; + + let thumbnail = document.createElement('img'); + thumbnail.src = getCanvasThumbnail(canvas, 150,150); + thumbnail.className = 'thumbnail'; + let thumbDiv = document.createElement('div'); + thumbDiv.style="display: inline-block;"; + thumbDiv.appendChild(thumbnail); + + let contentDiv = document.createElement('div'); + contentDiv.style="width: 70%; display: inline-block;position: relative; padding-left: 20px;" + let label = document.createElement('p'); + label.innerHTML = 'Page Label: ' + canvasLabel; + + var iiifURL = canvas.items[0].items[0].body.service[0]["@id"]; + + let link = document.createElement('a'); + link.href = iiifURL; + link.innerHTML = iiifURL; + + let pLink = document.createElement('p'); + pLink.innerHTML = 'IIIF Image URL:
    '; + pLink.appendChild(link); + + let button = document.createElement('button'); + button.style = "cursor: pointer; background-color: #0069d9; color: #fff; border-color: #0062cc; font-weight: 400; text-align: center; vertical-align: middle; user-select: none; border: 1px solid transparent; padding: .375rem .75rem; line-height: 1.5; border-radius: .25rem; transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; -webkit-appearance: button;text-transform: none; overflow: visible; margin: 0; font-family: inherit;box-sizing: border-box; "; + button.innerHTML = ' Copy Image URL'; + button.addEventListener('click', copyURL); + button.dataset.link = link; + + contentDiv.appendChild(label); + contentDiv.appendChild(pLink); + contentDiv.appendChild(button); + canvasDiv.appendChild(thumbDiv); + canvasDiv.appendChild(contentDiv); + + target_div.appendChild(canvasDiv); + } + } else { + showMessage(target_div, 'Manifest Error', 'The manifest you supplied contains no sequence so there are no images to show.'); + } + +} + +function manifestOK(manifest_uri, target_div) { + if (manifest_uri.startsWith('http://')) { + showMessage(target_div, 'http/https issue', 'The manifest link you supplied is a http link. To use this tool you need to supply a link that starts with https. This is a common problem you come across with IIIF. If the webpage you are using is https then the Manifest link must also start with https. The training site and most modern websites uses https which is a secure way of accessing the web.'); + + return false; + } + return true; +} + +/* + * Get thumbnail URL from canvas with canvas_id + * canvas_id can contain a fragement + * image returned will be the same size as desired_width and height or bigger + * zero means discount axis. + */ +function getCanvasThumbnail(canvas, desired_width, desired_height) { + // First try canvas thumbnail + if ('thumbnail' in canvas && (isObject(canvas.thumbnail) || Array.isArray(canvas.thumbnail))) { + let thumbnail = canvas.thumbnail; + if (Array.isArray(thumbnail)) { + thumbnail = thumbnail[0]; + } + if ('width' in thumbnail && 'height' in thumbnail) { + if (thumbnail.width > desired_width && thumbnail.height > desired_height) { + if ("@id" in thumbnail) { + return thumbnail["@id"]; + } else { + return thumbnail.id; + } + } + } + } + + // Next try first image + if ('images' in canvas && Array.isArray(canvas.images) + && 'resource' in canvas.images[0] && typeof canvas.images[0].resource === 'object') { + if ('service' in canvas.images[0].resource && typeof canvas.images[0].resource.service === 'object' + && '@id' in canvas.images[0].resource.service && typeof canvas.images[0].resource.service["@id"] === 'string') { + + let imageService = canvas.images[0].resource.service; + let isLevel0 = false; + if ('profile' in imageService) { + if (Array.isArray(imageService.profile)) { + imageService.profile.forEach(function(value) { + if (typeof key === 'string' && key === "http://iiif.io/api/image/2/level0.json") { + isLevel0 = true; + } + }); + } else if (typeof imageService.profile === 'string' && imageService.profile === "http://iiif.io/api/image/2/level0.json") { + isLevel0 = true; + } + } + + let imageId = imageService["@id"]; + + var region = "full"; + + let size = ""; + if (!isLevel0) { + let widthStr = ""; + let heightStr = ""; + if (desired_width != 0) { + widthStr = "" + desired_width; + } + if (desired_height != 0) { + heightStr = "" + desired_height; + } + size = widthStr + "," + heightStr; + } else { + // Find size that is bigger than the one we want. + if ('sizes' in imageService && Array.isArray(imageService.sizes)) { + smallest_width = imageService.width; + smallest_height = imageService.height; + + imageService.sizes.foreach(function(sizeOption) { + if ('width' in sizeOption && 'height' in sizeOption) { + if (sizeOption.width < smallest_width && sizeOption.height < smallest_height) { + smallest_width = sizeOption.width; + smallest_height = sizeOption.height; + } + } + }); + + size = "" + smallest_width + "," + smallest_height; + } else { + // At this point we should go and get the info.json + // No sizes so just have to use full + size = "full"; + } + } + + return imageId + '/' + region + '/' + size + '/0/default.jpg'; + } else { + // No image service so just return image. Really this should have a thumbnail + return canvas.images[0].resource["@id"]; + } + } +} + +function getLangString(label) { + if ('en' in label) { + return label.en; + } else if ('none' in label) { + return label.none; + } else { + return label; + } +} + +function showMessage(div, title, message) { + div.innerHTML = ''; + + let h3 = document.createElement('h3'); + h3.innerHTML = title; + div.appendChild(h3); + + let p = document.createElement('p'); + p.innerHTML = message + div.appendChild(p); + +} diff --git a/dhsi/day-two/clover.md b/dhsi/day-two/clover.md new file mode 100644 index 00000000..c0038804 --- /dev/null +++ b/dhsi/day-two/clover.md @@ -0,0 +1,26 @@ +# Clover + +## Embedding clover +Clover isn't particularly configurable using Vanilla JS. If you would like more customizable options you will have to use it with React. [https://samvera-labs.github.io/clover-iiif](https://samvera-labs.github.io/clover-iiif) has all the options avaliable for Clover with React. + +``` + + + Clover IIIF - Viewer - Web Component + + + + + + + + +``` + + + + \ No newline at end of file diff --git a/dhsi/day-two/configuring-viewers.md b/dhsi/day-two/configuring-viewers.md new file mode 100644 index 00000000..56c00ee0 --- /dev/null +++ b/dhsi/day-two/configuring-viewers.md @@ -0,0 +1,150 @@ +## Configuring Viewers + +Now that we've spent the day learning about the IIIF Presentation API and creating our own manifests, we thought it would fun to do a deeper dive on the use of IIIF Image Viewers. + +Specifically, we want to show you how we can not only add our manifests to existing viewers, but we can actually highly customize these viewers in a way tailored to our specific needs. + +For example: + +* If you're running museum exhibit, you might want a viewer that provides a guided curation of specific images and limits how the user can interact with the collection +* If you're building a research environment, you might want to use the viewer different to allow users to control every aspect of their environment. +* If you're trying to illustrate a research outcome, you might want to bring the users to a very specific place within a set of images. + +There are many options here. We're going to focus on two highly customizable viewers: Mirador and Universal Viewer. First, we're going to look at how to embed a viewer in your own project (to do this, we'll continue to use or "Custom Image Viewers" projects). Then we'll walk through several of the configuration option. Then we'll turn this into a work period, where you can start embedding a viewer into your project and adjust the configuration settings as needed. We'll come around and help you customize your project any way you want. + +## Viewers not covered +Tify, IIIF Curation Viewer and Diva.js all have videos and demo pages to play with at [https://iiif.io/guides/using_iiif_resources/#tools-for-viewing-manifests](https://iiif.io/guides/using_iiif_resources/#tools-for-viewing-manifests). + +## Mirador + +### Embedding Mirador + +Embedding mirador within a webpage (either as the entire web page or a component within the web page) is pretty easy. + +As you can see the example below, you just need to reference the Mirador code library and then create a `
    ` where Mirador can be instantiated. + + + +```html + + + + + +
    + + +``` + +If you're looking to embed mirador as a smaller piece within another website there multiple ways do this. + +One of the simplest ways to do this is to embed the mirador page as an ` + +You can see the [generated files on github](https://github.com/glenrobson/glenrobson.github.io/tree/master/iiif/welsh_book/page002/). There is also a blog on how to use IIIF level 0 images. [IIIF from Scratch](https://glenrobson.github.io/iiif/2018/01/12/iiif-from-scrtach.html). + +You can optionally follow this guide to create your own level 0 images. [Workshop Guide](https://training.iiif.io/iiif-online-workshop/day-two/image-servers/level0-workbench.html) + +Once you have created your level 0 images you can make them available with the following example services: + +Free: + * [GitHub Pages](https://pages.github.com/) - ([Workbench Guide](https://training.iiif.io/iiif-online-workshop/day-two/image-servers/level0-workbench.html)) + +Paid for: + * [Amazon s3 web hosting](https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html) + +For an idea of costs, the Amazon S3 costs are available [here](https://aws.amazon.com/s3/pricing/). For a ball park figure 2,000 images would cost around a $1 a month. + +Once the images are generated there is little maintenance required and the solution scales to millions of users. diff --git a/dhsi/day-two/image-servers/bl_images.md b/dhsi/day-two/image-servers/bl_images.md new file mode 100644 index 00000000..d696a1e3 --- /dev/null +++ b/dhsi/day-two/image-servers/bl_images.md @@ -0,0 +1,73 @@ + + +# Finding British Library IIIF Images + +For this exercise we are going to find a couple of British Library IIIF Images that we can use tomorrow in the IIIF Presentation API session. This exercise will show you how to find a single IIIF image within a digital object and then how you can manipulate this image so you can use it to tweet or embed in a blog or publication. + +## Stage 1: Find a BL digital item + +Using the [BL collection guide](https://www.bl.uk/collection-guides/iiif) find a digital object and open it up in the Viewer. Once you have found your item it should look as follows: + +![BL digital item in the UV](imgs/uv_bl.png) + +Now we have found the item we want to get the 'IIIF Manifest' for this item. We will go into more details about IIIF Manifests on Wednesday but a Manifest is a JSON document that contains links to all of the images and metadata that goes into a digital item. We are going to find the link to the IIIF Manifest and past this into a tool below which will allow us to find the IIIF Image URL to the image we want. + +To find the manifest click the 'share' link at the bottom of the viewer and then right click on the IIIF icon and select 'Copy link' or 'Copy Link Address' in Chrome: + +***Note:*** some collections like the Google printed books collection do not currently allow sharing so the share button will not be present. + +![BL digital item with manifest link open](imgs/uv_bl_share.png) + + +You can see the copy link from Firefox in this image: + +![Copy link for IIIF Manifest](imgs/uv_bl_copy_link.png) + +The copied link should look something like: + +``` +https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json?manifest=https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json +``` + +You can see the link to the manifest is created twice in this link so it can be cleaned up by removing everything after the `?` to leave: + +``` +https://api.bl.uk/metadata/iiif/ark:/81055/vdc_100104060212.0x000001/manifest.json +``` + +Some IIIF viewers and tools will be able to cope with the manifest being repeated but if possible its best to remove everything after the `?`. + +## Stage 2: Find IIIF Image URL + +Now we have got our Manifest we need to find the URL (or link) for image we want. We could do this by looking through the JSON and we can have a look at doing this after the Presentation API session on Wednesday but for now I have created the following tool that will take a link to a manifest and allow you to choose the image you want. Paste your manifest into the box below and click Load. + + +
    +
    +
    + + + + +
    +
    +
    +
    +
    + +## Stage 3: Experiment + +Now you have a IIIF Image URL you can plug it into the following IIIF Tools: + +Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2/info.json) + +![Open seadragon](imgs/bl_osd-qa.png) + +Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.qdl.qa/iiif/images/81055/vdc_100000000884.0x0001e3/IOR_L_PS_20_C260_0049.jp2) + +![TCD Image cropper](imgs/bl_image_cropping-qa.png) diff --git a/dhsi/day-two/image-servers/cantaloupe/cantaloupe-admin.png b/dhsi/day-two/image-servers/cantaloupe/cantaloupe-admin.png new file mode 100644 index 00000000..9cebf9cb Binary files /dev/null and b/dhsi/day-two/image-servers/cantaloupe/cantaloupe-admin.png differ diff --git a/iiif-5-day-workshop/images/cantaloupe-image.png b/dhsi/day-two/image-servers/cantaloupe/cantaloupe-image.png similarity index 100% rename from iiif-5-day-workshop/images/cantaloupe-image.png rename to dhsi/day-two/image-servers/cantaloupe/cantaloupe-image.png diff --git a/iiif-5-day-workshop/images/eddie_iiif.png b/dhsi/day-two/image-servers/cantaloupe/eddie_iiif.png similarity index 100% rename from iiif-5-day-workshop/images/eddie_iiif.png rename to dhsi/day-two/image-servers/cantaloupe/eddie_iiif.png diff --git a/dhsi/day-two/image-servers/cantaloupe/file_source.png b/dhsi/day-two/image-servers/cantaloupe/file_source.png new file mode 100644 index 00000000..d2eedc32 Binary files /dev/null and b/dhsi/day-two/image-servers/cantaloupe/file_source.png differ diff --git a/iiif-5-day-workshop/images/info_json.png b/dhsi/day-two/image-servers/cantaloupe/info_json.png similarity index 100% rename from iiif-5-day-workshop/images/info_json.png rename to dhsi/day-two/image-servers/cantaloupe/info_json.png diff --git a/dhsi/day-two/image-servers/chrome/chrome_apps.png b/dhsi/day-two/image-servers/chrome/chrome_apps.png new file mode 100644 index 00000000..aa71f170 Binary files /dev/null and b/dhsi/day-two/image-servers/chrome/chrome_apps.png differ diff --git a/dhsi/day-two/image-servers/chrome/chrome_web_server.png b/dhsi/day-two/image-servers/chrome/chrome_web_server.png new file mode 100644 index 00000000..b57b60c2 Binary files /dev/null and b/dhsi/day-two/image-servers/chrome/chrome_web_server.png differ diff --git a/iiif-5-day-workshop/images/level0-github-account-type.png b/dhsi/day-two/image-servers/github/level0-github-account-type.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-account-type.png rename to dhsi/day-two/image-servers/github/level0-github-account-type.png diff --git a/iiif-5-day-workshop/images/level0-github-clone-2.png b/dhsi/day-two/image-servers/github/level0-github-clone-2.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-clone-2.png rename to dhsi/day-two/image-servers/github/level0-github-clone-2.png diff --git a/iiif-5-day-workshop/images/level0-github-clone.png b/dhsi/day-two/image-servers/github/level0-github-clone.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-clone.png rename to dhsi/day-two/image-servers/github/level0-github-clone.png diff --git a/iiif-5-day-workshop/images/level0-github-commit.png b/dhsi/day-two/image-servers/github/level0-github-commit.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-commit.png rename to dhsi/day-two/image-servers/github/level0-github-commit.png diff --git a/iiif-5-day-workshop/images/level0-github-create-level0.png b/dhsi/day-two/image-servers/github/level0-github-create-level0.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-create-level0.png rename to dhsi/day-two/image-servers/github/level0-github-create-level0.png diff --git a/iiif-5-day-workshop/images/level0-github-customise.png b/dhsi/day-two/image-servers/github/level0-github-customise.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-customise.png rename to dhsi/day-two/image-servers/github/level0-github-customise.png diff --git a/iiif-5-day-workshop/images/level0-github-desktop-login.png b/dhsi/day-two/image-servers/github/level0-github-desktop-login.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-desktop-login.png rename to dhsi/day-two/image-servers/github/level0-github-desktop-login.png diff --git a/iiif-5-day-workshop/images/level0-github-desktop-nameemail.png b/dhsi/day-two/image-servers/github/level0-github-desktop-nameemail.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-desktop-nameemail.png rename to dhsi/day-two/image-servers/github/level0-github-desktop-nameemail.png diff --git a/iiif-5-day-workshop/images/level0-github-desktop-open.png b/dhsi/day-two/image-servers/github/level0-github-desktop-open.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-desktop-open.png rename to dhsi/day-two/image-servers/github/level0-github-desktop-open.png diff --git a/iiif-5-day-workshop/images/level0-github-email-verify.png b/dhsi/day-two/image-servers/github/level0-github-email-verify.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-email-verify.png rename to dhsi/day-two/image-servers/github/level0-github-email-verify.png diff --git a/iiif-5-day-workshop/images/level0-github-iiif-clone.png b/dhsi/day-two/image-servers/github/level0-github-iiif-clone.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-iiif-clone.png rename to dhsi/day-two/image-servers/github/level0-github-iiif-clone.png diff --git a/iiif-5-day-workshop/images/level0-github-iiif-clonelocation.png b/dhsi/day-two/image-servers/github/level0-github-iiif-clonelocation.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-iiif-clonelocation.png rename to dhsi/day-two/image-servers/github/level0-github-iiif-clonelocation.png diff --git a/iiif-5-day-workshop/images/level0-github-invitation-accept.png b/dhsi/day-two/image-servers/github/level0-github-invitation-accept.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-invitation-accept.png rename to dhsi/day-two/image-servers/github/level0-github-invitation-accept.png diff --git a/iiif-5-day-workshop/images/level0-github-invitation.png b/dhsi/day-two/image-servers/github/level0-github-invitation.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-invitation.png rename to dhsi/day-two/image-servers/github/level0-github-invitation.png diff --git a/iiif-5-day-workshop/images/level0-github-pushpull.png b/dhsi/day-two/image-servers/github/level0-github-pushpull.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-pushpull.png rename to dhsi/day-two/image-servers/github/level0-github-pushpull.png diff --git a/iiif-5-day-workshop/images/level0-github-signup.png b/dhsi/day-two/image-servers/github/level0-github-signup.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-signup.png rename to dhsi/day-two/image-servers/github/level0-github-signup.png diff --git a/iiif-5-day-workshop/images/level0-github-success.png b/dhsi/day-two/image-servers/github/level0-github-success.png similarity index 100% rename from iiif-5-day-workshop/images/level0-github-success.png rename to dhsi/day-two/image-servers/github/level0-github-success.png diff --git a/iiif-5-day-workshop/images/level0-verifygithub.png b/dhsi/day-two/image-servers/github/level0-verifygithub.png similarity index 100% rename from iiif-5-day-workshop/images/level0-verifygithub.png rename to dhsi/day-two/image-servers/github/level0-verifygithub.png diff --git a/dhsi/day-two/image-servers/ia/get_id.png b/dhsi/day-two/image-servers/ia/get_id.png new file mode 100644 index 00000000..0e17547d Binary files /dev/null and b/dhsi/day-two/image-servers/ia/get_id.png differ diff --git a/dhsi/day-two/image-servers/ia/iiif-image-url.png b/dhsi/day-two/image-servers/ia/iiif-image-url.png new file mode 100644 index 00000000..2125f403 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/iiif-image-url.png differ diff --git a/dhsi/day-two/image-servers/ia/login-create-user.png b/dhsi/day-two/image-servers/ia/login-create-user.png new file mode 100644 index 00000000..c3a4cb89 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/login-create-user.png differ diff --git a/dhsi/day-two/image-servers/ia/login-email.png b/dhsi/day-two/image-servers/ia/login-email.png new file mode 100644 index 00000000..fc2019d8 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/login-email.png differ diff --git a/dhsi/day-two/image-servers/ia/login-success.png b/dhsi/day-two/image-servers/ia/login-success.png new file mode 100644 index 00000000..ff98cf42 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/login-success.png differ diff --git a/dhsi/day-two/image-servers/ia/login-verification.png b/dhsi/day-two/image-servers/ia/login-verification.png new file mode 100644 index 00000000..d064f634 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/login-verification.png differ diff --git a/dhsi/day-two/image-servers/ia/login1.png b/dhsi/day-two/image-servers/ia/login1.png new file mode 100644 index 00000000..b6aa61e8 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/login1.png differ diff --git a/dhsi/day-two/image-servers/ia/openseadragon.png b/dhsi/day-two/image-servers/ia/openseadragon.png new file mode 100644 index 00000000..36ea729c Binary files /dev/null and b/dhsi/day-two/image-servers/ia/openseadragon.png differ diff --git a/dhsi/day-two/image-servers/ia/ucd-image-cropper.png b/dhsi/day-two/image-servers/ia/ucd-image-cropper.png new file mode 100644 index 00000000..1f2d9b27 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/ucd-image-cropper.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-drag-and-drop.png b/dhsi/day-two/image-servers/ia/upload-drag-and-drop.png new file mode 100644 index 00000000..94622c05 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-drag-and-drop.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-files.png b/dhsi/day-two/image-servers/ia/upload-files.png new file mode 100644 index 00000000..e1f04de8 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-files.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-itempage.png b/dhsi/day-two/image-servers/ia/upload-itempage.png new file mode 100644 index 00000000..f4cf6acc Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-itempage.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-metadata.png b/dhsi/day-two/image-servers/ia/upload-metadata.png new file mode 100644 index 00000000..8c88f2b5 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-metadata.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-timer.png b/dhsi/day-two/image-servers/ia/upload-timer.png new file mode 100644 index 00000000..da9acef4 Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-timer.png differ diff --git a/dhsi/day-two/image-servers/ia/upload-welcome.png b/dhsi/day-two/image-servers/ia/upload-welcome.png new file mode 100644 index 00000000..25cb276c Binary files /dev/null and b/dhsi/day-two/image-servers/ia/upload-welcome.png differ diff --git a/dhsi/day-two/image-servers/iiif-hosting-ia.md b/dhsi/day-two/image-servers/iiif-hosting-ia.md new file mode 100644 index 00000000..4862a839 --- /dev/null +++ b/dhsi/day-two/image-servers/iiif-hosting-ia.md @@ -0,0 +1,145 @@ +# Using the Internet Archive + +The Internet Archive allows you to upload images and then provides a IIIF Image API service. Helpfully they also have a function to delete your images after 30 days if you are using this as a test. The overall process is as follows: + +__Note__: some people have had some issues getting their images to show when uploading to the Internet Archive. To avoid these issues: + + * Ensure you only upload 1 image ( if you want multiple images you will need to create multiple items) + * Ensure the collection is 'Community Image' collection. The `Community Texts` collection seems to break the image viewing currently + * Some of the IIIF images appear very small even if you uploaded a large image. See the note below on adding the filename to the URL to get the original image available as IIIF. + +1. Register for a user account at [archive.org](https://archive.org) +2. Upload your image + * __Ensure you only upload a single image__ + * __Ensure you select the 'Community Image' collection__ +3. On the details page get the identifier for the image. For example if the details page link is: + + https://archive.org/details/img-8664_202009 + + the identifier would be `img-8664_202009` +4. Use the Internet Archive image service with this identifier: + + https://iiif.archivelab.org/iiif/img-8664_202009/info.json + +5. You should then be able to use this image: + + Create an image link: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg) + + Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json) + + Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009) + + **Note:** the UCD selector tool requires the Image link without the `info.json` at the end of the URL. + +### Small images workaround + +Some images are appearing small, to get round this issue you will need to add the filename to the URL. In the following example: + +https://archive.org/details/img-8664_202009 + +you would normally create the following URL: + +https://iiif.archivelab.org/iiif/img-8664_202009/info.json + +but to make the image larger you need to add the filename (`$IMG_8664.jpg`) so it looks like: + +https://iiif.archivelab.org/iiif/img-8664_202009$IMG_8664.jpg/info.json + +To find the image navigate to the details page: + +https://archive.org/details/img-8664_202009 + +and click on the main image. This will show the image full screen and if you look in the address bar you will be able to see the filename. The reason this happens is due to a bug in the Internet Archive IIIF implementation and I have submitted a [Bug](https://github.com/ArchiveLabs/iiif.archivelab.org/issues/44) and a fix on their github. + +## Step by step guide + +A step by step guide with screen shots for the above steps is below: + +1. Register for a user account at [archive.org](https://archive.org) + + Click signup or login if you already have an account: + + Sign up / Login + + Then create your user: + + Create user + + They will then ask you to verify your email address: + + Send verification email + + You will then see an email like the following: + + Verification Email + + Click on the link on the email and you will get the following screen: + + success + +2. Upload your image + + Select upload on the Archive Welcome screen: + + welcome screen + + You will then see the following screen. Select the green Upload Files button: + + upload choices + + Then click on the 'choose files to upload' button and select the image to upload: + + choose files + + Add metadata. The Title, URL, Description tags are mandatory. I left it in the Community Image collection. Usefully you can also say if its a test item which can be deleted after 30 days. + + __Update__: ensure collection is `Community Image Collection` otherwise the image won't work as IIIF. + + Metadata + + Then click 'Upload and Create Your Item'. This took at least 5 minutes and after the bar has completed you have to wait longer presumably so it can setup the derivative images. + + Upload wait + + If all has gone well you should see the item page: + + item page + +3. On the details page get the identifier for the image. For example if the details page link is: + + https://archive.org/details/img-8664_202009 + + the identifier would be `img-8664_202009` + + Get image identifier + +4. Use the Internet Archive image service with this identifier: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/full/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/full/0/default.jpg) + + IIIF Image URL + +5. You should then be able to use this image: + + Create an image link: + + [https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg](https://iiif.archivelab.org/iiif/img-8664_202009/full/512,/0/default.jpg) + + Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif.archivelab.org/iiif/img-8664_202009/info.json) + + OpenSeaDragon example + + Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.archivelab.org/iiif/img-8664_202009) + + UCD Image Cropper + diff --git a/dhsi/day-two/image-servers/images_in_manifest.md b/dhsi/day-two/image-servers/images_in_manifest.md new file mode 100644 index 00000000..c6f8b08d --- /dev/null +++ b/dhsi/day-two/image-servers/images_in_manifest.md @@ -0,0 +1,42 @@ + + +# Finding images in Manifests + +Some IIIF tools work with IIIF Image URLs rather than manifests. This is less common than it used to be but for tools like Omeka and basic region image generators getting the URL for the image you want is useful. + +Once you have a Manifest URL you can use the tool below to extract the Image URL. We could do this by looking through the Manifest JSON but this requires a deeper dive in to the Presentation API. + +## Stage 1: Find IIIF Image URL + +If you paste your Manifest URL in the box below and click Load it should show all of the images which are part of your Manifest. You can use the filter to search for a page label and then click `Copy Image URL` to copy the link to the IIIF Image. + + +
    +
    +
    + + + + +
    +
    +
    +
    +
    + +## Stage 2: Experiment + +Now you have a IIIF Image URL you can plug it into the following IIIF Tools: + +Check it works with a zooming viewer like OpenSeaDragon: + + [https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011/info.json](https://iiif.gdmrdigital.com/openseadragon/index.html?image=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011/info.json) + +![Open seadragon](imgs/bl_osd.png) + +Pull out regions using the UCD selector tool: + + [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://api.bl.uk/image/iiif/ark:/81055/vdc_100104087143.0x000011) + +![TCD Image cropper](imgs/bl_image_cropping.png) diff --git a/dhsi/day-two/image-servers/imgs/bl_image_cropping-qa.png b/dhsi/day-two/image-servers/imgs/bl_image_cropping-qa.png new file mode 100644 index 00000000..9d4eff56 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/bl_image_cropping-qa.png differ diff --git a/dhsi/day-two/image-servers/imgs/bl_image_cropping.png b/dhsi/day-two/image-servers/imgs/bl_image_cropping.png new file mode 100644 index 00000000..c3e266ca Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/bl_image_cropping.png differ diff --git a/dhsi/day-two/image-servers/imgs/bl_osd-qa.png b/dhsi/day-two/image-servers/imgs/bl_osd-qa.png new file mode 100644 index 00000000..55eeb9ef Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/bl_osd-qa.png differ diff --git a/dhsi/day-two/image-servers/imgs/bl_osd.png b/dhsi/day-two/image-servers/imgs/bl_osd.png new file mode 100644 index 00000000..f5b2c7b4 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/bl_osd.png differ diff --git a/dhsi/day-two/image-servers/imgs/img_server_use.png b/dhsi/day-two/image-servers/imgs/img_server_use.png new file mode 100644 index 00000000..5ccda292 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/img_server_use.png differ diff --git a/dhsi/day-two/image-servers/imgs/img_server_use_2023.svg b/dhsi/day-two/image-servers/imgs/img_server_use_2023.svg new file mode 100644 index 00000000..12878747 --- /dev/null +++ b/dhsi/day-two/image-servers/imgs/img_server_use_2023.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dhsi/day-two/image-servers/imgs/uv_bl.png b/dhsi/day-two/image-servers/imgs/uv_bl.png new file mode 100644 index 00000000..a9689d32 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/uv_bl.png differ diff --git a/dhsi/day-two/image-servers/imgs/uv_bl_copy_link.png b/dhsi/day-two/image-servers/imgs/uv_bl_copy_link.png new file mode 100644 index 00000000..af2aab43 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/uv_bl_copy_link.png differ diff --git a/dhsi/day-two/image-servers/imgs/uv_bl_share.png b/dhsi/day-two/image-servers/imgs/uv_bl_share.png new file mode 100644 index 00000000..711bd703 Binary files /dev/null and b/dhsi/day-two/image-servers/imgs/uv_bl_share.png differ diff --git a/dhsi/day-two/image-servers/level0-github-hosting.md b/dhsi/day-two/image-servers/level0-github-hosting.md new file mode 100644 index 00000000..a8089ed3 --- /dev/null +++ b/dhsi/day-two/image-servers/level0-github-hosting.md @@ -0,0 +1,101 @@ +# Level 0 hosting with GitHub Pages + +Once you have created your level 0 image we need to make it available to the public. + +One way to get access to free web hosting is to use GitHub pages. GitHub is a software and web application created to manage projects with multiple developers and manages the source code to ensure people's changes don't get overwritten. One feature of Github is GitHub Pages which allows you to create a Web page about your project. We are going to use this functionality to host a IIIF Image. This is a relatively convoluted process but once setup it will give you a free way to publish IIIF Images. + +## Step 1: Sign up to GitHub +Created an account by going to [Github](https://github.com/) and clicking signup. + + * Create Username, password, email + +![image](github/level0-github-signup.png) + + * Complete verify puzzle + +![image](github/level0-verifygithub.png) + + * Choose free option + +![image](github/level0-github-account-type.png) + + * Customise experience (skip this step) + +![image](github/level0-github-customise.png) + + * Verify email address + +![image](github/level0-github-email-verify.png) + + * Success!! + +![image](github/level0-github-success.png) + +## Step 2: Get Read/write access to repo + * Add username to: https://github.com/dhsi-iiif/dhsi-iiif.github.io/issues/1 + * You will get an invitation through the email you registered with in GitHub + +![image](github/level0-github-invitation.png) + + * Accept invitation + +![image](github/level0-github-invitation-accept.png) + +## Step 3: Check out repo +The GitHub desktop application manages the upload of your data to GitHub. It is possible to do this through the Git command line but for this part of the workshop it is suggested to use the Desktop version. + + * Download and install Github desktop https://desktop.github.com/ + * Login + * Click login through website + +![image](github/level0-github-desktop-login.png) + + * Configure name and email + +![image](github/level0-github-desktop-nameemail.png) + + * Download the GitHub dhsi 2019 repository to your local machine in the dhsi2019/dhsi-iiif.github.io. GitHub calls download a repository 'cloning'. So select the dhsi-iiif.github.io repository and click clone. + +![image](github/level0-github-clone.png) + + * Selecting where to download the repo to. + +![image](github/level0-github-clone-2.png) + + * Click open in Finder or similar for Windows + +![image](github/level0-github-desktop-open.png) + + * Make a directory inside the 2019 directory for your examples: + + ``` + dhsi-iiif.github.io/2019/ +``` +## Step 4: Upload level 0 image +Now move the directory you created in the previous step (Step 3 from [static-tiles](static-tiles.md)) into the following: + + ``` + dhsi-iiif.github.io/2019/ + ``` + +Now go to Github Desktop + +![image](github/level0-github-commit.png) + + * Add a commit message on the left hand side. Fill in the Summary and a short description. + * Click commit to master + * You now need to send your local changes to GitHub. To do this click the Push Origin button. Note if others in the class are also on this step they may have made changes to GitHub and the GitHub desktop application will not let you send your changes until you have the latest copy from GitHub. If this is the case it may ask you to Pull from origin. If this is the case Pull the latest changes before pushing your changes. + +![image](github/level0-github-pushpull.png) + + * In your local copy of `2019///info.json`, open it up in an editor and edit the `@id` with: `https://dhsi-iiif.github.io/2019//` + * As you did earlier add a Commit summary and description then commit and Push changes + * Wait 2mins + * Go to: `https://dhsi-iiif.github.io/2019///info.json` + * and you should see your info.json! + +## Step 5: View image: + * Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json + * Openseadragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json + * Note not all software works with level 0 images. + diff --git a/dhsi/day-two/image-servers/level0-workbench.md b/dhsi/day-two/image-servers/level0-workbench.md new file mode 100644 index 00000000..5179b4d2 --- /dev/null +++ b/dhsi/day-two/image-servers/level0-workbench.md @@ -0,0 +1,148 @@ +# Training Workbench + +This option takes advantage of a Website called [GitHub](https://github.com/) which provides among other things a small amount of free Web Space called [GitHub Pages](https://pages.github.com/). This process is similar to the one mentioned in the [Static tiles](static-tiles.html) task but instead of having to install and run the software locally this is provided as a cloud service for the training. + +As mentioned in the previous chapter, the IIIF Image API defines the following structure: + +`http://host:port/identifier/region/size/rotation/quality.format` + +and it is possible to generate images that fit this URL structure and conform to the IIIF Image API using a tile generator. This will generate the minimum required amount of files to implement the IIIF Image API. It does have some limitations, the main one being it is not possible to request images of a size that haven't been pre-generated. This type of pre-generated IIIF Image is known as a `Level 0` implementation. + +The workbench will generate these tiles and upload them to your own GitHub account and has a number of advantages over the Internet Archive option: + + * Images are owned by you on GitHub + * Support for IIIF version 3 + * Faster access to images + +The main disadvantage of this route is the one mentioned above in that it uses static images so you can not request custom sizes or regions, only the ones that have been pre-generated. This option will still allow you to use these images in Manifests and will perform the same for most annotation use cases. + +This solutions is suitable for those that want to use IIIF images but don't have the organisational support or funding to run an image server. The main stages for this process are as follows: + +1. Register for a GitHub account +2. Login to the Workbench +3. Create your project +4. Upload your images +5. View your image + +These steps are detailed below with screen shots. + +## Stage 1: Register for a GitHub account + +Create an account by going to [Github](https://github.com/) and clicking signup. + + * Create Username, password, email + +![image](github/level0-github-signup.png) + + * Complete verify puzzle + +![image](github/level0-verifygithub.png) + + * Choose free option + +![image](github/level0-github-account-type.png) + + * Customise experience (skip this step) + +![image](github/level0-github-customise.png) + + * Verify email address + +![image](github/level0-github-email-verify.png) + + * Success!! + +![image](github/level0-github-success.png) + +## Stage 2: Login to Workbench +In this stage we will go to the workbench and login using the GitHub account we just created. By using the GitHub account to login it allows the Workbench to create a Repository where it can store your uploaded images. If you ever lose access to the Workbench software the files will be safe and accessible on your GitHub account. + +Navigate to the Workbench: [https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/) + +You should see the following screen: + +![image](workbench/login.png) + +Click the Login with GitHub button. + +This will either ask you to login as shown in the following screen shot or if you are already logged in take you straight to the permissions page. + +![image](workbench/github_login.png) + +Next you will see the following permissions page. This is asking you if you are happy for the Workbench to write to your GitHub account. Click Authorize. + +![image](workbench/authorize.png) + +You should now be taken to the projects page: + +![image](workbench/no_project.png) + +You have now successfully logged into the Workbench using your GitHub username and password. Once you have been through the Authorisation step once your browser and GitHub will remember that you have given permission and it should log you straight in. The next stage is to create your project. + +## Stage 3. Create your project + +A project is a place to store the images and manifests you are working on. You can have multiple projects for every GitHub account but note each project is limited to 1GB in size. In the GitHub terminology a project in this case is equivalent to a GitHub Repository. + +To start click the Create Project button: + +![image](workbench/no_project.png) + +and enter a name for your project. Note the name can only contain letters, numbers or the following symbols `-` and `_` so don't add any spaces. + +![image](workbench/create_project.png) + +Click create. This will take a few seconds but will setup an empty project on GitHub and then forward you onto the images part of the Workbench. + +![image](workbench/no_images.png) + +You are now ready to upload your images. + +## Stage 4. Upload your images + +This stage will allow you to upload an image from your computer to the workbench which will convert it into IIIF tiles and store them on GitHub. To start click the upload button and you will see the following screen: + +![image](workbench/upload_image1.png) + +Click the Browse button and select an image on your computer. Once you have an image a `Name` box will appear which allows you to choose the name for your IIIF image. This will appear in the ID of the IIIF image so can't contain spaces and other characters. + +Next select the IIIF Image version either version 2 or 3. For this guides please select version 2 so they can be used in a version 2 manifest. + +![image](workbench/upload_image2.png) + +Then click upload. This will upload the image to Github, create the Image tiles and upload the files to GitHub. This can take a couple of minutes and you will see the following screen while the image is processing: + +![image](workbench/upload_image3.png) + +Once it has finished processing you should see a thumbnail of your image. + +![image](workbench/upload_image4.png) + +You have now uploaded an image and the next stage is to see if it has worked. + +## Stage 5. Viewing your images + +Underneath each of your images you should see two links. One to the `info.json` which we will use later and one to the full image. If you click the Full image link: + +![image](workbench/full_image.png) + +This will open the largest size of your image and the URL will look something like: + +https://iiif-test.github.io/test2/images/IMG_8711/full/full/0/default.jpg + +And note the end of the URL is a IIIF url asking for the `full` region, `full` size, `0` degrees rotation, `default` quality and a `jpg` file format. + +To view this in a zoomable viewer we need to copy the URL to the `info.json`. If you right click on the `info.json` link and select copy link. This should copy a URL similar to the following to your clipboard: + +https://iiif-test.github.io/test2/images/IMG_8711/info.json + +This is called a link to your Info.json and you should be able to open your images in the following two zoomable viewers by appending the link to your info.json to the end: + + * [Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url=](http://mejackreed.github.io/Leaflet-IIIF/examples/?url=https://iiif-test.github.io/test2/images/IMG_8711/info.json) + * [Openseadragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image=](http://iiif.gdmrdigital.com/openseadragon/index.html?image=https://iiif-test.github.io/test2/images/IMG_8711/info.json) + * Note not all software works with level 0 images. + +If you want to see the tiles that have been generated click the GitHub symbol on the top left: + +![image](workbench/github_link.png) + +this will open GitHub and show the files that it has generated. diff --git a/dhsi/day-two/image-servers/setting-up-cantaloupe.md b/dhsi/day-two/image-servers/setting-up-cantaloupe.md new file mode 100644 index 00000000..2dc3bc66 --- /dev/null +++ b/dhsi/day-two/image-servers/setting-up-cantaloupe.md @@ -0,0 +1,160 @@ +# Setting up Cantaloupe IIIF Image Server + +Cantaloupe is one of the open source image servers which is free to use but takes some command line setup to install. Once installed you will see how an Image Server works but note if you install it on your laptop then only you will be able to access it. The example viewers at the end of this session will work for you on your machine but if you sent it to someone else they wouldn't be able to access your machine. + +Following this tutorial will be most useful for those that are interested in setting up a IIIF Service in their own institution. It will be less relevant to those that are mostly interested in using IIIF Images in research. For those people it is better to use the hosted option or the static images option. + +## Prerequisites + +### Java + +In this workshop we will install and run a IIIF Image server and for this you will need Java 11 installed. + + - [Downloading Java 17](https://www.oracle.com/java/technologies/downloads/#java17) + +To verify you have the correct package installed, you can run the following command from a terminal or command prompt: + +```sh +$ java -version +# java version "1.17.0.10" +``` + +You should see version `1.17x`. + +### Using a text editor + +We will be using a text editor to edit some of the configuration files for Cantaloupe. If you don't know which text editor to choose, a good, free, open source option is [VS Code](https://code.visualstudio.com/). + +## Navigating on the command line / terminal + +In this workshop, we will be running commands from a terminal / command prompt. There is no need to be an expert, but before you start you may find the following introductions useful: + + - [Paths, Folders, Directories (pwd)](https://learnpythonthehardway.org/book/appendix-a-cli/ex2.html) + - [If You Get Lost](https://learnpythonthehardway.org/book/appendix-a-cli/ex3.html) + - [Make A Directory (mkdir)](https://learnpythonthehardway.org/book/appendix-a-cli/ex4.html) + - [Change Directory (cd)](https://learnpythonthehardway.org/book/appendix-a-cli/ex5.html) + +## Download Cantaloupe + +This is a short guide to installing Cantaloupe, for more information on each step, checkout the [Cantaloupe getting started guide](https://cantaloupe-project.github.io/manual/5.0/getting-started.html). + +Start by downloading [Cantaloupe v5.0.6](https://github.com/cantaloupe-project/cantaloupe/releases/download/v5.0.6/cantaloupe-5.0.6.zip) + +Open and extract the zip file to your directory of choosing. We suggest `~/iiif-workshop`. + +Open up a terminal or command prompt and change directory to that extracted directory: + +```sh +cd ~/iiif-workshop/Cantaloupe-5.0.6 +``` + +## Configure Cantaloupe + +Now lets create a copy of the configuration file: + +```sh +cp cantaloupe.properties.sample cantaloupe.properties +``` + +Now open up the new `cantaloupe.properties` in your text edit so we can enable the admin panel. + +Scroll to line 118, and change `false` to `true`. Also add a password. + +```diff +# Enables the Control Panel, at /admin. +- admin.enabled = false ++ admin.enabled = true +- admin.secret = ++ admin.secret = yolo +``` + +Save the file. + +Now lets try and start the server. Run this command from your Cantaloupe directory + +```sh +java -Dcantaloupe.config=./cantaloupe.properties -Xmx2g -jar cantaloupe-5.0.6.jar +``` + +Now navigate to [http://127.0.0.1:8182/iiif/2](http://127.0.0.1:8182/iiif/2) in your browser. + +You should see this: + +![server image](cantaloupe/cantaloupe-image.png) + +Congrats you successfully installed Cantaloupe! + +### Troubleshooting + +If you don't see the screen above there are a few common problems that people have come across: + + * Lack of memory. You may see something like the following when you run the Cantaloupe java command: + +``` +Error occurred during initialization of VM +Could not reserve enough space for 2097152000000KB object heap +``` + +to fix this change the `-Xmx` parameter to something smaller e.g: + +``` +java -Dcantaloupe.config=./cantaloupe.properties -Xmx1g -jar cantaloupe-5.0.6.jar + +``` + * Spaces in Windows. If you are using Windows ensure that there are no spaces in the directories above the Cantaloupe directory. + +## Admin panel + +Also make sure you can get into the admin panel by navigating to [http://127.0.0.1:8182/admin](http://127.0.0.1:8182/admin). + +Use the username `admin` and the password you set previously. + +![admin panel](cantaloupe/cantaloupe-admin.png) + +# Configuring Cantaloupe to use your images. + +Congrats now you have your image server up and running! We need to feed it some images to keep it happy! + +## Download some images + +Go ahead and download a `*.jpg` image from the Internet into your Cantaloupe directory `Cantaloupe-5.0.6`. Here is one [eddie.jpg](https://github.com/sul-cidr/histonets/raw/master/spec/fixtures/images/eddie.jpg) that you can use. + +## Configure Cantaloupe to use the correct path + +Now we need to configure Cantaloupe to use that image directory. + +Navigate to the admin page [http://127.0.0.1:8182/admin](http://127.0.0.1:8182/admin). + +Click on "Source", then click "FilesystemSource" tab at the bottom of the page. + +Next fill in Path Prefix to be `./` + +![file resolver](cantaloupe/file_source.png) + +and click `Save`. + +## Check it out in the browser + +Now you should be able to navigate to an image's info.json response successfully. + +Checkout [http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json](http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json) + +And if everything goes right, you should see an `info.json` response. + +![info json](cantaloupe/info_json.png) + +Let's finally check it using the Leaflet-IIIF image api viewer. + +Try this url: [http://mejackreed.github.io/Leaflet-IIIF/examples/?url=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json](http://mejackreed.github.io/Leaflet-IIIF/examples/?url=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json) + +Notice how we added our local IIIF server's info.json response url as a parameter. This is used by IIIF Image API clients to understand how they can request images/tiles. + +![eddie in iiif](cantaloupe/eddie_iiif.png) + +Cross our fingers, but you should see a picture of Eddie in a zoomable viewer. + +You can also try this image with: + * OpenSeaDragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image= + * http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json + * UCD Image clipper: https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID= + * e.g. https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=http://127.0.0.1:8182/iiif/2/eddie.jpg diff --git a/dhsi/day-two/image-servers/static-tiles.md b/dhsi/day-two/image-servers/static-tiles.md new file mode 100644 index 00000000..3814cd6c --- /dev/null +++ b/dhsi/day-two/image-servers/static-tiles.md @@ -0,0 +1,113 @@ +# Generating static tiles + +As mentioned in the previous chapter, the IIIF Image API defines the following structure: + +`http://host:port/identifier/region/size/rotation/quality.format` + +It is possible to generate images that fit this URL structure and conform to the IIIF Image API using a tile generator. This will generate the minimum required amount of files to implement the IIIF Image API. It does have some limitations, the main one being it is not possible to request images of a size that haven't been pre-generated. This type of pre-generated IIIF Image is known as a `Level 0` implementation. + +To generate these IIIF images we are going to use a IIIF tilling program which is available on Github. This workshop is useful for those that are looking for a cheap method of making a small amount of images available although there are instances where this method can be scaled to support hundreds of thousands of images. See this article for a method of making level 0 images scalable: [The Code4Lib Journal – Scaling IIIF Image Tiling in the Cloud](https://journal.code4lib.org/articles/14933). + +# Prerequisites + +### Java + +In this workshop we will install and run a IIIF Image server and for this you will need Java 11 installed. + + - [Downloading Java 11](https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html) + +To verify you have the correct package installed, you can run the following command from a terminal or command prompt: + +```sh +$ java -version +# java version "1.11.0_102" +``` + +You should see version `1.11.x`. For more information on the install options see: + + - [Java install options](https://java.com/en/download/help/download_options.xml) + +## Step 1: Download the IIIF Tiler + + * Navigate to the release page: https://github.com/glenrobson/iiif-tiler/releases/tag/0.9.1 + * Click the `assets` drop down + * Download [iiif-tiler.jar](https://github.com/glenrobson/iiif-tiler/releases/download/0.9.1/iiif-tiler.jar) + * Store this jar file in your `~/iiif-workshop` directory + +## Step 2: Prepare your image files + * Move the image files you want to work with into your `~/iiif-workshop` directory + +## Step 3: Generate the IIIF Image tiles + +Now either: + * Double click on the `iiif-tiler.jar` file in Finder or Windows. + +or + + * from the command line run: + +```sh +cd ~/iiif-workshop +java -jar iiif-tiler.jar +``` + * This will generate the IIIF image tiles in a `iiif` directory for every image it finds in the same directory as the iiif-tiler.jar. + +### Common issues: + +If you see the following error: + +``` +Exception in thread "main" java.lang.IllegalArgumentException: Failed to find combination under 100 files +``` + +Try running the following command: + +``` +java -jar iiif-tiler.jar image_filename 5 +``` + +Where `image_filename` is the filename of your image e.g. `image.jpg` + +## Step 4: Point the Chrome webserver to your `iiif-workshop` directory +We will cover the Chrome WebServer in more detail in the Presentation API session but this plugin makes your laptop work like an image server. + + * Open Chrome + * Click the Apps button on the top left + +![image](chrome/chrome_apps.png) + + * Click on the `Web Server` (if this is not listed ensure you have installed the [prerequisites](../prerequisites.md)). + * You should see the following: + +![image](chrome/chrome_web_server.png) + + * Click `choose folder` and select your `iiif-workshop` folder + * Where it says `Enter port` change it to 8887 + * Click `Show Advanced Settings` + * Ensure `Set CORS headers` has a tick next to it. + +## Step 5: Serve your IIIF Image through a http server + + * Open a browser and navigate to [http://127.0.0.1:8887/](http://127.0.0.1:8887/) + * You should see a `iiif` directory and if you click that you should see your image file. + * Click this directory then click on the `info.json`. + * If your image was called `image.jpg` the URL should be. + +`http://127.0.0.1:8887/iiif/image/info.json` + + * If you see the info.json you are now ready to view your image in a IIIF Image viewer. + +## Step 6: Show your image in a IIIF Viewer + +You can now load your image to a IIIF image viewer. The main image viewer is OpenseaDragon. This takes the URL of the info.json. So if your info.json URL is: + +```http://127.0.0.1:8887/iiif/image/info.json``` + +Open it with OpenseaDragon: + +[http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8887/iiif/image/info.json](http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8887/iiif/image/info.json) + +## Step 7: Hosting your image publicly + +You now have a working level 0 implementation. As you are using the Chrome plugin the images are only accessible on your machine. You can't share your images with other people. To be able to share your images you need to copy them to a public Web Server. As mentioned there are paid for services but you can also access free Web Hosting through GitHub which we will do next. + diff --git a/dhsi/day-two/image-servers/workbench/authorize.png b/dhsi/day-two/image-servers/workbench/authorize.png new file mode 100644 index 00000000..a06bd27f Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/authorize.png differ diff --git a/dhsi/day-two/image-servers/workbench/create_project.png b/dhsi/day-two/image-servers/workbench/create_project.png new file mode 100644 index 00000000..1c90e6a3 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/create_project.png differ diff --git a/dhsi/day-two/image-servers/workbench/full_image.png b/dhsi/day-two/image-servers/workbench/full_image.png new file mode 100644 index 00000000..bf3f6092 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/full_image.png differ diff --git a/dhsi/day-two/image-servers/workbench/github_link.png b/dhsi/day-two/image-servers/workbench/github_link.png new file mode 100644 index 00000000..a85ec908 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/github_link.png differ diff --git a/dhsi/day-two/image-servers/workbench/github_login.png b/dhsi/day-two/image-servers/workbench/github_login.png new file mode 100644 index 00000000..339d0292 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/github_login.png differ diff --git a/dhsi/day-two/image-servers/workbench/login.png b/dhsi/day-two/image-servers/workbench/login.png new file mode 100644 index 00000000..51bba150 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/login.png differ diff --git a/dhsi/day-two/image-servers/workbench/no_images.png b/dhsi/day-two/image-servers/workbench/no_images.png new file mode 100644 index 00000000..2f528b72 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/no_images.png differ diff --git a/dhsi/day-two/image-servers/workbench/no_project.png b/dhsi/day-two/image-servers/workbench/no_project.png new file mode 100644 index 00000000..e19e99dc Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/no_project.png differ diff --git a/dhsi/day-two/image-servers/workbench/upload_image1.png b/dhsi/day-two/image-servers/workbench/upload_image1.png new file mode 100644 index 00000000..ae3da039 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/upload_image1.png differ diff --git a/dhsi/day-two/image-servers/workbench/upload_image2.png b/dhsi/day-two/image-servers/workbench/upload_image2.png new file mode 100644 index 00000000..5d5bcbd7 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/upload_image2.png differ diff --git a/dhsi/day-two/image-servers/workbench/upload_image3.png b/dhsi/day-two/image-servers/workbench/upload_image3.png new file mode 100644 index 00000000..58438b3a Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/upload_image3.png differ diff --git a/dhsi/day-two/image-servers/workbench/upload_image4.png b/dhsi/day-two/image-servers/workbench/upload_image4.png new file mode 100644 index 00000000..7d5cd0f9 Binary files /dev/null and b/dhsi/day-two/image-servers/workbench/upload_image4.png differ diff --git a/dhsi/day-two/imgs/1-github-publishing.png b/dhsi/day-two/imgs/1-github-publishing.png new file mode 100644 index 00000000..830fff4e Binary files /dev/null and b/dhsi/day-two/imgs/1-github-publishing.png differ diff --git a/dhsi/day-two/imgs/2-github-publishing.png b/dhsi/day-two/imgs/2-github-publishing.png new file mode 100644 index 00000000..af09fd7c Binary files /dev/null and b/dhsi/day-two/imgs/2-github-publishing.png differ diff --git a/dhsi/day-two/imgs/3-github-publishing.png b/dhsi/day-two/imgs/3-github-publishing.png new file mode 100644 index 00000000..72c9a4db Binary files /dev/null and b/dhsi/day-two/imgs/3-github-publishing.png differ diff --git a/dhsi/day-two/imgs/4-github-publishing.png b/dhsi/day-two/imgs/4-github-publishing.png new file mode 100644 index 00000000..c39214ea Binary files /dev/null and b/dhsi/day-two/imgs/4-github-publishing.png differ diff --git a/dhsi/day-two/imgs/5-github-publishing.png b/dhsi/day-two/imgs/5-github-publishing.png new file mode 100644 index 00000000..67052405 Binary files /dev/null and b/dhsi/day-two/imgs/5-github-publishing.png differ diff --git a/dhsi/day-two/imgs/6-github-publishing.png b/dhsi/day-two/imgs/6-github-publishing.png new file mode 100644 index 00000000..16118c99 Binary files /dev/null and b/dhsi/day-two/imgs/6-github-publishing.png differ diff --git a/dhsi/day-two/imgs/7-github-publishing.png b/dhsi/day-two/imgs/7-github-publishing.png new file mode 100644 index 00000000..c3ac8bd9 Binary files /dev/null and b/dhsi/day-two/imgs/7-github-publishing.png differ diff --git a/dhsi/day-two/imgs/8-github-publishing.png b/dhsi/day-two/imgs/8-github-publishing.png new file mode 100644 index 00000000..134b1692 Binary files /dev/null and b/dhsi/day-two/imgs/8-github-publishing.png differ diff --git a/dhsi/day-two/imgs/JPEG2000_format.png b/dhsi/day-two/imgs/JPEG2000_format.png new file mode 100644 index 00000000..21bcdfa4 Binary files /dev/null and b/dhsi/day-two/imgs/JPEG2000_format.png differ diff --git a/dhsi/day-two/imgs/biiif-filestructure.png b/dhsi/day-two/imgs/biiif-filestructure.png new file mode 100644 index 00000000..f16eeae9 Binary files /dev/null and b/dhsi/day-two/imgs/biiif-filestructure.png differ diff --git a/dhsi/day-two/imgs/biiif-manifest.png b/dhsi/day-two/imgs/biiif-manifest.png new file mode 100644 index 00000000..bcf285b3 Binary files /dev/null and b/dhsi/day-two/imgs/biiif-manifest.png differ diff --git a/europeana/img/cdn.jpg b/dhsi/day-two/imgs/cdn.jpg similarity index 100% rename from europeana/img/cdn.jpg rename to dhsi/day-two/imgs/cdn.jpg diff --git a/europeana/img/horizontal.jpg b/dhsi/day-two/imgs/horizontal.jpg similarity index 100% rename from europeana/img/horizontal.jpg rename to dhsi/day-two/imgs/horizontal.jpg diff --git a/dhsi/day-two/imgs/iiif3validator-in-vscode-image.png b/dhsi/day-two/imgs/iiif3validator-in-vscode-image.png new file mode 100644 index 00000000..7df300f6 Binary files /dev/null and b/dhsi/day-two/imgs/iiif3validator-in-vscode-image.png differ diff --git a/dhsi/day-two/imgs/logo.png b/dhsi/day-two/imgs/logo.png new file mode 100644 index 00000000..9fb6f947 Binary files /dev/null and b/dhsi/day-two/imgs/logo.png differ diff --git a/dhsi/day-two/imgs/menu.jpg b/dhsi/day-two/imgs/menu.jpg new file mode 100644 index 00000000..2455c372 Binary files /dev/null and b/dhsi/day-two/imgs/menu.jpg differ diff --git a/dhsi/day-two/imgs/range-image.png b/dhsi/day-two/imgs/range-image.png new file mode 100644 index 00000000..81376cb3 Binary files /dev/null and b/dhsi/day-two/imgs/range-image.png differ diff --git a/dhsi/day-two/json-crash-course.md b/dhsi/day-two/json-crash-course.md new file mode 100644 index 00000000..9407c521 --- /dev/null +++ b/dhsi/day-two/json-crash-course.md @@ -0,0 +1,192 @@ +# JSON Crash Course + +JSON (Javascript Object Notation) is very popular data format for storing data. + +It is the privilege data for storing and communicating IIIF Data. + +So in order to feel comfortable with the IIIF Presentation API, we need to be comfortable with the basics of the JSON format. + +There are lots of online resources about JSON. A quick google search will give you more content than you could ever want. + +So here were just going to highlight a few fundamental concepts that will help us "interpret" a JSON document. Once that's in place we'll turn to the IIIF Presentation API, and we'll continue to get comfortable with the format the more we use it. + + +## Semantics + +In short there are six different data types that can be communicated with a JSON document. + +When we talk about a "data-type" we're not talking about the data itself, but what kind of data it is. + +For example the number 6 is kind of "number" and its data type is referred to as an **number**. In contrast, the word "dog" is a piece of data but it is distinct from a number. It is referred to as a **string**. + +While "numbers" and "strings" might the more obvious data data types, there are four more. Here's a list. + +* number +* string +* boolean (true or false) +* null (meaning no value) +* list +* object + +Those are the "semantics". The JSON format is distinguished by its "syntax" the manner in which it records or structures these data types so they can be interpreted first by machines but also be humans. + +## Syntax + +### Objects + +Let's start with Objects + +Objects are probably the most fundamental or important datatype (as indicated by the name "JSON **object** notation") + +An object is communicated view the "curly braces" and contains "keys". Each key can take a value which can be one of the 6 data types including objects. So, an object could have many objects nest within it. Let's look at a simple example. + +```json +{ + "name": "DHSI Conference", + "size": 500 +} +``` + +So here we have a small object that has two keys (often called object properties), "name" and "size". Each key has a value of a different data type: "name" takes a "string" while "size": takes a number. + +Note that these type requirements can enforced by something called a schema. While JSON itself doesn't say that a "name" property always has to take a string, a schema or an API (like the IIIF API) will often make declarations about which datatypes an key/property can take. Such a declaration helps the application consuming this data know what to expect when parsing the data. + +So we will often see the IIIF APIs spacing which kinds of values a given property CAN and CANNOT, SHOULD or SHOULD NOT , MAY or MAY NOT take. + +### Strings and Numbers + +Notice in the above example that "strings" are always surrounded by quotation marks while numbers are not. + +So there is a big difference between "1" and 1. + +To appreciate this difference consider the difference an consuming application would see when adding strings verses numbers. + +```js + "1" + "1" = "11" +``` + +while + +```js + 1 + 1 = 2 +``` + + +### Lists + +In addition to objects, there are lists (sometimes called "arrays"). + +Lists are indicated with "square brackets". Lists are "ordered lists" of data, and such lists can be list of all 6 data types, even mixed data types if there is no higher level (schema) restriction. Items within the list are separated by commas + +Here's an example of a **list** within our earlier **object** + +```json +{ + "name": "DHSI Conference", + "size": 500, + "participants": [ + "Bobby", + "Sally", + "Susie + ] +} +``` + +Here's an alternative version where the **items** within the **list** are **objects**: + +```json +{ + "name": "DHSI Conference", + "size": 500, + "participants": [ + { + "name": "Bobby", + "age": 24 + }, + { + "name": "Sally", + "age": 32 + }, + { + "name": "Susie", + "age": 39 + }, + ] +} +``` +NOTE: A **list** of **objects** is an extremely common pattern. And it will be a frequent data structure that you will see within the IIIF Presentation API. + +## Schema Restrictions + +Between the foundations of JSON, further restrictions and control can be implemented through Schemas. And this is precisely what the IIIF Presentation API will do. + +The editors of the IIIF Presentation API have basically defined one large JSON object. And then they have defined the names of various "keys/properties" that this object can take and then the various data types that each one of these properties can take as values. + +## Tools + +There are a lot of tools to make sure you're making valid json documents. + +There are online validators such as [https://jsonlint.com/](https://jsonlint.com/) which will help you make sure you've got quotation marks in the right + +Vscode will also have built in json validation, so if you're editing any file that ends in `.json` or `.jsonld` vscode will alert you to any syntax problems or errors. + +It can also help you format your Json. + +Try creating a document called `test.json` and opening it in vscode. + +Copy in the earlier example, but in a messy unformated way. + +```json +{ +"name": "DHSI Conference", +"size": 500, +"participants": [ +{ + "name": "Bobby", +"age": 24 + }, + { +"name": "Sally", +"age": 32 + }, +{ +"name": "Susie", + "age": 39 +}, + ] +} +``` + +After you've pasted this in, select ⇧⌥F (shift+option+F) and vscode should nicely format this for you. + +--- + +But note that the above two validation methods are only going to check that your syntax is correct, it's not going to check or validate any other schema restrictions. + +To check both syntax and schema validation, there are other tools like the [IIIf Presentation Validator](https://presentation-validator.iiif.io/) + +Finally, with a little prep, we can actually make your vscode environment IIIF schema aware (at least for version 3.0). + +To do this, open your settings panel with `shift+command+P` and type/select `>Preferences: Open User Settings (JSON)`. This will open lo and behold, a `json` document which we, now that we know how to navigate a `json` document are going to edit. + +We're going to add a new `property/key` to the main settings document called `json.schemas` and we're going to tell vscode to apply the IIIF 3.0 Schema to all files that end in `v3.jsonld`. + +Now anytime you name one of your files within the ending `v3.jsonld` the IIIF Presentation 3.0 Schema will be applied. + +Here's the block we want to add. + +```json +"json.schemas": [ + { + "fileMatch": [ + "**/**v3.jsonld" + ], + "url": "https://raw.githubusercontent.com/IIIF/presentation-validator/main/schema/iiif_3_0.json" + }, +] +``` + +Here's an example of what this looks like in my vscode. Here I have a json document designed for the IIIF Presentation API 2.0, and vscode is telling me all the places that are now "out of spec" and need to be updated. + +![alt text](imgs/iiif3validator-in-vscode-image.png) + diff --git a/dhsi/day-two/manifest-exercise.md b/dhsi/day-two/manifest-exercise.md new file mode 100644 index 00000000..4143f03e --- /dev/null +++ b/dhsi/day-two/manifest-exercise.md @@ -0,0 +1,8 @@ +# Manifest exercise + +Create a manifest using either the Bodleian editor (V2) or Digirati editor. You will need to find some Image API links. They don't have to all be from the same Institution/URL. + + +1. [Bodleian (V2)](day-two/bodleian-editor/README.md) +2. [Digirati (V3)](day-two/digirati-editor/README.md) +3. [Digirati A/V](day-two/digirati-editor/Add_video_manifest.md) \ No newline at end of file diff --git a/dhsi/day-two/navplace.md b/dhsi/day-two/navplace.md new file mode 100644 index 00000000..4c312083 --- /dev/null +++ b/dhsi/day-two/navplace.md @@ -0,0 +1,9 @@ +# Navplace viewer +The Navplace viewer requires a navPlace variable in your manifest or canvas(es). + +## NavPlace +``` + +``` + + \ No newline at end of file diff --git a/dhsi/day-two/openseadragon.md b/dhsi/day-two/openseadragon.md new file mode 100644 index 00000000..7be8c16b --- /dev/null +++ b/dhsi/day-two/openseadragon.md @@ -0,0 +1,52 @@ +# OpenSeadragon +OpenSeadragon is a zoomable image viewer that will work with almost any kind of image including a IIIF image. It is also used in almost every IIIF viewer we are going to show you in this class. + +OpenSeadragon also has a [plethora of plugins](https://openseadragon.github.io/#plugins) which we will not be covering in this class. There is also a [OpenSeadragon codepen](https://codepen.io/collection/APoyjJ/) which displays various configurations and the code to create them. + +There are two sets of documents you will want to know in order to work with OpenSeadragon. [https://openseadragon.github.io/docs/](https://openseadragon.github.io/docs/) which has everything from simple to complicated implementation docs for OpenSeadragon and the examples listed on the [homepage](https://openseadragon.github.io/) which will provide different implementations for types of images, etc. + +## Implementation +All you need for OpenSeadragon to work is a [IIIF image(s)](https://openseadragon.github.io/examples/tilesource-iiif/). The example below is built to work with both a single image and multiple. Make sure your container has a width and height otherwise it will not render properly. + + + +``` +
    + + +``` + +
    + + + +## Exercise +Place your images in OpenSeadragon. What are the limitations of this approach? \ No newline at end of file diff --git a/dhsi/day-two/presentation-api.md b/dhsi/day-two/presentation-api.md new file mode 100644 index 00000000..ff525021 --- /dev/null +++ b/dhsi/day-two/presentation-api.md @@ -0,0 +1,25 @@ +# Day Two - IIIF Presentation API +## Presentation API + + + +This video is also available on [YouTube](https://www.youtube.com/watch?v=98z9YNFiUqU) + +### Takeaways +The presentation API allows you to tie IIIF Images together to create a digital presentation of the resource. It allows you to: + + * Link multiple images in a particular order e.g. a Book, Newspaper or Manuscript + * Add Basic descriptive Metadata + * Add Rights information + * Link to other digital objects + * Add Table of Contents etc. + * Based on the linked data vocabulary [Shared Canvas](https://iiif.io/model/shared-canvas/1.0/) + +### Notes +- Image annotations mentioned in this video are not the same as textual annotations which we will be teaching. + +### Version 2 examples +* [The Welsh Book of Remembrance 1928](http://dams.llgc.org.uk/iiif/2.0/4642022/manifest.json) + +### Version 3 examples +* [IIIF 3.0 Cookbook](https://iiif.io/api/cookbook/) diff --git a/dhsi/day-two/publishing-manifests.md b/dhsi/day-two/publishing-manifests.md new file mode 100644 index 00000000..f23365ae --- /dev/null +++ b/dhsi/day-two/publishing-manifests.md @@ -0,0 +1,11 @@ +# Publishing IIIF Manifest +The next section is going to go over three ways of making a manifest visible via a web url. + +## Methods for publishing + +1. [Local Server](visual_studio_setup) +2. [Level 0 Static](workbench) +3. [Cantaloupe](github-publishing.html) + +# Exercise +Chose one of the methods for publishing your manifest. \ No newline at end of file diff --git a/dhsi/day-two/question.md b/dhsi/day-two/question.md new file mode 100644 index 00000000..32f22627 --- /dev/null +++ b/dhsi/day-two/question.md @@ -0,0 +1,18 @@ +# Question + + +Given this image: + + [https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg](https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg) + + ![Example image](https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg) + +How could we construct a URL that: + + * Shows the full image + * is 512px wide + * is upside down + * gray scale + * has a format of png + + diff --git a/dhsi/day-two/ranges.md b/dhsi/day-two/ranges.md new file mode 100644 index 00000000..ed45a629 --- /dev/null +++ b/dhsi/day-two/ranges.md @@ -0,0 +1,185 @@ +# Ranges + +Ranges are great way to provide a navigational aid through your manifest. (It's also a great way for us to continue getting familiar with the JSON and editing the manifest directly.) + +IIIF Viewers are designed to understand these ranges and display navigational aids (often a side panel "table of contents" like view) + +Here's an example. + +![alt text](imgs/range-image.png) + +Once you know what a manifest and a canvas is, adding ranges is not too complicated. + +Presentation API specification on [Ranges](https://iiif.io/api/presentation/3.0/#54-range) offers a clear statement about how to get started. + +> "Ranges must have URIs and they should be HTTP(S) URIs. Top level Ranges are embedded or externally referenced within the Manifest in a structures property. These top level Ranges then embed or reference other Ranges, Canvases or parts of Canvases in the items property." + +So to add a range or series of ranges, we add a `structures` properties on the `manifest object` like so: + +```json + +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "https://example.org/iiif/book1/manifest", + "type": "Manifest", + // Metadata here ... + + "items": [ + // Canvases here ... + ], + + "structures": [ + // your ranges go here + ] +} +``` + +Inside the `structures` array is a serious of `range` objects. Each range object can point to a sequences canvases or point to `sub-ranges` that themselves may point to a sequences of canvases or further sub ranges. + +As always, there are some minor differences between how we do this in a v2 and v3 manifest, but the main idea is the same. + +### v2 Example + +```json + "structures": [{ + "@id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1", + "@type": "sc:Range", + "label": "Sentences Commentary", + "viewingHint": "top", + "ranges": [ + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-2", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-3", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-4", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-5", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-6", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-7", + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-8" + ], + }, + { + "@id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1", + "within": "https://scta.info/iiif/plaoulcommentary/reims/range/r1", + "@type": "sc:Range", + "label": "Principia", + "ranges": [ + "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1-1" + ], + }, + { + "@id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1-1", + "within": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1", + "@type": "sc:Range", + "label": "Principium IV", + "canvases": [ + "http://scta.info/iiif/reims/canvas/R197v", + "http://scta.info/iiif/reims/canvas/R198r", + "http://scta.info/iiif/reims/canvas/R198v", + "http://scta.info/iiif/reims/canvas/R199r", + "http://scta.info/iiif/reims/canvas/R199v", + "http://scta.info/iiif/reims/canvas/R200r", + "http://scta.info/iiif/reims/canvas/R200v", + "http://scta.info/iiif/reims/canvas/R201r" + ] + } + ] +``` + + Here's a live example manifest that includes this full range: [https://scta.info/iiif/plaoulcommentary/reims/manifest](https://scta.info/iiif/plaoulcommentary/reims/manifest) + + ### v3 Example + +Below I've modified the above example, to comply with the v3 changes. (Can you spot the changes??!!!) + + ```json + "structures": [{ + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1", + "type": "Range", + "label": "Sentences Commentary", + "items": [ + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-2", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-3", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-4", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-5", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-6", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-7", + "type": "Range" + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-8", + "type": "Range" + }, + ], + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1", + "type": "Range", + "label": "Principia", + "ranges": [ + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1-1", + "type": "Range" + } + ], + }, + { + "id": "https://scta.info/iiif/plaoulcommentary/reims/range/r1-1-1", + "type": "Range", + "label": "Principium IV", + "items": [ + { + "id": "http://scta.info/iiif/reims/canvas/R197v", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R198r", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R198v", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R199r", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R199v", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R200r", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R200v", + "type": "Canvas" + }, + { + "id": "http://scta.info/iiif/reims/canvas/R201r", + "type": "Canvas" + } + ] + } + ] +``` \ No newline at end of file diff --git a/dhsi/day-two/reflections.md b/dhsi/day-two/reflections.md new file mode 100644 index 00000000..d9648957 --- /dev/null +++ b/dhsi/day-two/reflections.md @@ -0,0 +1,9 @@ +# Some Reflection Questions + +* What kind of NON-image data do you need to make your “viewer” work? +* What kind of labels and descriptions do you need? +* What kind of data relationships are needed in order to make it work? + * (For example sequence: what comes first, what comes last, what comes next?) +* What were the pain points of making an image viewer this way? +* What felt repetitive? +* Were there features you built that you wanted to re-use but couldn't? How come? \ No newline at end of file diff --git a/dhsi/day-two/scaling.md b/dhsi/day-two/scaling.md new file mode 100644 index 00000000..82365750 --- /dev/null +++ b/dhsi/day-two/scaling.md @@ -0,0 +1,17 @@ +# Image Server Scalability + + + +Horizontal scaling: + +![Diagram showing Horizontal Scaling](imgs/horizontal.jpg) + +Content Delivery Network + +![CDN](imgs/cdn.jpg) + +Further reading: + * [Getty Common Image Service](https://drive.google.com/file/d/1pB2eqlSlC4Ua5ZrEEEdJTbofl0wdDApg/view?usp%3Dsharing) - a useful comparison of Image API Servers + * [IIIF by the Numbers](https://journal.code4lib.org/articles/15217) - the UCLA image API setup and experiments + * [Evaluating HTJ2K as a Drop-In Replacement for JPEG2000 with IIIF](https://journal.code4lib.org/articles/17596) + diff --git a/dhsi/day-two/uses.md b/dhsi/day-two/uses.md new file mode 100644 index 00000000..c36a76fb --- /dev/null +++ b/dhsi/day-two/uses.md @@ -0,0 +1,29 @@ +## Uses of the Image API + +The Image URL can be used in the same way as a normal image and has lots of practical uses. + +Embedding on web pages: + +![example iiif image](https://ids.lib.harvard.edu/ids/iiif/25286607/full/,250/0/default.jpg) + +A home teaching background for a menu: + +![menu example](./imgs/menu.jpg) + +[Smithsonian Record](https://collections.si.edu/search/detail/edanmdm:chndm_1980-32-1810-11?q=menu&iiif.enabled=true&record=116&hlterm=menu) + +## Zoom Viewer: +The most common use case is to show the image in a viewer like OpenSeaDragon: + + + + +## National Museum of Sweden + +Some places embed a IIIF Image into their content management system and it means they don't need to use the Presentation API. For example: + +[Magistrate Heurlin's Residence Truveholm in Västergötland](http://emp-web-84.zetcom.ch/eMP/eMuseumPlus?service=ExternalInterface&module=collection&objectId=26240&viewType=detailView) + +## Geo-referencing: + +The [georefrencer.com](https://www.georeferencer.com/) tool is another example which works just with the Image API. diff --git a/dhsi/day-two/uv.md b/dhsi/day-two/uv.md new file mode 100644 index 00000000..d776ed20 --- /dev/null +++ b/dhsi/day-two/uv.md @@ -0,0 +1,229 @@ +# Universal Viewer +Documentation on more complex embeddings can be found on the [UV wiki.](https://github.com/UniversalViewer/universalviewer/wiki/UV-Examples) + +## Creating a Universal Viewer page +1. Create and open in VSCode a file named `uv.html`. +2. Copy the code below into the file +``` + + + + + + + Universal Viewer + + + + + +
    + + + + +``` + +3. Open the file your browser. `open uv.html` + +## Embedding Universal Viewer +1. Create and open in VSCode a file named `uv-embed.html` +2. Copy the code into your browser + +``` + + + + + + + Static Template + + + + + + + + + + + +``` + +3. Open the file in your browser. `open uv-embed.html` + +## Configuring UV +1. Create a file called uv-config.html +2. Copy code below into file +``` + + + + + + + Universal Viewer + + + + + +
    + + + + +``` +3. Open file. `open uv-config.html` +4. Update one of your options to something in this file: https://codesandbox.io/p/sandbox/vibrant-agnesi-7kh4s?file=%2Fuv-config.json +5. Reload the file + +## Configuring UV to use browser parameters (optional) +Perhaps you want to have UV load a manifest based on a parameter you pass into the url (uv.html?manifest='urlofmanifest'). This can be set up in UV. + +``` + + + + + + + Universal Viewer + + + + + +
    + + + + + +``` + diff --git a/dhsi/day-two/viewer.html b/dhsi/day-two/viewer.html new file mode 100644 index 00000000..7fe5047b --- /dev/null +++ b/dhsi/day-two/viewer.html @@ -0,0 +1,29 @@ + + + George and Glen's Teaching Viewer + + + + + +
    +
    + + + diff --git a/dhsi/day-two/visual_studio_setup/README.md b/dhsi/day-two/visual_studio_setup/README.md new file mode 100644 index 00000000..4ca7982c --- /dev/null +++ b/dhsi/day-two/visual_studio_setup/README.md @@ -0,0 +1,66 @@ +# Setup your environment + +Now we have downloaded the Manifest we need to setup an environment so that we can edit the Manifest and also view it using a IIIF viewer. This requires two bits of software the first to allow editing is a JSON aware editor and to allow the viewing of the IIIF manifest in a viewer we need a web server. + +## Installing Visual Studio Code + +There are a number of JSON editors available but Visual Studio Code or VS Code makes it a lot easier by having robust error checking. It is free, Open Source and is currently the most popular editor. There are versions available for MacOS X, Windows and linux. To install this program navigate to the [VS Code](https://code.visualstudio.com/) website and click the download button. + +Once you have downloaded and installed the editor it should look similar to the following: + +![VS Code start page](imgs/vs_code_open.png) + +Once VS Code is open we want to open the `iiif-workshop` folder so that we can view the Manifest we have created. To do this select the `Open` option highlighted below and navigate to the iiif-workshop directory. + +![Open the iiif-workshop directory](imgs/vs_code_open_dir.png) + +Once you have selected the iiif-workshop directory you will be confronted with the following screen. This is called the Explorer view and allows you to navigate between the files in your directory. The items highlighted in read are the current open tabs similar to a list of browser tabs. The items highlighted in yellow are the files in the directory you are working with. Currently there is only a Manifest.json file but as you create more files these will appear in this list. Once you have to to this screen you can click on the Manifest.json link and this will open the JSON file in the editor. You can also close the getting started tab. + +![VS Code Explorer](imgs/vs_code_explorer.png) + +You should now see your Manifest in the open tab of VS Code. You can already see some of the advantages of using VS code for editing JSON. Particularly the thumbnail image of the JSON on the right helps with navigating where you are in the JSON. You can also see how the different elements of the JSON line up as VS Code will connect a horizontal line to show you where a block starts and ends. We will go through the JSON in more detail later but for now you can have a look through your Manifest to see where the labels you entered are located in the JSON. + +![VS Code view Manifest.json](imgs/vs_code_view_manifest.png) + +## Setting up a Web Server + +The next stage is to setup a Web Server so we can share our Manifest and open it in a IIIF Viewer. Luckily VS Code has an extension that provides a Web Server we can use. To install it first click the extensions link highlighted below: + +![VS Code extension link](imgs/vs_code_extension_link.png) + +This will load up a screen to search and install extensions. In the Search box enter `live server` and then click the small install button next to the top result. This will download and install the Live Server plugin. + +![Add live server plugin](imgs/vs_code_add_plugin.png) + +The Live Server adds a Go Live button at the bottom of the editor highlighted in the screen shot below. If you click this it should open a link in your browser which allows you to navigate to your Manifest.json. + +![Go live button](imgs/vs_code_go_live.png) + +Once you've clicked the Go live button you should see the following page in your browser. Now click the `manifest.json` link and it should open up the Manifest. + +![Browser directory listing](imgs/browser_dir.png) + +Once opened the Manifest should like like the following. Now you will need to copy the link to the Manifest so you can open it in a IIIF Viewer. You can copy the URL in the address bar and if you have called your Manifest `manifest.json` the link will probably be: + +[http://127.0.0.1:5500/manifest.json](http://127.0.0.1:5500/manifest.json) + +![View Manifest](imgs/browser_manifest.png) + +## View the Manifest in Universal Viewer +1. Navigate to the [Universal Viewer](http://universalviewer.io) web page. +1. Scroll down to "View a IIIF Manifest". +1. Paste the URL http://127.0.0.1:5500/manifest.json into the text box and click "View". +1. You should see your manifest in the Universal Viewer. + +## Review the Manifest + +Finally it is useful to view the Manifest to see if you can spot where things are appearing in the Viewer and where the data is in the JSON. If you open the JSON at http://127.0.0.1:5500/manifest.json in your browser: + +- Find Manifest `label` +- Explore the Manifest structure: + - Sequence + - Canvas + - `@id` + - `label` + - Annotation + - IIIF Image API service \ No newline at end of file diff --git a/dhsi/day-two/visual_studio_setup/imgs/browser_dir.png b/dhsi/day-two/visual_studio_setup/imgs/browser_dir.png new file mode 100644 index 00000000..e7a31b38 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/browser_dir.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/browser_manifest.png b/dhsi/day-two/visual_studio_setup/imgs/browser_manifest.png new file mode 100644 index 00000000..a9ca2bf5 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/browser_manifest.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_add_plugin.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_add_plugin.png new file mode 100644 index 00000000..61bf3ccf Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_add_plugin.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_explorer.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_explorer.png new file mode 100644 index 00000000..dcedcaff Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_explorer.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_extension_link.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_extension_link.png new file mode 100644 index 00000000..df040303 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_extension_link.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_go_live.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_go_live.png new file mode 100644 index 00000000..86614382 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_go_live.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_open.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_open.png new file mode 100644 index 00000000..58d4eed8 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_open.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_open_dir.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_open_dir.png new file mode 100644 index 00000000..cbc414a7 Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_open_dir.png differ diff --git a/dhsi/day-two/visual_studio_setup/imgs/vs_code_view_manifest.png b/dhsi/day-two/visual_studio_setup/imgs/vs_code_view_manifest.png new file mode 100644 index 00000000..b03643de Binary files /dev/null and b/dhsi/day-two/visual_studio_setup/imgs/vs_code_view_manifest.png differ diff --git a/dhsi/day-two/workbench/README.md b/dhsi/day-two/workbench/README.md new file mode 100644 index 00000000..b71412fa --- /dev/null +++ b/dhsi/day-two/workbench/README.md @@ -0,0 +1,74 @@ +# Publishing your Manifest + +In the previous sections we have asked you to use the Chrome web server to make your manifests available. This works well for trying out your manifest but it does limit some of the tools you can use. The main issue is to do with the Chrome web server making your manifests available as http. In the last few years most web sites have moved over to https which encrypts the traffic and increases privacy. One of the restrictions of https is that it limits access to http resources which can cause problems with some IIIF tools. + +The solution to this is to use a service which will host your manifest using https and for the purposes of this course we are going to use the Workbench introduced in the [Static Images - Workbench](../../day-two/image-servers/level0-workbench.md) section. This encompasses the following stages: + +1. Logon to Workbench and navigate to the Manifests section +2. Upload your Manifest +3. View your Manifest in compatible IIIF tools. +4. Making changes to your manifest + +Further details on these stages are below with screen shots: + +# Stage 1. Logon to Workbench and navigate to the Manifests section + +Navigate to the training workbench: + +[https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/index.xhtml) + +Select the project you are working on and then select the Manifests heading at the top of the page. + +![image](images/start.png) + +# Stage 2. Upload your Manifest + +Now you can upload your manifest. Click the upload button and choose the manifest you want to upload. + +![image](images/upload.png) + +You can change the name of the manifest before uploading. You may want to do this if you already have a manifest with the same name that you've uploaded previously. Ensure that the filename doesn't have any spaces or characters that aren't `.`,`-` or `_`. + +![image](images/change_name.png) + +Then click upload. The upload happens in two stages. The first is uploading the manifest to GitHub which happens quite quickly. The second stage is GitHub updating the website which can take a couple of minutes. While the website is updating you may see the following which will wait to show the Mirador and UV links until the Manifest is available on the website. + +![image](images/loading.png) + +Once you see the IIIF image and other logos it is safe to start using your manifest in other tools. + +# Stage 3. View your Manifest in compatible IIIF tools. + +Now you have a public https manifest you can start using it! There are a number of buttons underneath your manifest which is a good place to get started. + +![image](images/buttons.png) + +The buttons from left to right are as follows: + + * IIIF Logo - if you click this, it will open your manifest in a new window and show you the JSON. If you right click on the image and select `Copy link`, this is the link to your manifest which you can use in other tools. + * Edit icon - click this if you want to make small edits to your manifest. This feature is discussed further in stage 4. + * Delete icon - This will delete the manifest from your project. + * Github icon - This will take you to the GitHub location of your manifest. + * Mirador icon - click this to see your manifest in the latest version of Mirador. + * UV icon - click this to see your manifest in the public UV version. + +As well as the tools above there are also a number of other tools that work with IIIF manifests. For these you will need to copy the Manifest URL in the IIIF logo. Some other tools to try are: + + * [A guide to IIIF viewers](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013) - try your manifest in Mirador 2, Tify, IIIF Curation Viewer and Diva.js + * [exhibit.so](https://exhibit.so/) a tool for creating Exhibits or presentations of your manifests. See the [Guest Videos](../../GuestPresentations.md) for more details. + * [FromThePage](https://www.fromthepage.com/) a transcription tool. Also see the video in the [Guest Videos](../../GuestPresentations.md). + * [Recogito](https://recogito.pelagios.org/) a hosted free transcription and teaching tool. + +# Stage 4. Making changes to your manifest + +If after trying out some of the tools above you want to make some changes to your manifest. There are two ways to do it. The first is to delete the manifest from your project and upload it again. + +The second way is to click the Edit icon. This will take you into GitHub and will look something like this: + +![image](images/github_edit.png) + +You can make changes to the manifest here but be careful as the GitHub interface doesn't provide any validation for the JSON so its easy to miss a `,` or brackets. Once you have made your changes scroll to the bottom of the page where you should see: + +![image](images/github_commit.png) + +Click the commit button to save the changes to your manifest. Note although your changes will be saved straight away it will take a couple of minutes for them to be reflected in the website version of the manifest. diff --git a/dhsi/day-two/workbench/images/buttons.png b/dhsi/day-two/workbench/images/buttons.png new file mode 100644 index 00000000..2b781375 Binary files /dev/null and b/dhsi/day-two/workbench/images/buttons.png differ diff --git a/dhsi/day-two/workbench/images/change_name.png b/dhsi/day-two/workbench/images/change_name.png new file mode 100644 index 00000000..7f7a85cb Binary files /dev/null and b/dhsi/day-two/workbench/images/change_name.png differ diff --git a/dhsi/day-two/workbench/images/github_commit.png b/dhsi/day-two/workbench/images/github_commit.png new file mode 100644 index 00000000..38b32203 Binary files /dev/null and b/dhsi/day-two/workbench/images/github_commit.png differ diff --git a/dhsi/day-two/workbench/images/github_edit.png b/dhsi/day-two/workbench/images/github_edit.png new file mode 100644 index 00000000..dc4e4f43 Binary files /dev/null and b/dhsi/day-two/workbench/images/github_edit.png differ diff --git a/dhsi/day-two/workbench/images/loading.png b/dhsi/day-two/workbench/images/loading.png new file mode 100644 index 00000000..bf0dd5ce Binary files /dev/null and b/dhsi/day-two/workbench/images/loading.png differ diff --git a/dhsi/day-two/workbench/images/start.png b/dhsi/day-two/workbench/images/start.png new file mode 100644 index 00000000..2e52870a Binary files /dev/null and b/dhsi/day-two/workbench/images/start.png differ diff --git a/dhsi/day-two/workbench/images/upload.png b/dhsi/day-two/workbench/images/upload.png new file mode 100644 index 00000000..72479f9d Binary files /dev/null and b/dhsi/day-two/workbench/images/upload.png differ diff --git a/dhsi/day-two/workbench/short.md b/dhsi/day-two/workbench/short.md new file mode 100644 index 00000000..ee0c7ef4 --- /dev/null +++ b/dhsi/day-two/workbench/short.md @@ -0,0 +1,99 @@ +# Publishing your Manifest + + + +Now we have downloaded the Manifest we can use a tool developed for the training called the Workbench. This will publish your manifest using GitHub and make it available on the Web. This encompasses the following stages: + +1. Logon to Workbench and navigate to the Manifests section +2. Upload your Manifest +3. View your Manifest in compatible IIIF tools. +4. Making changes to your manifest + +Further details on these stages are below with screen shots: + +# Stage 0. Register for a GitHub account if you don't have one. + +If you don't have a GitHub account register for one on the [Github](https://github.com/) webpage. + +# Stage 1. Logon to Workbench + +Then Navigate to the training workbench: + +[https://workbench.gdmrdigital.com/](https://workbench.gdmrdigital.com/index.xhtml) + +You should see the following screen: + +![image](../../day-two/image-servers/workbench/login.png) + +Click the Login with GitHub button. + +This will either ask you to login as shown in the following screen shot or if you are already logged in take you straight to the permissions page. + +![image](../../day-two/image-servers/workbench/github_login.png) + +Next you will see the following permissions page. This is asking you if you are happy for the Workbench to write to your GitHub account. Click Authorize. + +![image](../../day-two/image-servers/workbench/authorize.png) + +You should now be taken to the projects page: + +![image](../../day-two/image-servers/workbench/no_project.png) + +You have now successfully logged into the Workbench using your GitHub username and password. Once you have been through the Authorisation step once your browser and GitHub will remember that you have given permission and it should log you straight in. The next stage is to create your project. + +## Stage 2. Create your project + +A project is a place to store the images and manifests you are working on. You can have multiple projects for every GitHub account but note each project is limited to 1GB in size. In the GitHub terminology a project in this case is equivalent to a GitHub Repository. + +To start click the Create Project button: + +![image](../../day-two/image-servers/workbench/no_project.png) + +and enter a name for your project. Note the name can only contain letters, numbers or the following symbols `-` and `_` so don't add any spaces. + +![image](../../day-two/image-servers/workbench/create_project.png) + +Click create. This will take a few seconds but will setup an empty project on GitHub and then forward you onto the images part of the Workbench. + +![image](../../day-two/image-servers/workbench/no_images.png) + +You are now ready to upload your Manifest. + +# Stage 3. Upload your Manifest + +Now you can upload your manifest. Click the upload button and choose the manifest you want to upload. + +![image](images/upload.png) + +You can change the name of the manifest before uploading. You may want to do this if you already have a manifest with the same name that you've uploaded previously. Ensure that the filename doesn't have any spaces or characters that aren't `.`,`-` or `_`. + +![image](images/change_name.png) + +Then click upload. The upload happens in two stages. The first is uploading the manifest to GitHub which happens quite quickly. The second stage is GitHub updating the website which can take a couple of minutes. While the website is updating you may see the following which will wait to show the Mirador and UV links until the Manifest is available on the website. + +![image](images/loading.png) + +Once you see the IIIF image and other logos it is safe to start using your manifest in other tools. + +# Stage 4. View your Manifest in compatible IIIF tools. + +Now you have a public https manifest you can start using it! There are a number of buttons underneath your manifest which is a good place to get started. + +![image](images/buttons.png) + +The buttons from left to right are as follows: + + * IIIF Logo - if you click this, it will open your manifest in a new window and show you the JSON. If you right click on the image and select `Copy link`, this is the link to your manifest which you can use in other tools. + * Edit icon - click this if you want to make small edits to your manifest. This feature is discussed further in stage 4. + * Delete icon - This will delete the manifest from your project. + * Github icon - This will take you to the GitHub location of your manifest. + * Mirador icon - click this to see your manifest in the latest version of Mirador. + * UV icon - click this to see your manifest in the public UV version. + +As well as the tools above there are also a number of other tools that work with IIIF manifests. For these you will need to copy the Manifest URL in the IIIF logo. Some other tools to try are: + + * [A guide to IIIF viewers](https://iiif-io.medium.com/how-to-use-iiif-resources-and-image-viewers-bd378a68b013) - try your manifest in Mirador 2, Tify, IIIF Curation Viewer and Diva.js + * [exhibit.so](https://exhibit.so/) a tool for creating Exhibits or presentations of your manifests. See the [Guest Videos](https://training.iiif.io/iiif-online-workshop/GuestPresentations.html#exhibit) for more details. + * [FromThePage](https://www.fromthepage.com/) a transcription tool. Also see the video in the [Guest Videos](https://training.iiif.io/iiif-online-workshop/GuestPresentations.html#crowdsourced-transcription-using-fromthepage--iiif). + * [Recogito](https://recogito.pelagios.org/) a hosted free transcription and teaching tool. + diff --git a/dhsi/extras.js b/dhsi/extras.js new file mode 100644 index 00000000..3bb9ceeb --- /dev/null +++ b/dhsi/extras.js @@ -0,0 +1,4 @@ + +// Useful if you want to add extra images to the iiif demos +function addExtraImages(config) { +} diff --git a/dhsi/extras/AVExample.md b/dhsi/extras/AVExample.md new file mode 100644 index 00000000..f10f244b --- /dev/null +++ b/dhsi/extras/AVExample.md @@ -0,0 +1,119 @@ +# A basic Video Manifest + +This guide shows you how to create a basic video manifest using the VS code setup we did in Day 3 of the presentation API. The overall steps are as follows: + + 1. Download the example Video Manifest from the IIIF Cookbook + 2. Move your video to the `iiif-workshop` directory + 3. Edit the example Video manifest to point to your Video + 4. Test it in a IIIF viewer + +The steps in more detail are as follows: + +## 1. Download the example video Manifest from the IIIF Cookbook + +The IIIF Cookbook is a useful place to see examples of different use cases of IIIF. The example manifests provided in the recipes also allow you to take a working manifest and edit it with your content. + +To do this we will download the JSON from the following URL: + +[https://iiif.io/api/cookbook/recipe/0003-mvm-video/](https://iiif.io/api/cookbook/recipe/0003-mvm-video/) + +If you navigate to the above URL then right click on the JSON-LD link and select "Save link as": + +![image](images/save_as.png) + +and save the Manifest to your `iiif-workshop` directory and call it `av_manifest.json`. You should be able to access this manifest by clicking on the following URL: + +[http://localhost:5500/av_manifest.json](http://localhost:5500/av_manifest.json) + +## 2. Move your video to the iiif-workshop directory + +Now move your video into the `iiif-workshop` directory. For this example I am going to use the demo video [MistComing.mp4](video/MistComing.mp4). If you have the live server started then it should be accessible here: + +[http://localhost:5500/MistComing.mp4](http://localhost:5500/MistComing.mp4) + +## 3. Edit the example Video manifest to point to your Video + +We now need to edit the example manifest so it points to our video rather than the example video in the recipe. Before we do this we need to work out the dimensions of the video (i.e. width, height and duration in seconds). I found this on a Mac by right clicking on the video file and selecting Get Info: + +![Get file info](images/get_info.png) + +You can then see the dimensions in the more info part highlighted below. + +![Show dimensions](images/more_info.png) + +In this example the file has: + + * Width: 960 + * Height: 540 + * Duration: 00:10 or 10 seconds + +Now we need to open up the example manifest and start editing. To do this we are going to use the VS Code editor which is free to use and helps with editing JSON. Open up the `av_manifest.json` in VS Code. In the screen shot below I have highlighted the 4 changes that we need to make and more details on this changes are below. + +![Manifest edits](images/manifest_edits.png) + +### Changes: + + 1. On line 3 change the id so it points to your manifest. If you've called it `av_manifest.json` the value should be `http://localhost:5500/av_manifest.json` + 2. On line 27 change the URL to the video to point to your vide. If you are using the demo video then the value would be: `http://localhost:5500/MistComing.mp4` + 3. Now change the dimensions of your canvas to match your video. For the example change lines 14 to 16 to be: +``` + "height": 540, + "width": 960, + "duration": 10, +``` + 4. Finally change the dimensions of your video so they match the canvas on lines 29 to 31. + +The full edited manifest should look as follows: + +``` +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "http://localhost:5500/av_manifest.json", + "type": "Manifest", + "label": { + "en": [ + "Video Example 3" + ] + }, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0003-mvm-video/canvas", + "type": "Canvas", + "height": 540, + "width": 960, + "duration": 10, + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0003-mvm-video/canvas/page", + "type": "AnnotationPage", + "items": [ + { + "id": "https://iiif.io/api/cookbook/recipe/0003-mvm-video/canvas/page/annotation", + "type": "Annotation", + "motivation": "painting", + "body": { + "id": "http://localhost:5500/MistComing.mp4", + "type": "Video", + "height": 540, + "width": 960, + "duration": 10, + "format": "video/mp4" + }, + "target": "https://iiif.io/api/cookbook/recipe/0003-mvm-video/canvas" + } + ] + } + ] + } + ] +} +``` + +## 4. Test it in a IIIF viewer + +Now you have your first AV manifest it is time to test it in a viewer. If you have named your file `av_manifest.json` the following links should open up your manifest in the UV and Mirador: + + * [http://universalviewer.io/examples/#?c=&m=&s=&cv=&manifest=http://localhost:5500/av_manifest.json](http://universalviewer.io/examples/#?c=&m=&s=&cv=&manifest=http://localhost:5500/av_manifest.json) + +Note this example won't work in Mirador because Mirador is hosted at https://projectmirador and a https website is not allowed to access a http manifest. + diff --git a/dhsi/extras/README.md b/dhsi/extras/README.md new file mode 100644 index 00000000..5fdafb07 --- /dev/null +++ b/dhsi/extras/README.md @@ -0,0 +1,8 @@ +# Extras + +This is a place to show extra guides which may be useful for the end of week project or as extensions to explore. + +## Guides + + * [Using non IIIF images in a manifest](https://glenrobson.github.io/iiif_stuff/simple_images/) + * [A basic Video manifest](AVExample.md) diff --git a/dhsi/extras/images/get_info.png b/dhsi/extras/images/get_info.png new file mode 100644 index 00000000..f4247668 Binary files /dev/null and b/dhsi/extras/images/get_info.png differ diff --git a/dhsi/extras/images/manifest_edits.png b/dhsi/extras/images/manifest_edits.png new file mode 100644 index 00000000..124cf978 Binary files /dev/null and b/dhsi/extras/images/manifest_edits.png differ diff --git a/dhsi/extras/images/more_info.png b/dhsi/extras/images/more_info.png new file mode 100644 index 00000000..c971305b Binary files /dev/null and b/dhsi/extras/images/more_info.png differ diff --git a/dhsi/extras/images/save_as.png b/dhsi/extras/images/save_as.png new file mode 100644 index 00000000..c383eeb7 Binary files /dev/null and b/dhsi/extras/images/save_as.png differ diff --git a/dhsi/extras/video/MistComing.mp4 b/dhsi/extras/video/MistComing.mp4 new file mode 100644 index 00000000..a37896ce Binary files /dev/null and b/dhsi/extras/video/MistComing.mp4 differ diff --git a/iiif-5-day-workshop/help.md b/dhsi/help.md similarity index 89% rename from iiif-5-day-workshop/help.md rename to dhsi/help.md index 3f39eb4f..b14883e9 100644 --- a/iiif-5-day-workshop/help.md +++ b/dhsi/help.md @@ -11,9 +11,9 @@ $ npm i gitbook-cli -g ```sh $ git clone git@github.com:IIIF/training.git ``` -1. Change directory to `iiif-5-day-workshop` +1. Change directory to `dhsi` ```sh -$ cd training/iiif-5-day-workshop +$ cd training/dhsi ``` 1. Run the Gitbook server ```sh diff --git a/dhsi/styles/website.css b/dhsi/styles/website.css new file mode 100644 index 00000000..37fea250 --- /dev/null +++ b/dhsi/styles/website.css @@ -0,0 +1,66 @@ + +.demo li { + display: inline-block !important; + margin: 0px; + padding-left: 3px; + padding-right: 3px; + border-right: 1px solid black; +} +.demo { + padding-left: 0px !important; + list-style: none !important; + margin: auto; + text-align: center; + word-wrap: break-word !important; +} +.attr2 { + font-size: small; +} + +.centre { + display:block; + margin:auto; + text-align: center; +} + +.identifier { + max-width:300px; +} +.region { + max-width:100px; +} + +.highlight { + background-color: gainsboro; + box-shadow: 0.5px 0.5px 5px gray; + border: none; +} + +.standout-image { + box-shadow: 0.5px 0.5px 5px gray; + border: 1px solid black !important; +} + +#iiif-image-api-div { + position: relative; + background-image: url(https://ids.lib.harvard.edu/ids/iiif/25286607/full/500,/0/default.jpg); + background-size: contain; + background-repeat: no-repeat; + width: 100%; + height: 0; + padding-top: 66.64%; +} + +#highlight { + position: absolute; + top: 10px; + left: 100px; + width: 50px; + height: 50px; + background-color: white; + -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; /* IE 8 */ + filter: alpha(opacity=50); /* IE 5-7 */ + -moz-opacity: 0.5; /* Netscape */ + -khtml-opacity: 0.5; /* Safari 1.x */ + opacity: 0.5; /* Good browsers */ +} diff --git a/dhsi/unused/IIIFforResearch.md b/dhsi/unused/IIIFforResearch.md new file mode 100644 index 00000000..27aade61 --- /dev/null +++ b/dhsi/unused/IIIFforResearch.md @@ -0,0 +1,73 @@ +# Using IIIF for research + +## Quick review + +### Two APIs we'll focus on today +* Image API + +#### Quick Exercise: go to [https://www.learniiif.org/image-api/playground](https://www.learniiif.org/image-api/playground) and manipulate the test image + +* Presentation API + +"Manifest" - this is the bundle of information that IIIF relies on to enable sharing of books and manuscripts across viewers and institutions + +## Finding IIIF Materials "in the wild" + +How we encounter IIIF materials at various repositories varies widely. Explore some of the collections below to get a sense of what steps you might need to go through to find IIIF material to work with. + +* OCLC IIIF Explorer (experimental): [https://researchworks.oclc.org/iiif-explorer/](https://researchworks.oclc.org/iiif-explorer/) +* Bayerische StaatsBibliothek: [https://app.digitale-sammlungen.de/bookshelf/](https://app.digitale-sammlungen.de/bookshelf/) +* Stanford Special Collections: [https://bit.ly/stanford_iiif](https://bit.ly/stanford_iiif) +* Biblissima (aggregates many European libraries): [https://iiif.biblissima.fr/collections/](https://iiif.biblissima.fr/collections/) +* The Vatican: [https://digi.vatlib.it/](https://digi.vatlib.it/) +* Harvard: [https://library.harvard.edu/digital-collections](https://library.harvard.edu/digital-collections) +* Many, many more: [https://bit.ly/iiif_collections](https://bit.ly/iiif_collections) + +#### Quick Exercise: + +* Open an instance of Mirador 2 - [this one, for instance](http://dms-data.stanford.edu/data/mirador_cropper/example.html) or [this one](https://deploy-preview-13--mirador.netlify.app/demo/) +* Find an item from the collections listed above that you might be interested in exploring further +* Find the IIIF badge and drag it into Mirador, or use the IIIF manifest URL and add it to the Mirador workspace +* As a point of comparison, use the same IIIF manifest URL and add it to the [Universal Viewer](https://universalviewer.io/) +* Note: Different software for different user experiences, same source content + +## The Basics: Zooming and Comparison + +We're going to continue to use the Mirador Viewer, version 2, for this example, though version 3 would work as well if you prefer that - see the [Mirador 3 demo site](https://mirador-dev.netlify.app/__tests__/integration/mirador/) + +Many research uses simply call for being able to zoom in to specific details, which nearly all of the IIIF viewers do by default. Side-by-side comparison is another basic research need. + +#### Quick Exercise: +* Using one of the Mirador demo sites listed above, build a workspace view that compares two or more manuscripts. + +## Creating Annotations + +There are many ways to create annotations in IIIF. One of the simplest ways to start is to use Mirador to create "commenting" or "transcription" annotations. + +A very nice example of the use of these kinds of annotations can be found at the Vatican: https://spotlight.vatlib.it/humanist-library + +#### Quick Exercise +* Using the Mirador example you worked with previously, add some simple annotations to your object + +## Using Annotations to Drive a User Experience + +Another way to use annotations and images together for research or teaching purposes is with tools developed to guide a viewer through a curated experience. We'll talk about various tools to do this over the course of the week, but for today let's look at one approach developed by CogApp. + +* CogApp: Storiiies - [http://storiiies.cogapp.com/](http://storiiies.cogapp.com/) +* Storiiies Editor: [https://storiiies-editor.cogapp.com/](https://storiiies-editor.cogapp.com/) +* Example: [https://storiiies.cogapp.com/viewer/aeqi/The-Stoning-of-Saint-Stephen](https://storiiies.cogapp.com/viewer/aeqi/The-Stoning-of-Saint-Stephen) + +## Transcriptions are a Kind of Annotation + +For this section, we'll look at using IIIF to support transcription projects using [FromThePage](https://fromthepage.com/) + +Example: +* [La Sfera Challenge](https://lasferachallenge.wordpress.com/) +* [La Sfera at FromThePage](https://fromthepage.com/stanfordlibraries/the-international-la-sfera-challenge) +* [La Sfera Results in Mirador](https://dms-data.stanford.edu/data/build/lasfera.html) + +## Questions to pursue this week +* How do we save and host annotations and research outputs? +* How do we credit contributors? +* How do we notify others when new annotations are published? +* Others? diff --git a/dhsi/unused/README.md b/dhsi/unused/README.md new file mode 100644 index 00000000..56343e8f --- /dev/null +++ b/dhsi/unused/README.md @@ -0,0 +1,4 @@ +# Day 1 - Introductions and IIIF Basics +## Monday + +The first day of the workshop is focused on getting to know each other and to learn the basics of IIIF before diving into the different API specifications on day two and three. There is a short introduction to IIIF followed by a basic exercise to View a IIIF object in a IIIF Viewer. diff --git a/dhsi/unused/getty-guides.md b/dhsi/unused/getty-guides.md new file mode 100644 index 00000000..24e419d9 --- /dev/null +++ b/dhsi/unused/getty-guides.md @@ -0,0 +1,81 @@ +# Finding IIIF manifests in the GRI collection + +For the purposes of this workshop we are going to look at a GRI item in a number of different viewers to show one of the popular use cases. This can be either from the view point of a researcher choosing a particular viewer with the tools they need to do their research or from an institution creating a custom view on their collection. + +We are going to start with the Edward Ruscha photographs of Los Angeles streets which can be found on the website below and we are going to try and find something called a IIIF Manifest. A Manifest is something defined by the IIIF standards and is a document which points to all of the images and metadata about an object. We are going to copy a link to this manifest and open it in a number of different IIIF viewers. + + * [https://12sunsets.getty.edu](https://12sunsets.getty.edu) + +Once you have selected an image you will need to navigate to the record at Getty Research Institute: + +![Screen shot of the view in GRI](img/getty_view_gri.png) + +Once you have clicked on the GRI link you can scroll to the bottom of the page and look for the View IIIF manifest link. If you right click and either Copy link (Firefox) or Copy Link Address (Chrome). You now have a link to the manifest you can use in the viewers mentioned below. + +![Screenshot of the view manifest link](img/view_manifest.png) + +You could also use the [Digital Florentine Codex](https://florentinecodex.getty.edu/). Unfortunately it isn't possible to access the Manifests through the site as the site does not have a IIIF button. So the manifest for the site is shown below: + + * [The Florentine Codex](https://dfc-django-backend.getty.digirati.io/iiif/iiif/manifest/f75b53f9-7295-41f3-9299-6bbe04685c8b/) + +# Finding IIIF manifests from other institutions + +This is also an issues for the IIIF Community is how to find IIIF resources. One method that the community is using to solve this problem is to create a list of guides showing how to access IIIF manifest for various institutions. + +![Screenshot of the Guides Website](img/guides.png) + +This is available on the IIIF website at the following location: + +[https://iiif.io/guides/finding_resources/](https://iiif.io/guides/finding_resources/) + +This is a community effort and if your institution isn't listed then please feel free to add it to the [Github Repository](https://github.com/IIIF/guides) or fill in the following [Google form](https://forms.gle/S6LLjBy2o4iEBR8C9). + +If you look through the different collections listed you will notice there are many ways to get the link to a Manifest and this is also something the community is looking to standardise. + +# Task: Find a Manifest + +Using the guides site above find a Manifest you would like to view in one of the major IIIF viewers, either Mirador or the Universal Viewer (UV). Opening Manifests in the UV and Mirador is something that we will do a lot of during the course. + +## Opening up a Manifest in Mirador 3 + +Navigate to [https://projectmirador.org/](https://projectmirador.org/) and click the __Try a Live Demo__ button. Once Mirador opens close the two demo objects by clicking the two crosses highlighted in the screen shot below: + +![Mirador close window screenshot](img/mirador_close.png) + +Then click the Start here button on the top left. + +![Mirador start screenshot](img/mirador-start.png) + +Then click the add resource button at the bottom right: + +![Mirador add Manifest button](img/mirador-add-resource.png) + +Finally you can paste your URL to your manifest and click Add and Mirador should open your Manifest. + +![Mirador add Manifest](img/mirador-add-manifest.png) + +## Opening up a Manifest in the Universal Viewer + +Navigate to [http://universalviewer.io/](http://universalviewer.io/). Scroll down to where you see the __View a IIIF Manifest__ heading and enter in your Manifest URL and click View. + +![UV enter manifest screenshot](img/uv_manifest.png) + +If you need to switch to a new manifest then scroll to the bottom of the UV page and enter it in the __Set IIIF Manifest Id__ box and click the button next to it. + +## Other viewers + +Clover: + * [https://samvera-labs.github.io/clover-iiif/docs/viewer/demo](https://samvera-labs.github.io/clover-iiif/docs/viewer/demo) + * Paste the Manifest URL just below the docs button. + +IIIF Curation Viewer + * [http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/](http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/) + * Right click in the middle and click paste + +Tify + * [https://tify.rocks/](https://tify.rocks/) + * Scroll to the bottom and enter the manifest URL into the box and hit return. + +Annona + * [https://ncsu-libraries.github.io/annona/tools/#/display?url=https://media.getty.edu/iiif/manifest/4fc71f54-cd9e-4d68-bb33-3866e5deb530&viewtype=iiif-storyboard&manifesturl=&settings={"fullpage"%3Atrue}](https://ncsu-libraries.github.io/annona/tools/#/display?url=https://media.getty.edu/iiif/manifest/4fc71f54-cd9e-4d68-bb33-3866e5deb530&viewtype=iiif-storyboard&manifesturl=&settings={"fullpage"%3Atrue}) + * You will have to edit the URL to get your own Manifest in here. \ No newline at end of file diff --git a/dhsi/unused/guides.md b/dhsi/unused/guides.md new file mode 100644 index 00000000..8cabe9f0 --- /dev/null +++ b/dhsi/unused/guides.md @@ -0,0 +1,43 @@ +# Finding IIIF Manifests + +One of the issues facing the IIIF Community is how to find IIIF resources. One method that the community is using to solve this problem is to create a list of guides showing how to access IIIF manifest for various institutions. + +![Screenshot of the Guides Website](img/guides.png) + +This is available on the IIIF website at the following location: + +[https://iiif.io/guides/finding_resources/](https://iiif.io/guides/finding_resources/) + +This is a community effort and if your institution isn't listed then please feel free to add it to the [Github Repository](https://github.com/IIIF/guides) or fill in the following [Google form](https://forms.gle/S6LLjBy2o4iEBR8C9). + +If you look through the different collections listed you will notice there are many ways to get the link to a Manifest and this is also something the community is looking to standardise. + +# Task: Find a Manifest + +Using the guides site above find a Manifest you would like to view in one of the major IIIF viewers, either Mirador or the Universal Viewer (UV). Opening Manifests in the UV and Mirador is something that we will do a lot of during the course. + +## Opening up a Manifest in Mirador 3 + +Navigate to [https://projectmirador.org/](https://projectmirador.org/) and click the __Try a Live Demo__ button. Once Mirador opens close the two demo objects by clicking the two crosses highlighted in the screen shot below: + +![Mirador close window screenshot](img/mirador_close.png) + +Then click the Start here button on the top left. + +![Mirador start screenshot](img/mirador-start.png) + +Then click the add resource button at the bottom right: + +![Mirador add Manifest button](img/mirador-add-resource.png) + +Finally you can paste your URL to your manifest and click Add and Mirador should open your Manifest. + +![Mirador add Manifest](img/mirador-add-manifest.png) + +## Opening up a Manifest in the Universal Viewer + +Navigate to [http://universalviewer.io/](http://universalviewer.io/). Scroll down to where you see the __View a IIIF Manifest__ heading and enter in your Manifest URL and click View. + +![UV enter manifest screenshot](img/uv_manifest.png) + +If you need to switch to a new manifest then scroll to the bottom of the UV page and enter it in the __Set IIIF Manifest Id__ box and click the button next to it. diff --git a/dhsi/unused/image-api/format.md b/dhsi/unused/image-api/format.md new file mode 100644 index 00000000..ffadf03d --- /dev/null +++ b/dhsi/unused/image-api/format.md @@ -0,0 +1,47 @@ +## Format + + + + +The format of the image for example `jpg` or `png`. The list of images supported by the image server is again listed in the `info.json`. + +
    +
    + + + diff --git a/dhsi/unused/image-api/identifier.md b/dhsi/unused/image-api/identifier.md new file mode 100644 index 00000000..07fe69f5 --- /dev/null +++ b/dhsi/unused/image-api/identifier.md @@ -0,0 +1,86 @@ +## Identifier + + + +The identifier is highlighted below. Everything to the right of the identifier is controlled by the Image API and is predictable. In the viewer below a full IIIF image URL is shown. One thing to watch out for with a image URL is that it uses _https_ rather than _http_. With _http_ URLs you will not be able to open the image in a _https_ hosted viewer. + +You can see some different image examples by changing the identifier. +
    +
    + + +## Info.json + +As well as an image URL there is another special file accessible from the Identifier and this is the `info.json`: + +[https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001/info.json](https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001/info.json) + +This is a small JSON file that gives information to a viewer on the makeup of the image and what the server supports. For example the `info.json` gives the full width and height of the source image. A simple example `info.json` is below: + +``` +{ + "@context": "http://iiif.io/api/image/2/context.json", + "@id": "https://ids.si.edu/ids/iiif/CHSDM-317E001E9E352-000001", + "protocol": "http://iiif.io/api/image", + "width": 5471, + "height": 3757, + "tiles": [ + { + "width": 512, + "scaleFactors": [ + 1, + 2, + 4, + 8 + ] + } + ], + "profile": [ + "http://iiif.io/api/image/2/level2.json", + { + "formats": [ + "jpg" + ], + "supports": [ + "sizeByH", + "sizeByW", + "sizeByForcedWh" + ] + } + ] +} +``` + +The `profile` element advertises what the image server supports. In this example it only supports the `jpg` image format and a few features. These features are defined in the [Image API specification](https://iiif.io/api/image/2.1/compliance/). diff --git a/dhsi/unused/image-api/quality.md b/dhsi/unused/image-api/quality.md new file mode 100644 index 00000000..b02d9df4 --- /dev/null +++ b/dhsi/unused/image-api/quality.md @@ -0,0 +1,77 @@ +## Quality + + + +The Quality parameter defines whether the image should be delivered as: + +| Name | Definition | +| --- | --- | +| Default | The source colour | +| Gray | Grayscale | +| Bitonal | Each pixel is black or white | +| Color | The color image. This could be a colorized black and white image | + +This can be useful for some image processing tools like OCR generation. To see what types a image server supports you can look into the `info.json` profile section: + +[https://ids.lib.harvard.edu/ids/iiif/25286607/info.json](https://ids.lib.harvard.edu/ids/iiif/25286607/info.json) + +``` +profile": [ + + "http://iiif.io/api/image/2/level2.json", + { + "supports": [ + "canonicalLinkHeader", + "profileLinkHeader", + "mirroring", + "rotationArbitrary", + "regionSquare", + "sizeAboveFull" + ], + "qualities": [ + "default", + "bitonal", + "gray", + "color" + ], + "formats": [ + "jpg", + "tif", + "png", + "gif", + "webp" + ] + } + +], +``` + +See the example below: + +
    +
    + + + diff --git a/dhsi/unused/image-api/region.md b/dhsi/unused/image-api/region.md new file mode 100644 index 00000000..46b319ce --- /dev/null +++ b/dhsi/unused/image-api/region.md @@ -0,0 +1,60 @@ +## Region + + + + +The region allows you to extract a portion of an image. The format is `/x,y,width,height/` with the origin of the image being the top left. See this simplified version below: + +![region example](https://iiif.io/api/image/2.1/img/region_px.png) + +This region would be noted as `/125,15,120,140/` which is: + * x = 125 pixels from the left + * y = 15 pixels from the top + * width = 120 pixels + * heigh = 140 pixels + +The pixel dimensions are relative to the full width and height of the image. This generally makes the regions fiddly to work out by hand and there are many cropping tools available which will give you a region: + + * [Jack Reed's Cropping tool](https://bl.ocks.org/mejackreed/6936585f435b60aa9451ae2bc1c199f2) + * [UCD Image Cropping tool](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://ids.lib.harvard.edu/ids/iiif/25286607) + +As well as specifying the exact pixel dimensions there are a couple of short cuts: + + * `full` the full image. + * `square` a region where the width and height are equal. The region is positioned by the server. This can be useful for square thumbnails. + +Use the region drop down to select different regions of the image: + +
    +
    + + + diff --git a/dhsi/unused/image-api/rotation.md b/dhsi/unused/image-api/rotation.md new file mode 100644 index 00000000..4d900a93 --- /dev/null +++ b/dhsi/unused/image-api/rotation.md @@ -0,0 +1,56 @@ +## Rotation + + + + +Rotating the image in degrees up to 360. You can also use the `!n` to mirror and rotate the image. Note not all image server support rotation and there are the following levels of support known as [compliance levels](https://iiif.io/api/image/2.1/compliance/): + +| Feature | Level | +| --- | --- | +| No rotation supported | Level 0 | +| Only 90 degree rotation supported | Optional in Level 1 mandatory in level 2 | +| Arbitrary rotation | Optional at all levels | +| Mirroring | Optional at all levels | + +The Harvard image service supports all rotation parameters and is known as a Level 2 implementation. + +
    +
    + + + diff --git a/dhsi/unused/image-api/size.md b/dhsi/unused/image-api/size.md new file mode 100644 index 00000000..e32de428 --- /dev/null +++ b/dhsi/unused/image-api/size.md @@ -0,0 +1,56 @@ +## Size + + + + +The size governs the size of the output image. A full list of options is available in the [Image API specification](https://iiif.io/api/image/2.1/#size). Some of the more common ones: + +| Form | Description | +| -- | -- | +| full | The full image (this is renamed `max` in 3.0) | +| w, | Only the width is specified and the server works out the correct height to keep the aspect ratio. Example `500,`| +| ,h | The alternative only specifying the height. Example `,250`| +| w,h | Explicit width and height. Note this will distort the image. Example: `250,250` | +| !w,h | Fit in a box width by height but don't distort the image. Example `!250,250` | + +See the examples below: + +
    +
    + + + diff --git a/europeana/SUMMARY.md b/europeana/SUMMARY.md index 0094b930..3f70b4e5 100644 --- a/europeana/SUMMARY.md +++ b/europeana/SUMMARY.md @@ -12,11 +12,11 @@ - [Hosted - Internet Archive](day-two/image-servers/iiif-hosting-ia.md) - [Static Images - Workbench](day-two/image-servers/level0-workbench.md) - [Cantaloupe (Advanced)](day-two/image-servers/setting-up-cantaloupe.md) -- [Scaling IIIF Images](scaling.md) +- [Scaling IIIF Images](day-two/scaling.md) ## Presentation API -- [Presentation API](prezi-intro.md) -- [How do people create Manifests?](prezi-how.md) +- [Presentation API](day-three/prezi-intro.md) +- [How do people create Manifests?](day-three/prezi-how.md) - [Create a Manifest](bodliean-editor.md) - [Publishing your manifest](day-three/workbench/short.md) - [Extra: Create an Exhibit](exhibit/exhibit.md) diff --git a/europeana/book.json b/europeana/book.json index 0a8e715d..890e79b5 100644 --- a/europeana/book.json +++ b/europeana/book.json @@ -5,8 +5,6 @@ "theme-default", "toggle-chapters", "git-author", - "-highlight", - "sunlight-highlighter", "toggle-chapters" ], "gitbook": "3.2.3", diff --git a/europeana/exhibit/getty.md b/europeana/exhibit/getty.md new file mode 100644 index 00000000..f7fc0bba --- /dev/null +++ b/europeana/exhibit/getty.md @@ -0,0 +1,64 @@ +# Create an Exhibit + +This is a practical way to demonstrate what you can do with Manifests. An example of a presentation pulling together multiple manifests is given below: + + + +This tells the story of a ship called the Canganian and brings together IIIF resources from Newspapers to Manuscripts to make the presentation. + +## Find manifests + +For this example we are going to use the manifests from the [12 Sunsets project](https://12sunsets.getty.edu/). + +## Create an Exhibit + +Navigate to: + +[https://www.exhibit.so/](https://www.exhibit.so/) + +Scroll to the bottom until you see the 'Create an Exhibit' button. Click this and you will be taken to the following screen: + +![Create Exhibit screen](img/create.png) + +On this screen you can choose the following type of presentation: + + * Kiosk - this will auto play the slides and is useful for a public display terminal + * Scroll - 'slides' will be presented in a single long web page and uses will scroll down to read the story + * Slides - the default and allows uses to press right or left to navigate the different parts of the story. + * Quiz - Similar to the Slides option buy you can ask your viewers to answer a questions + +For this tutorial we will focus on the slides option. Fill in a Title, Author and Description for your exhibit and agree to the Terms and Conditions and tick the I am not a robot button. Then click "Create Exhibit". + +You will then be presented with the following screen: + +![Exhibition start screen](img/start.png) + +The first thing to do is to add your Manifest. Now switch back to the Exhibit tool and click the Add Item button and it will show this dialog: + +![Add Manifest URL](img/add_item.png) + +Paste the Manifest URL into the text box and click import. You should see the manifest load in the background and the manifest title in the Items dialog: + +![List items dialog](img/list_items.png) + +Click the cross to close this dialog. + +Now we have the manifest loaded we want to create a 'slide'. Click the + on the left hand side of the screen underneath the Title and description: + +![add slide button](img/add_anno.png) + +Enter a description of what you would like to show and then zoom the right hand image into an area of the image you would like to highlight. + +![add description and zoom](img/zoom.png) + +Once you are happy with the description and zoom click the tick symbol to save the annotation. + +You can now add a number of different slides to tell your story. You can also add different Manifests using the Add Item button. + +Once you are happy click the Preview button which will show you what your presentation looks like: + + + +You can find Manifests from various institutions by going to the IIIF Guides website: + +[https://guides.iiif.io/finding_resources/](https://guides.iiif.io/finding_resources/) diff --git a/europeana/prezi-how.md b/europeana/prezi-how.md deleted file mode 100644 index 10f5eee0..00000000 --- a/europeana/prezi-how.md +++ /dev/null @@ -1,55 +0,0 @@ -# How do people create Manifests? - - - -In this workshop we are going to take you through creating a Manifest using a Manifest Editor. This works well for a small number of manifests and to give you an idea of what a Manifest contains. If you are going to create thousands or millions of manifests then you would need to look at automating this process. - -Generally the data required to create a manifest generator are as follows: - - * Accessible IIIF Images - * Structural data on how the images relate to each other. For example the order of the pages in a manuscript - * Descriptive metadata for example: - * Title - Name of the item this is called a `label` in IIIF - * Description (optional) - * Rights or licensing (optional) - * Metadata useful for discovery (optional) - this will be explained later - -Generally the format of the incoming metadata means that often these manifest generation tools are custom to each institution although there are the following libraries that can assist in the process: - - * [biiif](https://github.com/edsilv/biiif/) Organise your files according to a simple naming convention to generate IIIF v3 manifests. - * [demetsiiify](https://github.com/jbaiter/demetsiiify) - Web service for creating IIIF manifests from METS/MODS documents. - -## Presentation API Libraries - * [IIIF Manifest Generator](https://github.com/yale-web-technologies/IIIF-Manifest-Generator) - PHP library for generating IIIF manifests. - * [iiif-apis](https://github.com/dbmdz/iiif-apis) - Java IIIF API libraries. - * [iiif-prezi](https://github.com/IIIF/iiif-prezi) - Python library providing a reference implementation. - * [O'Sullivan](https://github.com/IIIF/osullivan) - Ruby API for creating IIIF manifests. - * [Swiiift](https://github.com/mejackreed/Swiiift) - IIIF presentation API library for Swift. - * [tabula-rasa](https://www.npmjs.com/package/tabula-rasa) - npm module for creating and manipulating IIIF manifests. - * [ViewDir](https://iiif-commons.github.io/) - Documentation on IIIF-related libraries and components. - -Once the Manifests are generated they can be stored on any Web Server and don't need a specific server like the Image API. - -## Important Considerations - -When publishing manifests there are a couple of considerations you need to take in account. - -### http/https issue - -With the Web more generally moving to https if you publish your manifests as http it means they will no longer work in many of the online viewers and tools. Previously this was encouraged but now with the number of https sites it is almost impossible to use a http manifest. - -### CORS issues - -Another requirement for IIIF is to enable CORS headers. CORS headers tell the browser that its OK to open this JSON on a website which doesn't match the location of your Manifest. For example it says projectMirador.org can open a manifest from the Library of Congress. Without CORS headers being set then you will only be able to open your manifest on your website. For more details see: - -https://enable-cors.org/ - -### JSON issues - -Finally if you are hand editing JSON documents it is very easy to miss required commas and brackets so the following tool is useful to validate your JSON: - - * [JSONLint](https://jsonlint.com/) - -If your Manifest is valid JSON but its not working in a viewer there is a IIIF Validator which will let you know if the JSON has fields that are not part of the IIIF specifications: - - * [IIIF Presentation Validator](https://iiif.io/api/presentation/validator/service/) diff --git a/europeana/scaling.md b/europeana/scaling.md deleted file mode 100644 index 7f2afd0c..00000000 --- a/europeana/scaling.md +++ /dev/null @@ -1,17 +0,0 @@ -# Image Server Scalability - - - -Horizontal scaling: - -![Diagram showing Horizontal Scaling](img/horizontal.jpg) - -Content Delivery Network - -![CDN](img/cdn.jpg) - -Further reading: - * [Getty Common Image Service](https://drive.google.com/file/d/1pB2eqlSlC4Ua5ZrEEEdJTbofl0wdDApg/view?usp%3Dsharing) - a useful comparison of Image API Servers - * [IIIF by the Numbers](https://journal.code4lib.org/articles/15217) - the UCLA image API setup and experiments - * [Using Loris for IIIF at Wellcome](https://stacks.wellcomecollection.org/using-loris-for-iiif-at-wellcome-6ed1fefaf801) - diff --git a/europeana/styles b/europeana/styles index 7f12b895..ae9de7f3 120000 --- a/europeana/styles +++ b/europeana/styles @@ -1 +1 @@ -../iiif-online-workshop/styles/ \ No newline at end of file +../iiif-online-workshop/styles/. \ No newline at end of file diff --git a/gri_getty/README.md b/gri_getty/README.md new file mode 100644 index 00000000..696d7981 --- /dev/null +++ b/gri_getty/README.md @@ -0,0 +1,10 @@ +# GRI Custom training + +This is a custom training built for the Getty GRI and was delivered on the 10th of November 2023. It is a 2 hour workshop with the following aims: + +1. Brief introduction to overall IIIF capabilities. A general overview of major IIIF functionality, and a wide range of example use cases from institutional uses around the world. +2. IIIF Viewers. The general usage of IIIF viewers, such as Mirador 3 and Universal Viewer. Other viewers, perhaps with specialized interfaces, could be added if time allows. +3. Finding IIIF Manifests in the RCV and using them in IIIF viewers. +4. Cropping Tools. How to extract images from within Getty IIIF manifests, and using them in well-known IIIF cropping tools. +5. Comparison Tools. The usage of additional comparison functionality within Mirador, and how researchers and scholars use this IIIF functionality to further their work. +6. Time-allowing: The basics of Annotations and Guided Storytelling. \ No newline at end of file diff --git a/gri_getty/SUMMARY.md b/gri_getty/SUMMARY.md new file mode 100644 index 00000000..de8e5eb7 --- /dev/null +++ b/gri_getty/SUMMARY.md @@ -0,0 +1,16 @@ +# Summary + +- [Overview](README.md) + +# Part 1 +- [IIIF Basics](https://training.iiif.io/iiif-online-workshop/day-one/whatisiiif.html) +- [How users make use of IIIF](introduction.md) +- [Finding IIIF manifests](day-one/getty-guides.md) + +# Part 2 + +- [Looking at other GRI collections](gri_collections.md) +- [Cropping Tools](cropping_tools.md) +- [Geolocating a Map](geo-locating-map.md) +- [Exhibit building](exhibit/getty.md) +- [Project demos and summary](demos.md) diff --git a/gri_getty/book.json b/gri_getty/book.json new file mode 100644 index 00000000..e1036a0a --- /dev/null +++ b/gri_getty/book.json @@ -0,0 +1,26 @@ +{ + "title": "Getty GRI Workshop 10th November 2023", + "plugins": [ + "include", + "theme-default", + "toggle-chapters", + "git-author", + "-highlight", + "toggle-chapters" + ], + "gitbook": "3.2.3", + "styles": { + "website": "styles/website.css" + }, + "pluginsConfig": { + "theme-default": { + "showLevel": true + }, + "git-author": { + "position": "bottom", + "modifyTpl": "Last modified by {user} {timeStamp}", + "createTpl": "Created by {user} {timeStamp}", + "timeStampFormat": "YYYY-MM-DD HH:mm:ss" + } + } +} diff --git a/gri_getty/cropping_tools.md b/gri_getty/cropping_tools.md new file mode 100644 index 00000000..47e84be4 --- /dev/null +++ b/gri_getty/cropping_tools.md @@ -0,0 +1,11 @@ +# Cropping tools + +For this part of the workshop we will be diving into the details of the Image API. This is a specification which allows zooming into high quality images but can also be used with certain tools to create cropped images. We are going to use the following tool: + +https://iiifimage.link + +You can follow along with your own image from the previous step but you can also use the following examples: + + * Rossetta image: https://rosettaapp.getty.edu/iiif/2/FL9931118.jpg/info.json + * 12 sunsets image: https://media.getty.edu/iiif/image/14bd1507-c4b0-48d4-b489-411c4d672105/info.json + * Digital Florentine Codex: https://media.getty.edu/iiif/image/d5472c67-e070-4022-afb0-3e2c7b97d16a \ No newline at end of file diff --git a/gri_getty/day-one b/gri_getty/day-one new file mode 120000 index 00000000..e18512dd --- /dev/null +++ b/gri_getty/day-one @@ -0,0 +1 @@ +../iiif-online-workshop/day-one \ No newline at end of file diff --git a/gri_getty/demos.md b/gri_getty/demos.md new file mode 100644 index 00000000..9e4a2417 --- /dev/null +++ b/gri_getty/demos.md @@ -0,0 +1,39 @@ +# Project demos + +We've now completed the course and would be interested in seeing the demos you've been working on. + +## Slack channels + +Join the [IIIF slack](http://bit.ly/iiif-slack): + + * general - general discussion and announcements + * beginner - beginner questions lots of people to help + * iiif-in-the-classroom - ideas for IIIF in the classroom + * curators_of_awesome - become a curator of awesome by helping to curate: https://github.com/IIIF/awesome-iiif + * mirador - ask questions and see the latest developments with Mirador + * technical - ask difficult technical questions :-) + +## Zoom calls +Community Calls https://iiif.io/community/call/ + +## Community groups +See all IIIF calls on the IIIF Calendar: https://iiif.io/community/ + +Community groups: + * [3D](https://iiif.io/community/groups/3d) + * [A/V](https://iiif.io/community/groups/av) + * [Design](https://iiif.io/community/groups/D4H) + * [Maps](https://iiif.io/community/groups/maps) + * [Museums](https://iiif.io/community/groups/museums) + * [Outreach](https://iiif.io/community/groups/outreach) + +Technical Groups + * [3D](https://iiif.io/community/groups/3d/tsg/) + * [Authentication](https://iiif.io/community/groups/auth-tsg) + * [Content Search](https://iiif.io/community/groups/content-search-tsg) + + +## Stay informed + + * Join the [monthly newsletter](https://iiif.io/newsletter/) + * Join the IIIF Discuss [email list](https://groups.google.com/forum/#!forum/iiif-discuss) diff --git a/gri_getty/exhibit b/gri_getty/exhibit new file mode 120000 index 00000000..eff5668b --- /dev/null +++ b/gri_getty/exhibit @@ -0,0 +1 @@ +../europeana/exhibit \ No newline at end of file diff --git a/gri_getty/geo-locating-map.md b/gri_getty/geo-locating-map.md new file mode 100644 index 00000000..2dc0a2e4 --- /dev/null +++ b/gri_getty/geo-locating-map.md @@ -0,0 +1,13 @@ +# Geo-locating a map + +While looking through the GRI collection I noticed a number of Maps which is a good excuse to demonstrate one of the new tools available for IIIF maps. For this example I am going to use this map of Paris: + +https://rosettaapp.getty.edu/delivery/DeliveryManagerServlet?dps_pid=IE2799092&dps_file=FL2799094&md_pane=hide + +![Paris map](imgs/paris_map.png) + +Using the detektIIIF tool discussed previously we can use this map in the following Geo-referencing tool: + +https://editor.allmaps.org/ + +![All maps import](imgs/all_maps_import.png) diff --git a/gri_getty/gri_collections.md b/gri_getty/gri_collections.md new file mode 100644 index 00000000..e73d87a7 --- /dev/null +++ b/gri_getty/gri_collections.md @@ -0,0 +1,32 @@ +# Looking at other GRI collections + +We will now have a look at the collections that are available from Rosseta and can be accessed from the following URL: + + * [Getty Search Gateway](https://search.getty.edu/gateway/search?q=maps&cat=source&sources=%22GRI%20Digital%20Collections%22&highlights=%22Open%20Content%20Images%22&rows=50&srt=&dir=s&dsp=0&img=0&pg=1) + +When you get to an item page you can View the IIIF image in on of the basic IIIF viewers called [Openseadragon](https://openseadragon.github.io/). For example: + +![Screenshot of rossetta](imgs/rossetta.png) + +https://rosettaapp.getty.edu/delivery/DeliveryManagerServlet?dps_pid=IE9931113 + +Although this is a photo album with many pages it doesn't seem to have an associated manifest. It maybe possible to enable this and there are some instructions [here](https://knowledge.exlibrisgroup.com/Rosetta/Training/What%27s_New_Videos/Rosetta_5-3/IIIF_Image_Viewing). + +Without access to the IIIF manifest it makes it very difficult for end users to re-use this content. One solution is to use a community developed tool called [DetektIIIF](https://seige.digital/en/detektiiif/). This was developed by a IIIF community member; Leander Seige to make it easier to find manifests. It can be installed in either Firefox or chrome. If you install the plugin then refresh the page you should be able to access it in the extensions part of the browser: + +![detektIIIF](imgs/detekt_item.png) + +In this example it shows a red 1 to show that it has found an IIIF item. If you then navigate to a different image and select the detekt extension again and click to open the extension you will now see: + +![detektIIIF image](imgs/detekt_image.png) + +You will notice that no Manifests were found but it has found some IIIF images. If you click the Copy URL button you should be ready for the next stage of cropping the image. The URL will look something like: + +https://rosettaapp.getty.edu/iiif/2/FL9931118.jpg/info.json + + +For Manifests like [The Florentine Codex](https://dfc-django-backend.getty.digirati.io/iiif/iiif/manifest/f75b53f9-7295-41f3-9299-6bbe04685c8b/) or the 12 Sunset photographs you can use the following tool to get the Image ID: + +https://glenrobson.github.io/CanvasFinder/ + + diff --git a/gri_getty/imgs/IIIF-D4H-UX-Research-Findings.jpg b/gri_getty/imgs/IIIF-D4H-UX-Research-Findings.jpg new file mode 100644 index 00000000..1a1e4232 Binary files /dev/null and b/gri_getty/imgs/IIIF-D4H-UX-Research-Findings.jpg differ diff --git a/gri_getty/imgs/all_maps_import.png b/gri_getty/imgs/all_maps_import.png new file mode 100644 index 00000000..fe4aadb6 Binary files /dev/null and b/gri_getty/imgs/all_maps_import.png differ diff --git a/gri_getty/imgs/detekt_image.png b/gri_getty/imgs/detekt_image.png new file mode 100644 index 00000000..4ca949bd Binary files /dev/null and b/gri_getty/imgs/detekt_image.png differ diff --git a/gri_getty/imgs/detekt_item.png b/gri_getty/imgs/detekt_item.png new file mode 100644 index 00000000..28f52da3 Binary files /dev/null and b/gri_getty/imgs/detekt_item.png differ diff --git a/gri_getty/imgs/paris_map.png b/gri_getty/imgs/paris_map.png new file mode 100644 index 00000000..66c46810 Binary files /dev/null and b/gri_getty/imgs/paris_map.png differ diff --git a/gri_getty/imgs/rossetta.png b/gri_getty/imgs/rossetta.png new file mode 100644 index 00000000..0db3a6b6 Binary files /dev/null and b/gri_getty/imgs/rossetta.png differ diff --git a/gri_getty/introduction.md b/gri_getty/introduction.md new file mode 100644 index 00000000..13d63420 --- /dev/null +++ b/gri_getty/introduction.md @@ -0,0 +1,74 @@ +# Introductions + +## Getty involvement with IIIF +IIIF is a set of standards that provide access to high quality images and audio-visual content in a method that allows users to choose different viewers and tools to interact with cultural heritage content. It has been widely adopted by world leading organisations including the J. Paul Getty Trust. It provides a basis for users to gather digital content and enables research by comparing and annotating content. The IIIF standards are developed by an international open community and are supported by a consortium of institutions including the Getty. + +The Getty has been involved with the development of IIIF since the very beginning and was instrumental in the addition of audio-visual support to IIIF. It was also one of the early members of the [IIIF Consortium](https://iiif.io/community/consortium/). Members of staff at the Getty have been active participants in the community providing advice on implementation and also funding tools that benefit both the Getty and the wider IIIF community. A highlight of some of IIIF related work the Getty has presented on are below: + + * [2016 Edward Ruscha photographs of Los Angeles streets](https://12sunsets.getty.edu) + * [2017 press release for 30,000 artworks](https://www.getty.edu/news/30000-getty-museum-images-published-iiif/) + * [Quire](https://quire.getty.edu/) - a widely used publication system + * [Animal Crossing Art Generator](https://experiments.getty.edu/ac-art-generator) + * [iiif-for-dolls](https://iiif-for-dolls.davidnewbury.com/) - a thought provoking app on relating physical size to digital images. + * [Digital Florentine Codex](https://florentinecodex.getty.edu/) - mentioned at the 2019 DHSI training + +# How users make use of IIIF + +One of the IIIF Community groups has done some research on how people use IIIF items and created the following groups of users: + +![D4H Personas Diagram](imgs/IIIF-D4H-UX-Research-Findings.jpg) + +From the [D4H Community Group Research Findings presentation](https://docs.google.com/presentation/d/1JhhjJdGIAZjYm0j9iNig7-YT2LJqFgVgThsoS59jAV0/edit#slide=id.gdbd80f572f_0_95) + +The groups are defined as: + +### Gatherers + * **EXPERTISE IN IIIF:** Does not use IIIF. May be aware or unaware that it exists. + * **MOTIVATION:** The materials relevant to their research; technology agnostic. + * **TOOLBOX:** Use tools like Zotero, Google Drive, Dropbox and MS Office to manage digital items. + * **PEERS:** Involved in their own research communities. + +Use cases include: + * Making use of your [catalogue](https://search.getty.edu/gateway/landing) to find digital stuff + * Browsing a project website like: + * [Digital Florentine Codex](https://florentinecodex.getty.edu/) + * [Edward Ruscha photographs of Los Angeles streets](https://www.getty.edu/research/collections/collection/100071) + * Storing references in Zotero or Spreadsheets + * Downloading images + +### Adopters + * **EXPERTISE IN IIIF:** Utilize IIIF-compliant materials for research projects. + * **MOTIVATION:** Available technology and materials relevant to their research. + * **TOOLBOX:** Use tools like [FromThePage](https://fromthepage.com/), [Wordpress](https://www.vam.ac.uk/blog/digital/iiif-wordpress-and-shakespeare-too), [Omeka](https://omeka.org/s/), and other out-of-the-box solutions for research projects. + * **PEERS:** Involved in their own research communities more than IIIF community. + +Use cases include: + * Looking for IIIF material. + * Using multiple collections with tools like [Mirador](https://projectmirador.org/) + * Will use tools like [Exhibit](https://exhibit.so/) to put together exhibitions/presentations. + * This is where this course will target. + +### Educators + * **EXPERTISE IN IIIF:** Understand how to use IIIF tools for viewing, annotation, and transcription. + * **MOTIVATION:** Teach people about the possibilities of IIIF. + * **TOOLBOX:** Use tools like viewers in teaching. + * **PEERS:** May be involved with IIIF community. + +Use cases include: + * Similar tools to above + * Will use annotation tools we will cover on Thursday + * Will use tools like [Recogito](https://recogito.pelagios.org/) which is a hosted annotation tool for teaching + * Use AV tools like [Timeliner](https://cultural-heritage.digirati.com/our-work/timeliner/) or the [Europeana Media Player](https://video-editor.eu/). + * Can setup crowdsourcing projects + * We held a community call on Teaching and Learning with IIIF. Notes [here](https://docs.google.com/document/d/1viF1tgssZSTTiMTPy1sY3iTxgAKfByt1eM9MrCQEfF4/edit) and video [here](https://www.youtube.com/watch?v=ILrmRxPcK-o). + +### Builders + * **EXPERTISE IN IIIF:** Possess a deep, technical knowledge. + * **MOTIVATION:** Make digital content from their institution available. + * **TOOLBOX:** Use tools like Github, code editors, open source tools. + * **PEERS:** Members of the IIIF community. + +Use cases: + * Create Manifests and IIIF Images either programmatically or through tools like Manifest Editors + * They know about the IIIF tools available and where to look for them ([awesome-iiif](https://github.com/IIIF/awesome-iiif)) + diff --git a/gri_getty/styles b/gri_getty/styles new file mode 120000 index 00000000..6692a04a --- /dev/null +++ b/gri_getty/styles @@ -0,0 +1 @@ +../iiif-online-workshop/styles \ No newline at end of file diff --git a/humboldt_university/README.md b/humboldt_university/README.md new file mode 100644 index 00000000..b18fb707 --- /dev/null +++ b/humboldt_university/README.md @@ -0,0 +1,16 @@ +# Humboldt-Universität Training + +The training will be provided online using Zoom with practical tasks associated with the training. It is expected that the training will be given to roughly 5 people. + + * Introduction to IIIF - 1:10 + * Basics of IIIF functionality + * Finding manifests + * Using Mirador & Universal Viewer + * Making changes to Manifests - e.g. rights + * Open Q&A + * Break - 20mins + * Looking into Aggregation - 1:10 + * Europeana example + * Manuscriptorium + * ARGO Maps + * IIIF discovery diff --git a/humboldt_university/SUMMARY.md b/humboldt_university/SUMMARY.md new file mode 100644 index 00000000..7f04509e --- /dev/null +++ b/humboldt_university/SUMMARY.md @@ -0,0 +1,9 @@ +# Summary + +- [Overview](README.md) +- [What is IIIF](part1/whatisiiif.md) +- [Exercise: Finding Census Manifests](census.md) +- [Exercise: Finding IIIF Manifests](part1/guides.md) +- [Deep dive into the Census Manifests](census-manifests.md) +- [A look into Aggregation](aggregation.md) +- [Extra: Create an Exhibit](exhibit/exhibit.md) \ No newline at end of file diff --git a/humboldt_university/aggregation.md b/humboldt_university/aggregation.md new file mode 100644 index 00000000..138d5b63 --- /dev/null +++ b/humboldt_university/aggregation.md @@ -0,0 +1,36 @@ +# Aggregation + +Aggregation is the action of bringing together a number of digital objects from different locations into one Website. This allows you to gather together related content into a single portal and potentially develop specific tools for that content. There are a number of organizations which have done this and integrated IIIF. The advantage of doing integration with IIIF is that you don't need to copy the Image files but instead can harvest the IIIF Manifests and embed them on your site. + +There are three examples of aggregation included in this guide. + +## Example 1 - Manuscriptorium +https://new.manuscriptorium.com/hub/catalog/default/dashboard?lang=en + +Manuscriptorium seeks to aggregate the old written and documentary heritage (medieval and early modern manuscripts, incunabula, and early printed books until c. 1800) of European civilisation in a united user interface and present it to end users as well as have other sources use it (Manuscriptorium is, for example, a domain aggregator for Europeana). In addition to being an extensive digital library, Manuscriptorium has the ambition to become a virtual research environment for working with historical documents and collections by creating digital tools adapted as modules in a digital network. As a result, user data can be created in the personalised environment of an individual account and published in correlation with the aggregated content (data and metadata). The ultimate goal is the full integration in the digital network environment with the use of data standards, digitised document indexes, and persistent addressing of both complex digital documents (manuscripts, books) and their partial objects (pages) or fragments (page details) where blockchainisation is an inspiration rather than big data. + +from https://new.manuscriptorium.com/en/about-us/ + +## Example 2 - Europeana example +https://www.europeana.eu/en/search?page=1&qf=collection%3Aindustrial&query=provider_aggregation_edm_isShownBy%3A%2Aiiif%2A&view=grid + + * A large scale aggregator + * Use a variety of methods to ingest content. Both IIIF Discovery and other technologies + +To find all 4 million IIIF items: https://www.europeana.eu/portal/en/search?q=provider_aggregation_edm_isShownBy%3A*iiif*&view=grid + +## Example 3 - ARGO Maps +https://www.argomaps.org/ + +This is a different type of aggregation focused on maps around the American Revolution. + + * Currently 16 partners + * Includes cross instution themes and stories + * Allows Georeferencing of Maps + * Allows you to explore through a map + +## Methods for aggregation + +Single item + +IIIF discovery and other aggregation standards diff --git a/humboldt_university/census-manifests.md b/humboldt_university/census-manifests.md new file mode 100644 index 00000000..8d64da3a --- /dev/null +++ b/humboldt_university/census-manifests.md @@ -0,0 +1,286 @@ +# Deep dive into Census Manifests + +In this section we are going to have a look at one of the easyDB manifests to see whats there and possible improvements. We will be using the following Manifest: + +https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/iiif/v3/manifest.json + +while doing this we will also have a look at the item in Mirador so we can see where the content comes from: + +https://projectmirador.org/embed/?iiif-content=https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/iiif/v3/manifest.json + +The first part we will look at is the top level of the manifest particularly the following sections: + +``` +{ + "@context": "http://iiif.io/api/presentation/3/context.json", + "id": "https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/iiif/v3/manifest.json", + "label": { }, + "metadata": [ ], + "provider": [ ], + "rendering": [ ], + "requiredStatement": {}, + "seeAlso": [ ], +``` + +## Label + +The label is the title of the item and you can see this prominently displayed in Mirador. In the example item it has the label of 'inv. 405 A v' and the language is set to US English: +``` +"label": { + "en-US": [ + "inv. 405 A v" + ] + }, +``` +## Metadata + +The [metadata section](https://iiif.io/api/presentation/3.0/#metadata) is an open list of metadata about the item. This is shown in the side panel of Mirador and should give the user enough context to understand what they are looking at if they open the Manifest in a viewer which isn't on your site. + +In the example Manifest there are a number of fields but we are going to focus on the first one 'Label Name'. In the metadata section you have a 'label' and a 'value' so for example 'author' maybe a label and the value could be 'Charles Dickens'. Both the label and the value can be translated into multiple languages. In the example below the label has both a English label and a German Label (but note the actual text 'Label Name' is in English for both cases). The value doesn't have a language associated with it so its label as `none`. + +The value contains HTML which is valid but not strictly necessary in this case and does lead to some strange formatting in Mirador. + +``` +metadata": [ + { + "label": { + "de-DE": [ + "Label Name" + ], + "en-US": [ + "Label Name" + ] + }, + "value": { + "none": [ + "\n inv. 405 A v" + ] + } + }, +``` +The value of Creator in particular would be better formatted as separate fields. Currently it has: + +``` + + + + Creation Date + + + + + + Date + + post 1504-ante 1536 + + + + Earliest Date + + 1505-01-01 00:00:00 + + + + Latest Date + + 1536-01-05 00:00:00 + + + + + + + Actors Involved in Creation + + + + + + Actor + + Peruzzi, Baldassare + + + + Actor Role + + artist/author + + + + + +``` + +For example: +``` + { + "label": { + "en-US": [ + "Creation Date" + ] + }, + "value": { + "none": [ + "post 1504-ante 1536" + ] + } + }, +``` + +## provider + +This is where you can link back to the institution that is publishing the resource. In this case the Census website. Unfortunately this property isn't well supported by Viewers currently (see: https://iiif.io/api/cookbook/recipe/0234-provider/) + +``` +"provider": [ + { + "id": "https://database.census.de", + "label": { + "de-DE": [ + "" + ], + "en-US": [ + "Census Database" + ] + }, + "logo": [ + { + "format": "image/jpeg", + "height": 720, + "id": "https://database.census.de/api/v1/eas/download/215665/870edd2273b3393e9aaea88baeb6b077fb3bfa32472a88218fcfb04f870d5984/original.jpg", + "service": { + "id": "https://database.census.de/api/v1/eas/iiif/215665/870edd2273b3393e9aaea88baeb6b077fb3bfa32472a88218fcfb04f870d5984/original.jpg", + "profile": "level1", + "type": "ImageService3" + }, + "type": "Image", + "width": 586 + } + ], + "type": "Agent" + } + +], +``` + +## rendering + +Rendering is where you advertise different versions of the resource you are currently looking at. Typically these are things like a PDF version of a resource. In this manifest there is a HTML version of the resource. Note if you are linking back to the conical location of the item you would use a `homepage` property. + +``` +rendering": [ + { + "format": "text/html", + "id": "https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/html", + "label": { + "da-DK": [ + "HTML representation" + ], + "de-DE": [ + "HTML Representation" + ], + "en-US": [ + "HTML representation" + ], + "fi-FI": [ + "HTML-esitys" + ], + "fr-FR": [ + "Représentation HTML" + ], + "it-IT": [ + "Rappresentazione HTML" + ], + "ru-RU": [ + "" + ], + "sv-SE": [ + "HTML representation" + ], + "uz-UZ": [ + "" + ] + }, + "type": "Text" + } +], +``` + +## requiredStatement +In the example this is empty but this is where you would put attribution or mention where the material comes from. You can see a populated version of this rights statement in this [cookbook recipe](https://iiif.io/api/cookbook/recipe/0008-rights/). + +``` +requiredStatement": { + "label": { + "de-DE": [ + "" + ], + "en-US": [ + "" + ] + }, + "value": { + "de-DE": [ + "" + ], + "en-US": [ + "" + ] + } +}, +``` + +## seeAlso + +See Also is where you can link out to Machine Readable metadata about the item. This is particularly useful for aggregators like Europeana which requires structured metadata to be able to accept items into their collection. + +In the example manifest it links out to some easydb XML metadata. + +``` +seeAlso": [ + { + "id": "https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/xml_easydb", + "type": "Dataset", + "format": "text/xml", + "label": { + "da-DK": [ + "XML (easydb)" + ], + "de-DE": [ + "XML (easydb)" + ], + "en-US": [ + "XML (easydb)" + ], + "fi-FI": [ + "XML (easydb)" + ], + "fr-FR": [ + "XML (easydb)" + ], + "it-IT": [ + "XML (easydb)" + ], + "ru-RU": [ + "" + ], + "sv-SE": [ + "XML (easydb)" + ], + "uz-UZ": [ + "" + ] + } + } +], +``` + +## Other sections + +The other parts of the manifest are the `items` where the different pages of the manuscript live and the `structures` element which is where you setup a table of contents. You can see the following table of contents for a Vatican manifest: + +https://projectmirador.org/embed/?iiif-content=https://digi.vatlib.it/iiif/MSS_Pal.lat.957/manifest.json + +The table of contents for the easyDb manifest looks a but confused and doesn't work in mirador. It looks like the metadata has been incorrectly copied into the Structures element. \ No newline at end of file diff --git a/humboldt_university/census.md b/humboldt_university/census.md new file mode 100644 index 00000000..dbfdd71e --- /dev/null +++ b/humboldt_university/census.md @@ -0,0 +1,60 @@ +# Finding Census Manifests + +The Census database currently uses EasyDB and it appears that it provides access to IIIF Manifests even though this isn't publicized in the site. What we are going to do is: + + * Find an item in the database + * Work out the Manifest URL + * Open this Manifest in a IIIF Viewer called Mirador + +This could replicate a researchers workflow assuming there was an easier way to get access to the Manifest URL and would allow them to perform the following: + + * Gather together material from multiple collections and view it side by side in Mirador + * Import the Manifests into an Annotation system + * Gather a collection of material to work AI or Machine Learning workflows. + +## Step 1: Find an item in the database + +Navigate to the Census database: + +[https://database.census.de/](https://database.census.de/) + +Select an item which has a Image associated with it like the follow: + +![Database record](img/item_info.png) +[Example Record](https://database.census.de/#/detail/12017636) + +## Step 2: Work out the Manifest URL + +The Manifest URL for easyDB looks like the following: + +https://database.census.de/api/v1/objects/uuid/cc04f6bd-9e97-4c3f-92eb-f64bf2663cd1/format/iiif/v3/manifest.json + +Where the part in bold (cc04f6bd-9e97-4c3f-92eb-f64bf2663cd1) is the unique identifier for the item. We can find this identifier by scrolling to the bottom of the information window for the item. See the highlighted part in the image below: + +[uuid example](img/uuid.png) + +In this example the uuid is '4b3714d5-6112-47b3-ba6e-97f816e3fa41' so the Manifest is available at: + +https://database.census.de/api/v1/objects/uuid/4b3714d5-6112-47b3-ba6e-97f816e3fa41/format/iiif/v3/manifest.json + +Note some items seem to throw an error so if you get into trouble you can use the manifest above for the next step. + +## Step 3: Open this Manifest in a IIIF Viewer Called Mirador + +Now we have a Manifest we can open it up in Mirador + +Navigate to [https://projectmirador.org/](https://projectmirador.org/) and click the __Try a Live Demo__ button. Once Mirador opens close the two demo objects by clicking the two crosses highlighted in the screen shot below: + +![Mirador close window screenshot](part1/img/mirador_close.png) + +Then click the Start here button on the top left. + +![Mirador start screenshot](part1/img/mirador-start.png) + +Then click the add resource button at the bottom right: + +![Mirador add Manifest button](part1/img/mirador-add-resource.png) + +Finally you can paste your URL to your manifest and click Add and Mirador should open your Manifest. + +![Mirador add Manifest](part1/img/mirador-add-manifest.png) \ No newline at end of file diff --git a/humboldt_university/exhibit b/humboldt_university/exhibit new file mode 120000 index 00000000..921edccd --- /dev/null +++ b/humboldt_university/exhibit @@ -0,0 +1 @@ +../annotations/exhibit \ No newline at end of file diff --git a/humboldt_university/img/item_info.png b/humboldt_university/img/item_info.png new file mode 100644 index 00000000..73d5d17b Binary files /dev/null and b/humboldt_university/img/item_info.png differ diff --git a/humboldt_university/img/uuid.png b/humboldt_university/img/uuid.png new file mode 100644 index 00000000..7888500c Binary files /dev/null and b/humboldt_university/img/uuid.png differ diff --git a/humboldt_university/part1 b/humboldt_university/part1 new file mode 120000 index 00000000..e18512dd --- /dev/null +++ b/humboldt_university/part1 @@ -0,0 +1 @@ +../iiif-online-workshop/day-one \ No newline at end of file diff --git a/iiif-1-day-workshop/book.json b/iiif-1-day-workshop/book.json index f590ab2d..876d5d60 100644 --- a/iiif-1-day-workshop/book.json +++ b/iiif-1-day-workshop/book.json @@ -5,8 +5,6 @@ "theme-default", "toggle-chapters", "git-author", - "-highlight", - "sunlight-highlighter", "toggle-chapters" ], "gitbook": "3.2.3", diff --git a/iiif-5-day-workshop/README.md b/iiif-5-day-workshop/README.md deleted file mode 100644 index c0e4b839..00000000 --- a/iiif-5-day-workshop/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Introduction - -> Access to image-based resources is fundamental to research, scholarship and the transmission of cultural knowledge. Digital images are a container for much of the information content in the Web-based delivery of images, books, newspapers, manuscripts, maps, scrolls, single sheet collections, and archival materials. Yet much of the Internet’s image-based resources are locked up in silos, with access restricted to bespoke, locally built applications. A growing community of the world’s leading research libraries and image repositories have embarked on an effort to collaboratively produce an interoperable technology and community framework for image delivery. IIIF (International Image Interoperability Framework) has the following goals: To give scholars an unprecedented level of uniform and rich access to image-based resources hosted around the world, To define a set of common application programming interfaces that support interoperability between image repositories, and To develop, cultivate and document shared technologies, such as image servers and web clients, that provide a world-class user experience in viewing, comparing, manipulating and annotating images. - (http://iiif.io). - - This course will introduce students to the basic concepts and technologies that make IIIF possible, allowing for guided, hands-on experience in installing servers and clients that support IIIF, and utilizing the advanced functionality that IIIF provides for interactive image-based research, such as annotation. diff --git a/iiif-5-day-workshop/SUMMARY.md b/iiif-5-day-workshop/SUMMARY.md deleted file mode 100644 index 8ee055a8..00000000 --- a/iiif-5-day-workshop/SUMMARY.md +++ /dev/null @@ -1,54 +0,0 @@ -# Summary - -- [Introduction](README.md) - -## Day One -- [Introduction](day-one/README.md) -- [IIIF Introduction](day-one/iiif-introduction.md) -- [Image API](day-one/image-api.md) -- [Getting started with the Image API](day-one/getting-started-with-the-image-api.md) - - [IIIF Hosting software as a service](day-one/iiif-hosting-saas.md) - - [Setting up Cantaloupe as an image server](day-one/setting-up-cantaloupe.md) - - [Configuring Canataloupe](day-one/configuring-cantaloupe.md) - - [Level 0 hosting with GitHub pages](day-one/level0-github-hosting.md) - - [Creating a basic image viewer](day-one/creating-a-basic-image-viewer.md) - -## Day Two -- [Introduction](day-two/README.md) -- [Presentation API Deep Dive](day-two/0-presentation-api-introduction.md) - - [Anatomy of a Basic Manifest](day-two/1-anatomy-of-a-basic-manifest.md) - - [Building a Group Manifest](day-two/2-activity-group-manifest.md) - - [Building an Individual Manifest](day-two/3-activity-create-your-own-manifest.md) - - [Serving Your Manifest](day-two/4-serving-your-manifest.md) - - [Viewing Your Manifest](day-two/5-viewing-your-manifest-in-a-viewer.md) -- [Building a Simple Gallery Viewer](day-two/6-building-a-gallery-viewer-intro.md) - - [Building a Simple Gallery Viewer From Scratch](day-two/7-building-a-gallery-viewer.md) - - [Adding Open Seadragon](day-two/8-building-a-gallery-viewer-with-opensea-dragon.md) - - [Adding Leaflet](day-two/9-building-a-gallery-viewer-with-leaflet.md) - -## Day Three -- [Introduction](day-three/README.md) -- [Annotations, AnnotationLists](day-three/annotations-and-annotation-lists.md) - - [Annotations Exercise](day-three/exercise.md) - - [Annotating with Mirador](day-three/annotations-exercises.md) - - [Annotating Stores](day-three/annotations-stores.md) - - [Annotating Stores - Results](day-three/annotations-stores-results.md) - - [Annotating Stores - Do it yourself](day-three/annotations-stores-install.md) - - [Annotation Stores - download](day-three/annotation-store-download.md) - - [Advanced annotation presentation](day-three/advanced-annotations.md) -- [Collections](day-three/collections.md) -- [Ranges](day-three/ranges.md) - - -## Day Four -- [Introduction](day-four/README.md) - - -- [IIIF + AI](day-four/iiif-and-ai.md) -- [IIIF + A/V](day-four/iiif-and-av.md) - - - - -## Day Five -- [Introduction](day-five/README.md) diff --git a/iiif-5-day-workshop/book.json b/iiif-5-day-workshop/book.json deleted file mode 100644 index f590ab2d..00000000 --- a/iiif-5-day-workshop/book.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "title": "IIIF 5 Day Workshop", - "plugins": [ - "include", - "theme-default", - "toggle-chapters", - "git-author", - "-highlight", - "sunlight-highlighter", - "toggle-chapters" - ], - "gitbook": "3.2.3", - "styles": { - }, - "pluginsConfig": { - "theme-default": { - "showLevel": true - }, - "git-author": { - "position": "bottom", - "modifyTpl": "Last modified by {user} {timeStamp}", - "createTpl": "Created by {user} {timeStamp}", - "timeStampFormat": "YYYY-MM-DD HH:mm:ss" - } - } -} diff --git a/iiif-5-day-workshop/day-five/README.md b/iiif-5-day-workshop/day-five/README.md deleted file mode 100644 index b683f533..00000000 --- a/iiif-5-day-workshop/day-five/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Day Five - -## Project Presentations - -## Closing Discussion diff --git a/iiif-5-day-workshop/day-four/README.md b/iiif-5-day-workshop/day-four/README.md deleted file mode 100644 index 897c6050..00000000 --- a/iiif-5-day-workshop/day-four/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Day Four - -## Mirador 3 - -## IIIF for AI/Deep Learning - -## It's not just for images anymore: IIIF + A/V - -## Demos of IIIF and Integration with DH Tools - -### IIIF and Omeka - -### IIIF and Islandora/Drupal - -## Work Session (Build Something Cool!) diff --git a/iiif-5-day-workshop/day-four/iiif-and-ai.md b/iiif-5-day-workshop/day-four/iiif-and-ai.md deleted file mode 100644 index b8c68452..00000000 --- a/iiif-5-day-workshop/day-four/iiif-and-ai.md +++ /dev/null @@ -1,38 +0,0 @@ -# IIIF and AI/Machine Learning - -## Automatic detection and highlighting of handwritten annotations in printed books - -For this case study, we'll get some hands-on experience with experimental code developed by librarians, students and staff at the UCLA Digital Library [Collections Lab](https://collectionslab.github.io/) to detect handwritten marginal annotations in books from the recently digitized [Early Modern Annotated Books collection](https://calisphere.org/collections/26771/) at UCLA's William Andrews Clark Memorial Library. - -![image](../images/omniscribe.png) - -Full disclosure: the original training set of tagged handwritten annotations was crowd-sourced using [this Zooniverse site](https://www.zooniverse.org/projects/kirschbombe/book-annotation-classification), which does not use a IIIF-based viewer/annotation system! - -The automated detection system, however, which is built upon a "Mask Region-based Convolutional Neural Network" (MRCNN) model trained on the crowd-sourced data, has been designed to access new book page images via IIIF image API services and to produce manifests with annotation lists identifying the detected annotations, which can be opened in a IIIF viewer. - -The code and documentation for this system, called Omniscribe, is [on Github](https://github.com/collectionslab/omniscribe). - -We'll run this code on some sample manifests. Because the software requires a fairly complex system environment, including Tensorflow, Google's open-source deep-learning Python libraries, and also runs faster on systems with special graphics-processing (GPU) or "Tensor processing" (TPU) hardware, we won't bother to install the software on our own machines. Rather, we'll set it up and run it within a cloud-based computational "notebook" environment from Google's [Colaboratory](https://colab.research.google.com) ("Colab") service, which also provides access to cloud-based TPUs. - -The notebook is available at this link: -https://colab.research.google.com/drive/10llFSdKa8uK3PVTNwHjxV80mleQ5ZXk2 - -As a group, we'll walk through the steps necessary to access the notebook and to run a copy of it in our own Google accounts. Notebooks like these are designed to incorporate documentation as well as code, so just by reading the inline instructions in the notebook, you should be able to follow the steps needed to run the Omniscribe software on a IIIF manifest and then to view the detected annotations in a local instance of Mirador - -Please use one of the following manifests as your source of input page images when running the Omniscribe "inferencer" in the notebook: -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_BF1681A441713_11-20.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_BF1681A441713_21-30.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_BF1681A441713_31-40.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_BF1681A441713_41-50.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_BF1681A441713_51-60.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_SB322S53_11-20.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_SB322S53_21-30.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_SB322S53_31-40.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_SB322S53_41-50.json -- https://marinus.library.ucla.edu/iiif/annotated/uclaclark_SB322S53_51-60.json - -## Object detection in Edo-period Japanese illustrations - -This project was inspired by the IIIF-based [Collection of Facial Expressions](http://codh.rois.ac.jp/face/iiif-curation-finder/) "curation viewer" project at the [Japanese Center for Open Data in the Humanities](http://codh.rois.ac.jp/), a joint project of the National Institute of Informatics and the Institute of Statistical Mathematics. - -Another impressive IIIF + AI-based project from CODH: the [Hentaigana Image Recognition](http://npn-2sc1815j.appspot.com/hentaigana/?pages=200003067&pos=5) interface. \ No newline at end of file diff --git a/iiif-5-day-workshop/day-four/iiif-and-av.md b/iiif-5-day-workshop/day-four/iiif-and-av.md deleted file mode 100644 index 41f27310..00000000 --- a/iiif-5-day-workshop/day-four/iiif-and-av.md +++ /dev/null @@ -1,11 +0,0 @@ -# IIIF A/V - -The IIIF Community has been working on adding support to IIIF for Audio/Visual resources. This is now possible in Version 3.0 of the IIIF API. I am going to go through the following presentation on [google slides](https://docs.google.com/presentation/d/1r-0Ffu8hbKGZdzP5hmYt1EZWu8Dl0AzSrTUTtRgm4c4/edit?usp=sharing). - -The links I am going to show are: - - * [Tom Crane fire example](https://tomcrane.github.io/fire/) - * [Universal Viewer A/V examples](https://universalviewer.io/examples/#?c=&m=&s=&cv=&manifest=https%3A%2F%2Fiiif-commons.github.io%2Fiiif-av-component%2Fexamples%2Fdata%2Fiiif%2Flunchroom-manners.json) - * [Glenn Gould Presentation](http://www.kanzaki.com/works/2016/pub/image-annotator?u=/works/2018/test/goldberg-subcanvas.json) - * [Distributed Digital Music Archives - McGill University](https://ddmal.github.io/IIIF-AV-player/) - * [Example A/V Manifest](https://iiif.gdmrdigital.com/nlw/LLOYD_GEORGE_FARMING-mp4.json) diff --git a/iiif-5-day-workshop/day-four/iiif-and-dh-platforms.md b/iiif-5-day-workshop/day-four/iiif-and-dh-platforms.md deleted file mode 100644 index 9301dbbc..00000000 --- a/iiif-5-day-workshop/day-four/iiif-and-dh-platforms.md +++ /dev/null @@ -1,5 +0,0 @@ -# Integrating IIIF into other platforms and frameworks - -## Digital Analysis of Syriac Handwriting (DASH) -- a work in progress: -- Demo with Mirador 3: https://sul-cidr.github.io/scriptchart/viewer/ -- Demo with Mirador 2: https://syriac.reclaim.hosting/scriptchart/viewer/ \ No newline at end of file diff --git a/iiif-5-day-workshop/day-four/islandora-drupal.md b/iiif-5-day-workshop/day-four/islandora-drupal.md deleted file mode 100644 index 0c42794c..00000000 --- a/iiif-5-day-workshop/day-four/islandora-drupal.md +++ /dev/null @@ -1,31 +0,0 @@ -# Islandora/Drupal - -Islandora is an open-source software framework designed to help institutions and organizations and their audiences collaboratively manage, and discover digital assets using a best-practices framework. Islandora makes use of Drupal, a scalable, open platform for web content management and digital experiences, as the presentation layer for collections. - -Similar to Omeka, both Islandora and Drupal have a module-based structure that allows users to customize their site depending on need. At present, there are over 40,000 Drupal modules that touch on a range of needs such as interface design, analytics, metadata and libraries. - -See here for a full list of Drupal moduel see: https://www.drupal.org/project/project_module?page=3 - -Islandora also has a large number of modules and can be seen here: https://github.com/Islandora-Labs/islandora_awesome . - - -At the University of Toronto, Drupal is used heavily for websites and Islandora for digital collections. As we’ve moved towards implementing IIIF library-wide it became necessary to ensure Islandor/Drupal could work with IIIF in some capacity. - -### Modules -Mirador Image viewer module (UofT): -
  • View large images, books, collections etc. in Mirador.
  • -
  • Pan and zoom capabilities + image manipulation
  • -
  • Point to a datastream in Fedora or url from a iiif server
  • -
  • Viewer for Drupal alone built by Zyxware Technologies
  • -

    -IIIF manifest generator module (UofT): -
  • Generate manifests from images and metadata
  • -
  • Save as a datastream in Fedora
  • -
  • Other example from Yale (presentation API only)
  • - -### Examples -University of Toronto Digital Collections - -Art Gallery of Ontario, Small Wonders Exhibit (using similar custom modules) - -The Life of Buddha project (Yale module) \ No newline at end of file diff --git a/iiif-5-day-workshop/day-four/omeka.md b/iiif-5-day-workshop/day-four/omeka.md deleted file mode 100644 index c027c479..00000000 --- a/iiif-5-day-workshop/day-four/omeka.md +++ /dev/null @@ -1,41 +0,0 @@ -# Omeka - -

    - “Omeka provides open-source web publishing platforms for sharing digital collections and creating media-rich online exhibits” -

    omeka.org -

    - - -Omeka is very popular in the heritage sector to create digital exhibits and collections, in digital humanities classrooms to explore digital accessibility, metadata and digital scholarship, and in research as a means to manage data. - -You can see some sites using Omeka here: http://omeka.org/classic/showcase/ - -At the University of Toronto we have built a series of plugins to integrate IIIF with Omeka in a way that also interacted with other popular plugins (ex. Exhibits, Neatline, Tags etc.). Our user group, mostly medievalists, indicated they want to make use of IIIF viewer functionality - pan, zoom, colour change etc. - as well as annotation. - - -### Plugin: IIIF Toolkit - -Scenario: I want to use IIIF content from mine or other institutions to annotate, present, edit and maintain in a way that is useful to me and my research. - -IIIF Toolkit allows users to ingest IIIF content, view content in the Mirador image viewer, annotated images, re-order/edit canvases and use them in online exhibits along with non-IIIF material. In addition, the plugin allows the Exhibits plugin to reference external manifests without ingesting them into Omeka at all. - -Demo: https://www.youtube.com/watch?v=wudps0cMhCk - -### Plugin: Batch Upload - -Scenario: I have DIY images (jpeg/tiff/png) that I want to store and manage somewhere. I also want to be able to use a IIIF viewer and annotate my images. - -The Batch Uploader allows users to upload image files and metadata from their desktop in bulk into Omeka. At the same time, the plugin generates a manifest for the images on the fly so they can be viewed in Mirador and annotated. - -Demo - -Projects using these plugins: - - -
  • IIIF-Neatline Sandbox Professor Nagasaki, University of Tokyo
  • -
  • Japenese Classics Professor Yang, University of Calgary
  • -
  • John Stows Books Professor Gillespie, Unviersity of Toronto
  • -
  • Malcove Medieval Collection Heather Pigat, Art Museum at UofT
  • - -
    -You can find our plugins here. \ No newline at end of file diff --git a/iiif-5-day-workshop/day-one/README.md b/iiif-5-day-workshop/day-one/README.md deleted file mode 100644 index 5f9febf0..00000000 --- a/iiif-5-day-workshop/day-one/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# Day One - -## 2.1 Introductions - -Instructors: - -- Name and pronouns -- Affiliation -- Dream IIIF project - -Students: - -- Name and pronouns -- Affiliation -- What brought you to this workshop? -- What are you hoping to get out of this workshop? - - -## 2.2 IIIF Introduction - -Pulling from these slides: [https://hadro.github.io/presentations/dhsi2019/dhsi-workshop-day-1-introduction.html#/](https://hadro.github.io/presentations/dhsi2019/dhsi-workshop-day-1-introduction.html#/) - -Intro to IIIF deck: [https://www.dropbox.com/s/lcm5akc3x5jqj40/DHSI%20intro.pptx?dl=0](https://www.dropbox.com/s/lcm5akc3x5jqj40/DHSI%20intro.pptx?dl=0) (Warning: Large pptx file) - - -### IIIF Technology & Community -### IIIF Highlights -### Fun with IIIF - -### Excercise: Class projects sketch - -What kind of project would you like to work on? - -​​- What is the source material? -- What is the context of the project? -- Who is the intended audience? -- What work do you think might be required (to the extent you know this)? - -## 2.3 Image API - -## 2.4 Presentation API - -## 2.5 Getting Started with the Image API diff --git a/iiif-5-day-workshop/day-one/configuring-cantaloupe.md b/iiif-5-day-workshop/day-one/configuring-cantaloupe.md deleted file mode 100644 index 2fd0bbd4..00000000 --- a/iiif-5-day-workshop/day-one/configuring-cantaloupe.md +++ /dev/null @@ -1,44 +0,0 @@ -# Configuring Cantaloupe to use your images. - -Congrats now you have your image server up and running! We need to feed it some images to keep it happy! - -## Download some images - -Go ahead and download a `*.jpg` image from the Internet into your Cantaloupe directory `Cantaloupe-3.4.2`. Here is one [eddie.jpg](https://github.com/sul-cidr/histonets/raw/master/spec/fixtures/images/eddie.jpg) that you can use. - -## Configure Cantaloupe to use the correct path - -Now we need to configure Cantaloupe to use that image directory. - -Navigate to the admin page [http://127.0.0.1:8182/admin](http://127.0.0.1:8182/admin). - -Click on "Resolver", then click "FilesystemResolver" tab. - -Next fill in Path Prefix to be `./` - -![file resolver](../images/file_resolver.png) - -## Check it out in the browser - -Now you should be able to navigate to an image's info.json response successfully. - -Checkout [http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json](http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json) - -And if everything goes right, you should see an `info.json` response. - -![info json](../images/info_json.png) - -Let's finally check it using the Leaflet-IIIF image api viewer. - -Try this url: [http://mejackreed.github.io/Leaflet-IIIF/examples/?url=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json](http://mejackreed.github.io/Leaflet-IIIF/examples/?url=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json) - -Notice how we added our local IIIF server's info.json response url as a parameter. This is used by IIIF Image API clients to understand how they can request images/tiles. - - -![eddie in iiif](../images/eddie_iiif.png) - -Cross our fingers, but you should see a picture of Eddie in a zoomable viewer. - -Other ways to view this image include: - * OpenSeaDragon: [http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json](http://iiif.gdmrdigital.com/openseadragon/index.html?image==http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json) - * UCD Image Cropper: [https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=http://127.0.0.1:8182/iiif/2/eddie.jpg](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=http://127.0.0.1:8182/iiif/2/eddie.jpg) diff --git a/iiif-5-day-workshop/day-one/creating-a-basic-image-viewer.md b/iiif-5-day-workshop/day-one/creating-a-basic-image-viewer.md deleted file mode 100644 index 90b71fd8..00000000 --- a/iiif-5-day-workshop/day-one/creating-a-basic-image-viewer.md +++ /dev/null @@ -1,92 +0,0 @@ -# Creating a Basic Image Viewer - -We have already had success in setting up a IIIF Image Server, now lets put that to use. - -## IIIF Image API Client Libraries - -There are several widely used [IIIF Image API client libraries](https://github.com/IIIF/awesome-iiif#image-viewers), available for multiple languages including JavaScript and Swift. For this workshop (at least for today) we are going to focus on working with Leaflet-IIIF. Why Leaflet-IIIF, well the facilitator of the workshop is the author of the library. Later in the week we will cover some more technologies. - -## Adopting an existing basic example - -For this basic example we want to adopt some pre-existing code hosted as Gist and available at [https://bl.ocks.org/mejackreed/b0aba2ff6f5a54f197767313fbc5a26e](https://bl.ocks.org/mejackreed/b0aba2ff6f5a54f197767313fbc5a26e). - -Go ahead and check that link out. Now let's download the code to get started. - -1. Visit https://gist.github.com/mejackreed/b0aba2ff6f5a54f197767313fbc5a26e -1. Download the code example, "Download ZIP" is probably the easiest way. -1. Unzip downloaded ZIP file and then open the directory in a code editor. -1. Lets run the code as is. Change into the downloaded directory (using `cd`) in a terminal -```sh -$ cd b0aba2ff6f5a54f197767313fbc5a26e-7ece2b016005fb9454dad91d5fcabf5a3ddc934f -``` -**Hint: Use tab to autocomplete directory or file names in the terminal** -1. Run a webserver in the directory. There are two options here, you can use the Nodejs package "http-server" if you installed Nodejs. `npm install --global http-server` and then run it using `http-server`. Or if you have Python installed you can run `python -m SimpleHTTPServer`. -1. We should now be able to visit the page in our browser: Visit [http://127.0.0.1:8000](http://127.0.0.1:8000) or [http://127.0.0.1:8080](http://127.0.0.1:8080). You should see the example we saw on the bl.ocks site. -![basic leaflet-iiif example](../images/basic-leaflet-iiif.png) -1. Let's change the image to use one we setup in the last step. In your code editor modify the following line in `app.js`. - -```diff -- L.tileLayer.iiif('https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/info.json').addTo(map); -+ L.tileLayer.iiif('http://127.0.0.1:8182/iiif/2/eddie.jpg/info.json').addTo(map); -``` -Now when we reload the webpage, we should see our image similar to the last example. -![basic leaflet-iiif example](../images/basic-leaflet-iiif-eddie.png) - -## Adding annotation - -One advantage of using Leaflet-IIIF is the vast plugin ecosystem. We can quickly add the ability to add annotations to our image using a Leaflet plugin, [Leaflet-Draw](https://github.com/Leaflet/Leaflet.draw). - -1. Add the Leaflet.Draw CSS and JavaScript dependencies to our `index.html` file. - -```diff - - - - - -+ - - - - -+ - - -
    - - - -``` -1. Initialize the Leaflet.Draw plugin and a data structure to hold the annotations. - -```diff -// Initialize the FeatureGroup to store editable layers -var drawnItems = new L.FeatureGroup(); -map.addLayer(drawnItems); - -// Initialize the draw control and pass it the FeatureGroup of editable layers -var drawControl = new L.Control.Draw({ - edit: { - featureGroup: drawnItems - } -}); - -map.addControl(drawControl); - -map.on(L.Draw.Event.CREATED, function (e) { - var type = e.layerType - var layer = e.layer; - - // Do whatever else you need to. (save to db, add to map etc) - - drawnItems.addLayer(layer); -}); -``` -1. You should now be able to reload your webpage and add annotation shapes to your image. -![leaflet-iiif-annotation](../images/leaflet-iiif-annotation.png) - -This example is online at [https://bl.ocks.org/mejackreed/462e89092ce71ae7dd09e6074d60f2e0](https://bl.ocks.org/mejackreed/462e89092ce71ae7dd09e6074d60f2e0). diff --git a/iiif-5-day-workshop/day-one/getting-started-with-the-image-api.md b/iiif-5-day-workshop/day-one/getting-started-with-the-image-api.md deleted file mode 100644 index 5980616f..00000000 --- a/iiif-5-day-workshop/day-one/getting-started-with-the-image-api.md +++ /dev/null @@ -1,24 +0,0 @@ -# Getting started with the Image API - -Let's start by hosting an image with the IIIF Image API. There are a few different ways to get started and we are going to try out several. - - -Image formats -Where do you store your image go round room. - -## Hosted - * Klokan: https://www.iiifhosting.com/ - * Digirati: https://dlcs.info/ - - -## Static tiles - * Code https://github.com/zimeon/iiif/tree/master/demo-static - * Example: https://glenrobson.github.io/iiif/2018/01/12/iiif-from-scrtach.html - -## IIIF Image server - * https://github.com/IIIF/awesome-iiif#image-servers - * Main ones: - * [IIP Image](https://iipimage.sourceforge.io/) - written in C - * [Loris](https://github.com/loris-imageserver/loris) - python - * [Cantaloupe](https://cantaloupe-project.github.io/) - Java - diff --git a/iiif-5-day-workshop/day-one/iiif-hosting-saas.md b/iiif-5-day-workshop/day-one/iiif-hosting-saas.md deleted file mode 100644 index dac50059..00000000 --- a/iiif-5-day-workshop/day-one/iiif-hosting-saas.md +++ /dev/null @@ -1,49 +0,0 @@ -# IIIF Hosting - software as a service - -The quickest way to get up and going is to upload images to an image hosting service. One quick one to get started with is [IIIF Hosting](https://www.iiifhosting.com/). - - -1. Click "Sign in/up" -![IIIF Hosting Signup](../images/iiif-hosting-signup.png) - -1. Click "Import" -![IIIF Hosting Signup](../images/iiif-hosting-import.png) - -1. Drag or upload an image from your computer. - -1. Success, now you should be able to see a zoomable version of your image. -![IIIF Hosting Image](../images/iiif-hosting-eddie.png) - -Now you have a hosted version of your image, using a IIIF Image API server. If you click the "[info.json](http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549/info.json)" link in the upper right-hand corner, you will see the Image Information response. - -```javascript -// http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549/info.json -{ - "@context" : "http://iiif.io/api/image/2/context.json", - "@id" : "http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549", - "protocol" : "http://iiif.io/api/image", - "width" : 3024, - "height" : 4032, - "sizes" : [ - { "width" : 189, "height" : 252 }, - { "width" : 378, "height" : 504 } - ], - "tiles" : [ - { "width" : 256, "height" : 256, "scaleFactors" : [ 1, 2, 4, 8, 16 ] } - ], - "profile" : [ - "http://iiif.io/api/image/2/level1.json", - { "formats" : [ "jpg" ], - "qualities" : [ "native","color","gray" ], - "supports" : ["regionByPct","regionSquare","sizeByForcedWh","sizeByWh","sizeAboveFull","rotationBy90s","mirroring"] } - ] -} -``` - -Try this image with: - * Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url= - * e.g. http://mejackreed.github.io/Leaflet-IIIF/examples/?url=http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549/info.json - * OpenSeaDragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image= - * http://iiif.gdmrdigital.com/openseadragon/index.html?image=http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549/info.json - * UCD Image clipper: https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID= - * e.g. https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=http://free.iiifhosting.com/iiif/9dfc3d789672fcbe8f47b9fb51db1b3eb1fa38b0badf35df093e5b7df7f8c549 diff --git a/iiif-5-day-workshop/day-one/iiif-introduction.md b/iiif-5-day-workshop/day-one/iiif-introduction.md deleted file mode 100644 index e83489bf..00000000 --- a/iiif-5-day-workshop/day-one/iiif-introduction.md +++ /dev/null @@ -1,134 +0,0 @@ -# Introduction to IIIF - - -## The Problem - -![image](../images/data%20silos.jpg) - -Since images have been available online, institutions have made a lot of assumptions about how people use images on the web. - -You can infer this by the way in which images are presented to you: -* Each institution or site has their own image viewers -* Assumes rather passive viewing of images -* Assumes you only want to look at one image at a time - -The technical implications of such image delivery also has serious consequences: - -* Siloed data -* Systems often don’t play well together -* Different backends, different UIs -* Often, the data is tied to the platform. What happens to the data when the platform must update or change? - -## The Solution - -![image](../images/API-framework.jpg) - -IIIF came about as a solution to the problems experienced by researchers and tech departments across the world. The idea came from thinking past what was currently possible on the web with digital images to what could and should be possible. - -**What do users and institutions want and/or need?** - -* Ability to contextualize images from across collections and institutions -* Actively engage with images - deep zoom, pan, annotate -* Combine images from across the world in one space -* Be free to use the image viewer of choice -* Cite and Share work - confidence in stable image URLs - -**What do institutions want and/or need?** - -* Make images highly available and open -* But in a standardized, extensible way -* Ability to load/transfer large, high res images easily without server overwork -* That not only has a view openness and access but data persistence and longevity -* System flexibility -* Publish once, reuse often - -### Enter IIIF -Access to image-based resources is fundamental to research, scholarship and the transmission of cultural knowledge. Digital images are a container for much of the information content in the Web-based delivery of images, books, newspapers, manuscripts, maps, scrolls, single sheet collections, and archival materials. Yet much of the Internet’s image-based resources are locked up in silos, with access restricted to bespoke, locally built applications. - -A growing community of the world’s leading research libraries and image repositories have embarked on an effort to collaboratively produce an interoperable technology and community framework for image delivery. -Goals - -IIIF (International Image Interoperability Framework) has the following goals: -* To give scholars an unprecedented level of uniform and rich access to image-based resources hosted around the world. -* To define a set of common application programming interfaces that support interoperability between image repositories. -* To develop, cultivate and document shared technologies, such as image servers and web clients, that provide a world-class user experience in viewing, comparing, manipulating and annotating images. (iiif.io/about/) - -### What is IIIF? In Three Parts -It is most helpful to define what IIIF is by first defining what it is not. IIIF is not a database, web client, repository, or service. It is not a specific website that you log into or access, nor is it an ecosystem of tools. Rather, IIIF is set of standards and guidelines aimed at providing worldwide uniform access to image-based resources with the goal of enhancing the research of digital images. IIIF is not the end result of a process but rather the instructions that can enable libraries to create new ways to use their digital special collections. Think of it as more of the recipe for a cake - a global, interoperable cake made of digital images but potentially other digital media - rather than the finished cake itself. - -#### The specification -Image API (Image Delivery) - -![image](../images/Deep%20zoom.jpg) - -[Princeton scroll](http://libimages.princeton.edu/osd-demo/?feedme=pudl0123%2F8172070%2F01%2F00000001.jp2) - -Presentation API (Image Structure/Layout) -* Just enough metadata to create a remote viewing experience) - -![image](../images/Image%20and%20Pres%20API.jpg) - -Search API (Search within) - -![image](../images/search%20within.jpg?raw=true) - -Authentication API (Access control) - * The IIIF Authentication specification describes a set of workflows for guiding the user through an existing access control system - - ![image](../images/Authentication.png) - -#### The Software (What can you do?) - -Viewers - Comparison -![image](../images/Compare%20images.jpg?raw=true) - -Viewers - Reunite - -Before -![image](../images/broken%20manuscript.png?raw=true) - -After -![image](../images/Biblissima-reunited.png?raw=true) - -Annotation - -![image](../images/annotation.jpg?raw=true) -[Harvard](https://courses.edx.org/courses/course-v1:HarvardX+MCB64.1x+2T2016/d16e07a5cec442eeb7cd9dfcb695dce0/) - -And more! - -* Transciption Tools -* Editors -* Validators -* Games - -#### The Community - -50 Consortium members can be seen [here](http://iiif.io/community/consortium/) - -1 billion+ images - -![image](../images/Adoption.jpg?raw=true) - -Community Groups -* Manuscripts -* Museums -* Newspapers -* Outreach -* Text Granulaity -* 3D -* Archives - -Technical Specification Groups -* A/V -* Discovery -* Software Developers - -## The Future -* IIIF 3.0 - support for audiovisual content -* Discovery for Humans (companion to Discovery TSG) - -#### Videos - -IIIF Vatican: https://www.youtube.com/watch?v=EE1YskDrzPs -IFLA News Media: https://www.youtube.com/watch?v=8LiNbf4ELZM \ No newline at end of file diff --git a/iiif-5-day-workshop/day-one/image-api-examples.md b/iiif-5-day-workshop/day-one/image-api-examples.md deleted file mode 100644 index 7a62dfdb..00000000 --- a/iiif-5-day-workshop/day-one/image-api-examples.md +++ /dev/null @@ -1,26 +0,0 @@ -# Basic IIIF Image API Examples - -One of the most basic examples of utilizing the IIIF Image API is to embed an image in a webpage using an `` tag. - - - -This example uses the Image API to request an image from a IIIF image server. If you select the "index.html" file you can see the URL that is being requested. - -```html - -``` - -This URL is crafted to extract a specific region, at a relative size, from the high quality original image. The original image is measured at 5426 x 3820 pixels and has a file size of 4.7MB. Having users download the entire file is inefficient and will likely provide a poor user experience. The IIIF Image API allows you to serve out derivative versions of these images in a standardized way, without having to generate derivates in advance. - -## Zoomable Images -Several different libraries now exist to use the IIIF Image API to provide a "deep zoom" for the images. Below is an example of the [Leaflet-IIIF](https://github.com/mejackreed/Leaflet-IIIF) displaying the same image we looked at previously. Here you can see the entire image and zoom in with great detail. Using tiled zoom enables viewing of high resolution images without needing to download the full resolution images. - - - -## How does all of this work? -The IIIF Image API server knows how to efficiently deliver these images to the viewer client. The viewer client knows what types of images that it can request from the server. The client gets this information from the server through a [Image Information](http://iiif.io/api/image/2.1/#image-information) request. - -Let's dive into more of how the Image API works. diff --git a/iiif-5-day-workshop/day-one/image-api-internals.md b/iiif-5-day-workshop/day-one/image-api-internals.md deleted file mode 100644 index 6c18b899..00000000 --- a/iiif-5-day-workshop/day-one/image-api-internals.md +++ /dev/null @@ -1,79 +0,0 @@ -# Image API Internals - -## Image Request Parameters -We saw in the previous examples that we could request an image using a defined URL syntax. This syntax is a significant part of how the IIIF Image API works. - -Images are requested using URI templates that have the following syntax: - -```html -{scheme}://{server}{/prefix}/{identifier}/{region}/{size}/{rotation}/{quality}.{format} -``` - -Here is a quick example of how modifying these parameters can change the image that is delivered back to you. - -[![transformation](../images/transformation.png)](http://iiif.io/api/image/2.1/#order-of-implementation) -``` -region=125,15,120,140 size=90, rotation=!345 quality=gray -.../125,15,120,140/90,/!345/gray.jpg -# Source: http://iiif.io/api/image/2.1/#order-of-implementation -``` - -If you went and visited the [IIIF Image API Playground](https://www.learniiif.org/image-api/playground) you would have seen a form that allowed you to change these parameters. - -## Image Information -IIIF Image API software often times need to know what types of requests the server can support. A [Image Information](http://iiif.io/api/image/2.1/#image-information) response from the IIIF Image server is used for this purpose. This response is used by IIIF Image API clients to determine what types of image requests it can make. - -An example of a Image Information response: - -`https://stacks.stanford.edu/image/iiif/hg676jb4964%2F0380_796-44/info.json` - -```javascript -{ - "@context": "http://iiif.io/api/image/2/context.json", - "@id": "https://stacks.stanford.edu/image/iiif/hg676jb4964%252F0380_796-44", - "protocol": "http://iiif.io/api/image", - "width": 5426, - "height": 3820, - "sizes": [ - { - "width": 170, - "height": 119 - }, - { - "width": 339, - "height": 239 - }, - { - "width": 678, - "height": 478 - }, - { - "width": 1357, - "height": 955 - }, - { - "width": 2713, - "height": 1910 - }, - { - "width": 5426, - "height": 3820 - } - ], - "tiles": [ - { - "width": 2713, - "height": 1910, - "scaleFactors": [ - 1, - 2, - 4, - 8, - 16, - 32 - ] - } - ], - "profile": "http://iiif.io/api/image/2/level2" -} -``` diff --git a/iiif-5-day-workshop/day-one/image-api.md b/iiif-5-day-workshop/day-one/image-api.md deleted file mode 100644 index b440b134..00000000 --- a/iiif-5-day-workshop/day-one/image-api.md +++ /dev/null @@ -1,88 +0,0 @@ -# IIIF Image API - -## Overview - -The Image API provides for a standardized way to request and deliver images. Having this standardization allows both browser and server applications to reuse software and provide a consistent experience for requesting images. - -I will be presenting this [Google slide deck](https://docs.google.com/presentation/d/1sannNtwGz-h9oRe02tZ2aOjr7jJ9LYY6W_jP3uvA9kk/edit?usp=sharing) but will include all links here so you can follow along. - -## Presenter - -Glen Robson, IIIF Technical Coordinator - -National Library of Wales links: - * [Digitisation](http://bit.ly/2zPFx8a) - * [Newspapers](http://newspapers.library.wales/) - -## Pre-IIIF Viewers - -Example from Ben Albritton's blog [Fellow Travelers: The Canterbury Tales and IIIF](http://stanford.io/1PW789d) - -## Image API - -Latest version of the Image API is available at [http://iiif.io/api/image/2.1/](http://iiif.io/api/image/2.1/). - -## Image API demonstration - -Many of these examples are from Tom Crane's [excellent blog series](http://resources.digirati.com/iiif/an-introduction-to-iiif/). - - * [Original oil painting from the Wellcome Trust](http://wellcomelibrary.org/item/b14658197) - * [Example API calls](https://tomcrane.github.io/the-long-iiif/image-api.html) - * [Tile Explorer](http://tomcrane.github.io/presentations/tile-exploder.html) - * [Example info.json](https://dlcs.io/iiif-img/3/2/04fbbb28-d5a7-4408-b7da-800c4e65eda3/info.json) - -### Image API Exercises - -Look at the following and play around with the parameters: - * [Jason Ronallo's detailed example](http://ronallo.com/iiif-workshop/image/detailed-example.html) - * [Tom Cranes example](https://tomcrane.github.io/the-long-iiif/image-api.html) - * [UCD image cropper](https://jbhoward-dublin.github.io/IIIF-imageManipulation/index.html?imageID=https://iiif.ucd.ie/loris/ivrla:10408) - -### Questions -In pairs answer the following questions: - - 1. Given the following image URL: [https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg](https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/full/512,/0/default.jpg) what would be the URL for the `info.json`? - 2. What is the width and height of the biggest size image? - 3. Construct a URL that: - * Shows the full image - * is 512px wide - * is upside down - * gray scale - * has a format of `png` - 4. What formats can you request for this image? - -Looking at the IIIF API Specification [https://iiif.io/api/image/2.1/](https://iiif.io/api/image/2.1/) - - 5. What status code should be returned if you ask for a format the image server doesn't support? - 6. What does `max` image size mean? How does it differ to `full`? When might you use this? - -Given the following info.json: - -``` -{ - "@context": "http://iiif.io/api/image/2/context.json", - "@id": "http://example.com/iiif/image/2", - "@type": "iiif:Image", - "protocol": "http://iiif.io/api/image", - "width": 400, - "height": 400, -} -``` -and image: - -![image](../images/4_Quadrants.jpg) - -**HINT**: remember 0,0 is the top left of the image. - - 5. What would the URL be to cut out the green quarter? - 6. What would the URL be to cut out the white quarter? - -### Bonus points: - -Given the following info.json: https://iiif.lib.ncsu.edu/iiif/mc00198-008-ff0051-000-001_0001/info.json - - 7. How many tiles would you need to show the full image? - -If you finish have a look at [http://puzzle.mikeapps.me/](http://puzzle.mikeapps.me/) - - diff --git a/iiif-5-day-workshop/day-one/level0-github-hosting.md b/iiif-5-day-workshop/day-one/level0-github-hosting.md deleted file mode 100644 index 86abfce8..00000000 --- a/iiif-5-day-workshop/day-one/level0-github-hosting.md +++ /dev/null @@ -1,143 +0,0 @@ -# Level 0 hosting with GitHub Pages - -One of the really useful things with IIIF is there is always something called a level 0 implementation which is a way of implementing the IIIF APIs without running a server. For the Image API this means creating all of the image tiles and making them available through your web accessible space. - -One way to get access to free web hosting is to use GitHub pages. GitHub is a software and web application created to manage projects with multiple developers and manages the source code to ensure people's changes don't get overwritten. One feature of Github is GitHub Pages which allows you to create a Web page about your project. We are going to use this functionality to host a IIIF Image. This is a reliability convoluted process but once setup it will give you a free way to publish IIIF Images. - -## Step 1: Sign up to GitHub -Created an account by going to [Github](https://github.com/) and clicking signup. - - * Create Username, password, email - -![image](../images/level0-github-signup.png) - - * Complete verify puzzle - -![image](../images/level0-verifygithub.png) - - * Choose free option - -![image](../images/level0-github-account-type.png) - - * Customise experience (skip this step) - -![image](../images/level0-github-customise.png) - - * Verify email address - -![image](../images/level0-github-email-verify.png) - - * Success!! - -![image](../images/level0-github-success.png) - -## Step 2: Get Read/write access to repo - * Add username to: https://github.com/dhsi-iiif/dhsi-iiif.github.io/issues/1 - * You will get an invitation through the email you registered with in GitHub - -![image](../images/level0-github-invitation.png) - - * Accept invitation - -![image](../images/level0-github-invitation-accept.png) - -## Step 3: Check out repo -The GitHub desktop application manages the upload of your data to GitHub. It is possible to do this through the Git command line but for this part of the workshop it is suggested to use the Desktop version. - - * Download and install Github desktop https://desktop.github.com/ - * Login - * Click login through website - -![image](../images/level0-github-desktop-login.png) - - * Configure name and email - -![image](../images/level0-github-desktop-nameemail.png) - - * Download the GitHub dhsi 2019 repository to your local machine in the dhsi2019/dhsi-iiif.github.io. GitHub calls download a repository 'cloning'. So select the dhsi-iiif.github.io repository and click clone. - -![image](../images/level0-github-clone.png) - - * Selecting where to download the repo to. - -![image](../images/level0-github-clone-2.png) - - * Click open in Finder or similar for Windows - -![image](../images/level0-github-desktop-open.png) - - * Make a directory inside the 2019 directory for your examples: - - ``` - dhsi-iiif.github.io/2019/ -``` -## Step 4: Upload level 0 image - * Download the following zip file which contains an Image split into tiles: - -https://iiif.github.io/training/iiif-5-day-workshop/images/page001.zip - - * Extract zip into: - - ``` - dhsi-iiif.github.io/2019/ - ``` - - * This should create a page001 directory and if you look into this directory you should see familiar directory names which match a IIIF Image request. - * Go to Github Desktop - -![image](../images/level0-github-commit.png) - - * Add a commit message on the left hand side. Fill in the Summary and a short description. - * Click commit to master - * You now need to send your local changes to GitHub. To do this click the Push Origin button. Note if others in the class are also on this step they may have made changes to GitHub and the GitHub desktop application will not let you send your changes until you have the latest copy from GitHub. If this is the case it may ask you to Pull from origin. If this is the case Pull the latest changes before pushing your changes. - -![image](../images/level0-github-pushpull.png) - - * In your local copy of `2019//page001/info.json`, open it up in an editor and edit the `@id` with: `https://dhsi-iiif.github.io/2019//page001/info.json` - * and you should see your info.json! - -## Step 5: View image: - * Leaflet: http://mejackreed.github.io/Leaflet-IIIF/examples/?url=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json - * Openseadragon: http://iiif.gdmrdigital.com/openseadragon/index.html?image=https://dhsi-iiif.github.io/2019/glenrobson/page001/info.json - * Note not all software works with level 0 images. - -## Advanced Step 6: Extras make your own static image: -This step allows you to create your own level 0 image. It requires Python which comes installed on MacOS X and can be downloaded for windows at https://www.python.org/downloads/. - * Clone the code repo - * Go to: https://github.com/zimeon/iiif - * Click on `clone or download` - * Click Open in Desktop - -![image](../images/level0-github-iiif-clone.png) - - * Save it to `dhsi2019/GitHub/iiif` - -![image](../images/level0-github-iiif-clonelocation.png) - - * Now open up the terminal or command line and change into the iiif directory: - - ```cd dhsi2019/GitHub/iiif/``` - - * Note a simple way to do this is to open up the terminal type `cd` then drag the iiif directory from Finder into the terminal. - - * Install the required libraries. To do this run: - - ```pip install Pillow``` - - * If you get a permission denied error then run it as root: - - ```sudo pip install Pillow``` - - * Finally run the command to create the level 0 image. Note the first location is where I want the images to be saved and `~/Pictures/Glen.jpg` is a picture in my home pictures directory: - - ```./iiif_static.py -d ~/dhsi2019/GitHub/dhsi-iiif.github.io/2019/glenrobson/ ~/Pictures/Glen.jpg``` - -![image](../images/level0-github-create-level0.png) - - * Finally as you did earlier go to the GitHub desktop application add a Commit summary and description then commit and Push changes - * Your image should now be accessiable at - - ```https://dhsi-iiif.github.io/2019///info.json``` diff --git a/iiif-5-day-workshop/day-one/presentation-api.md b/iiif-5-day-workshop/day-one/presentation-api.md deleted file mode 100644 index 7a42ffb1..00000000 --- a/iiif-5-day-workshop/day-one/presentation-api.md +++ /dev/null @@ -1,29 +0,0 @@ -# IIIF Presentation API - -The IIIF Image API provides a machine-readable mechanism to retrieve pixels. But when we want to know more about the context of the image, such as its rights, title, description, and related information, and when we are working with structured sets of several images, we need the presentation API. - -> The Image API retrieves pixels. -> The Presentation API presents the image(s) in context. - -![IIIF API Separation](../images/api_puzzle_pieces.png) - -> The Presentation API presents "just enough metadata to drive a remote viewing experience". - -![IIIF Image API Definition](../images/image_api_slide.png) -![IIIF Presentation API Definition](../images/presentation_api_slide.png) -![IIIF Software Stack](../images/software_stack_slide.png) - -Several "Presentation API Clients" have been written over the last few years at this top layer. -[Mirador]( http://projectmirador.org/demo/ ) -[Universal Viewer]( https://universalviewer.io/examples/#?c=&m=&s=&cv=&manifest=http%3A%2F%2Fwellcomelibrary.org%2Fiiif%2Fb18035723%2Fmanifest&xywh=-1383%2C-197%2C5333%2C3936 ) -[IIIF Curation Viewer]( http://codh.rois.ac.jp/software/iiif-curation-viewer/demo/?manifest=http://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json ) - -![IIIF Presentation vs. Image API Interface](../images/image_and_presentation_highlighted.png) - -## Enhanced Interoperability -### Drag and Drop -### Annotations -## Advanced Representation Features -### Reunification of Broken Books -### Reunification of Fragmented Pages -### Multispectral Image Layers diff --git a/iiif-5-day-workshop/day-one/setting-up-cantaloupe.md b/iiif-5-day-workshop/day-one/setting-up-cantaloupe.md deleted file mode 100644 index f342d4d0..00000000 --- a/iiif-5-day-workshop/day-one/setting-up-cantaloupe.md +++ /dev/null @@ -1,59 +0,0 @@ -# Setting up Cantaloupe IIIF Image Server - -Make sure you have [installed the prerequisites](https://gist.github.com/mejackreed/8ed979425ae702eaf1ebb2dbc1d7313b). - -## Download Cantaloupe - -For more information, checkout the [Cantaloupe getting started guide](https://medusa-project.github.io/cantaloupe/manual/3.4/getting-started.html). - -Download [Cantaloupe v3.4.2](https://github.com/medusa-project/cantaloupe/releases/download/v3.4.2/Cantaloupe-3.4.2.zip) - -Open and extract the zip file to your directory of choosing. We suggest `~/Desktop`. - -Now change directory to that extracted directory - -```sh -$ cd ~/Desktop/Cantaloupe-3.4.2 -``` - -## Configure Cantaloupe - -Now lets create a copy of the configuration file: - -```sh -$ cp cantaloupe.properties.sample cantaloupe.properties -``` - -Now lets enable the admin panel where we will modify the rest of the settings. - -Scroll to line 104, and change `false` to `true`. Also add a password. - -```diff -# Enables the Control Panel, at /admin. -- admin.enabled = false -+ admin.enabled = true -- admin.secret = -+ admin.secret = yolo -``` - -Save the file. - -Now lets try and start the server. Run this command from your Cantaloupe directory - -```sh -$ java -Dcantaloupe.config=./cantaloupe.properties -Xmx2g -jar Cantaloupe-3.4.2.war -``` - -Now navigate to [http://127.0.0.1:8182/iiif/2](http://127.0.0.1:8182/iiif/2) in your browser. - -You should see this: - -![server image](../images/cantaloupe-image.png) - -Congrats you successfully installed Cantaloupe! - -Also make sure you can get into the admin panel by navigating to [http://127.0.0.1:8182/admin](http://127.0.0.1:8182/admin). - -Use the username `admin` and the password you set previously. - -![admin panel](../images/cantaloupe-admin.png) diff --git a/iiif-5-day-workshop/day-three/README.md b/iiif-5-day-workshop/day-three/README.md deleted file mode 100644 index a0e2e51e..00000000 --- a/iiif-5-day-workshop/day-three/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Day Three - -## Background: Context and Theory of Annotations -Slides: https://slides.com/hadro/dhsi-workshop-day-3-annotations - -## Annotations and Annotation Lists - -## Exercise: Annotating multiple images, and text annotations - -## Collections - -## Ranges diff --git a/iiif-5-day-workshop/day-three/advanced-annotations.md b/iiif-5-day-workshop/day-three/advanced-annotations.md deleted file mode 100644 index c6926e5e..00000000 --- a/iiif-5-day-workshop/day-three/advanced-annotations.md +++ /dev/null @@ -1,16 +0,0 @@ -# Advanced Annotations - -For this section I will be using this [google slides](https://docs.google.com/presentation/d/1StVt_Eixt9wmFXoyPRjjlq-J1VevR7b4qvVmVs7yBWg/edit?usp=sharing) presentation. Links for the different examples are available below: - - * [Georeferencer for maps](https://www.georeferencer.com/) - * [Stanford Georeference example](https://www.davidrumsey.com/view/georeferencer) - * [Final site for the Cynefin data](https://places.library.wales/) - * [Visualisation of the Shipping records data](https://medium.com/@404mike/shipping-records-73e3fd48a16e#.aqxgfeogl) - * Tribunal data - * Graphs: https://iiif.gdmrdigital.com/ww1-tribunal/index.html - * Data: https://github.com/NLW-paulm/Welsh-Tribunal-annotations - * [Video on how to configure the crowdsourcing system](https://www.youtube.com/playlist?list=PLMd2mmRYjSJlKs829X0z_kYueQemSfwDd) - * [Recogito](https://recogito.pelagios.org/) - * [From the Page](https://fromthepage.com/) - * [Indigenous Digital Archive](https://omeka.dlcs-ida.org/s/ida/page/home) - * [LibCrowds from the BL](https://www.libcrowds.com/collection/playbills) diff --git a/iiif-5-day-workshop/day-three/annotation-store-download.md b/iiif-5-day-workshop/day-three/annotation-store-download.md deleted file mode 100644 index 51de69cc..00000000 --- a/iiif-5-day-workshop/day-three/annotation-store-download.md +++ /dev/null @@ -1,111 +0,0 @@ -# Creating and downloading Annotations - -In this tutorial we are going to annotate an image from your own manifest using the hosted SimpleAnnotationStore. Once we have finished annotating we are going to download the annotations created in an Annotation list and link them to the Manifest. This is a way of permanently attaching annotations to a manifest. - -## Step 1 Load your manifest into the hosted Mirador: - * Go to http://sas.gdmrdigital.com - * Add your manifest to the addNewObject field and click load: - -![image](../images/annos_download_annotating.png) - -## Step 2: annotate manifest - - * Start annotating your manifest - -![image](../images/annos_download_success.png) - -## Step 3: Download annotations - -Now you have finished annotating you need to download the annotations and link them to canvases in your manifest. To do this you will download 1 annotation list per page/canvas. - - * Navigate to http://sas.gdmrdigital.com/list.html - * You will have to check the canvas ids linked on that page next to the canvas ids in your manifest. - * Right click and do save as. - * Save the annotations to your `dhsi2019` folder with the name `annotations1.json`, `annotations2.json` etc... - -## Step 4: Turn annotation list into a list that can be linked in Mirador - -By default the SimpleAnnotationServer generates a list of annotations that need to be slightly edited when linked to the manifest. To do this open the annotations in Atom (`dhsi2019/annotations1.json`. Add the following to the top of the file: - -```json -{ - "@context":"http://iiif.io/api/presentation/2/context.json", - "@id":"http://localhost:8887/annotations1.json", - "@type":"sc:AnnotationList", - "resources": -``` - -and also add `}` at the end of the file. Now save this and go on to the following step. - -## Step 5: Link annotations to Manifest -To get the annotations to display you need to link them into the manifest. To do this find the canvas your annotations point to then add the following: - -```json -"otherContent": [ - { - "@id": "http://example.com/files/page1.json", - "@type": "sc:AnnotationList", - "label": "My fantastic annotations" - } -] -``` - -after the images array. A full canvas example is below: - -```json -{ - "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json", - "@type": "sc:Canvas", - "label": "1r", - "height": 5584, - "width": 3744, - "images": [ - { - "@id": "http://dams.llgc.org.uk/iiif/2.0/4004562/annotation/4004563.json", - "@type": "oa:Annotation", - "motivation": "sc:painting", - "resource": { - "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563/full/1024,/0/default.jpg", - "@type": "dctypes:Image", - "format": "image/jpeg", - "service": { - "@context": "http://iiif.io/api/image/2/context.json", - "@id": "http://dams.llgc.org.uk/iiif/2.0/image/4004563", - "profile": "http://iiif.io/api/image/2/level1.json" - }, - "height": 5584, - "width": 3744 - }, - "on": "http://dams.llgc.org.uk/iiif/2.0/4004562/canvas/4004563.json" - } - ], - "otherContent": [ - { - "@id": "http://example.com/files/page1.json", - "@type": "sc:AnnotationList", - "label": "My fantastic annotations" - } - ] -}, - -``` - -Save the manifest. - -## Step 5: check the annotations are showing - - * Go to https://projectmirador.org/demo/ or http://iiif.gdmrdigital.com/mirador/index.html if you want a version that doesn't require https. - * Load the manifest using Add new object from URL - * Click on one of the images to view the manifest - * Click on the speech bubble to show the annotations. - -![image](../images/annos_download_show.png) - - * and if it all worked OK you should see your annotation. - -![image](../images/annos_download_success.png) - - -It is also possible to do the above with a locally running SimpleAnnotationServer just follow the [Annotating Stores - Do it yourself](day-three/annotations-stores-install.md) part of the course. When you get to downloading the annotations the file to get the list of annotated canvases is: - -http://localhost:8080/list.html diff --git a/iiif-5-day-workshop/day-three/annotations-and-annotation-lists.md b/iiif-5-day-workshop/day-three/annotations-and-annotation-lists.md deleted file mode 100644 index 29ec6440..00000000 --- a/iiif-5-day-workshop/day-three/annotations-and-annotation-lists.md +++ /dev/null @@ -1,84 +0,0 @@ -# What are annotations - -Annotations relate an object ("resource") to another object ("on"). -The nature of that relationship can be of various types. -Treating the annotation itself as a resource allows describe and category the nature of that relationship. - -For more, we'll go through the slides here: -https://slides.com/hadro/dhsi-workshop-day-3-annotations - -## Example Annotation - -```json - -{ - "@type": "oa:Annotation", - "motivation": "sc:painting", - "resource":{ - "@id": "http://example.org/iiif/book1/res/tei-text-p1.xml", - "@type": "dctypes:Text", - "format": "application/tei+xml" - }, - "on": "http://example.org/iiif/book1/canvas/p1" -} - -``` - -## What are annotationsLists? - -See Specification Chapter: [http://iiif.io/api/presentation/2.1/#annotation-list](http://iiif.io/api/presentation/2.1/#annotation-list) - -Annotations are simply lists of annotations grouped together. -They can be re-used by any application that wants to retrieve them. - -```json -{ - "@context": "http://iiif.io/api/presentation/2/context.json", - "@id": "http://localhost:8887/coin/canvas/AnnotationList", - "@type": "sc:AnnotationList", - "resources": [ - { - "@id": "http://localhost:8887/coin/list/1", - "@type": "oa:Annotation", - "motivation": "sc:painting", - "resource": { - "@type": "cnt:ContentAsText", - "format": "text/plain", - "chars": "Zeus seated on stool-throne" - }, - "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" - }, - { - "@id": "http://localhost:8887/coin/list/1", - "@type": "oa:Annotation", - "motivation": "sc:painting", - "resource": { - "@type": "cnt:ContentAsText", - "format": "text/plain", - "chars": "Zeus seated on stool-throne" - }, - "on": "http://localhost:8887/coin/canvas#xywh=3706,208,522,522" - } - ] -} -``` - -That can also be linked to manifests so that a viewer can bring them together in one cohesive experience. - -## Caveat: Open Annotations vs Web Annotations - -## Annotations Exercise - -Go on to the [Annotations Exercise](exercise.html) to try out some cases where annotations come into play. - -## Using an annotation Store - -What is an annotation store? An annotation store is just a database designed to ingest data structured according to the Open Annotations (or Web Annotations) specifications. - -There are lots of them annotation stores. You can make your own or use one that has been made by someone else. - - -## Local Storage as an annotation store - -Because an annotation store is nothing other than place to store raw data, -even your browser's local storage can function as an annotation store. diff --git a/iiif-5-day-workshop/day-three/annotations-exercises.md b/iiif-5-day-workshop/day-three/annotations-exercises.md deleted file mode 100644 index ab90ed6c..00000000 --- a/iiif-5-day-workshop/day-three/annotations-exercises.md +++ /dev/null @@ -1,78 +0,0 @@ -# Annotation Exercises - -Annotations through Mirador: - -Step 1: - * Go to https://projectmirador.org/ - -Step 2 - Navigating with Mirador: - * Click 'Try a live demo' - -Mirador commands: - -![image](../images/annos_mirador.png) - - * Select a Manifest by clicking on one of the Rows: - -![image](../images/annos_select_manifest.png) - - * Or add your own manifest in the 'Add new object from URL' - -Step 3 - Start annotating: - * Click the speech bubble on the top left - -![image](../images/annos_toggle_annotations.png) - - * Lots of options: - -![image](../images/annos_anno_options.png) - -From left to right the buttons are: - * Speech bubble - hide annotation buttons - * Pointer - to select existing annotations and change the size or edit the content - * Rectangle - Draw a rectangle annotation - * Oval - Draw a Oval annotation - * Freeform - Go free style with the shape of the annotation - * Ploygon - Create a shape with straight sides - * Pin - Drop a pin as the target of the annotation - * Thickness - change the thickness of the shape's line - * Line colour - change the colour of the shape's line - * Fill - fill the shape with a colour. - - * Once you have drawn a shape on the image you get a box where you can add content for the annotation. - -![image](../images/annos_anno_options.png) - -Again you have more buttons to choose from and these are to format the content of the annotation: - * Make the text bold - * Make the text italics - * Insert a link - * Insert an image - * Insert a video or audio file - * Clear formatting - * and change orientation of the text (left/right or right/left) - -To format the text with bold or italics, type of your text then highlight it and click the bold or italics button. - -Once you have added some text click save. You can also add a tag if you like. - -You will then see a box appear and if you put your mouse over the box you will see the text you entered: - -![image](../images/annos_created.png) - -Take 5 minutes to play around creating annotations so you get a feel for how it works. Also think on the following questions: - - * What type of project would this be useful for? - * What might it not work so well with? - -## Where are these annotations stored? - -This version of Mirador stores the annotations in the browser local storage. This means: - - * They are only accessible on your machine - * They are not permanent and may disappear - * Its the perfect storage location for a demo site - -## How do we make these annotations more permanent? - -With an Annotation Store. diff --git a/iiif-5-day-workshop/day-three/annotations-stores-install.md b/iiif-5-day-workshop/day-three/annotations-stores-install.md deleted file mode 100644 index 10ca021b..00000000 --- a/iiif-5-day-workshop/day-three/annotations-stores-install.md +++ /dev/null @@ -1,115 +0,0 @@ -# Installing an Annotation Server - -We are now going to attempt to install an Annotation Server locally. For this you will need: - - * The Chrome Web server you setup as part of the Presentation API. This should be running on port `8887` and the directory should be `dhsi2019`. - * Atom open ready for editing a manifest - * A command line open and `cd` into the `dhsi2019` directory. Remember the following commands: - - `cd` - Change directory - - `ls` - list directory - - `pwd` - to show you where you are (Print Working Directory) - - - Step 1: - * Download the SimpleAnnotationServer release: https://github.com/glenrobson/SimpleAnnotationServer/releases. Download sas.zip - -![image](../images/annos_sas_download.png) - - Step 2: - * Extract the zip file into your `dhsi2019`. On windows make sure it is extracted by right click on the file and uncompressing. - - Step 3: - * In your terminal window `cd` into the sas directory which should have been created in the last step. - -``` -Glens-MacBook-Pro:tmp gmr$ cd sas -Glens-MacBook-Pro:sas gmr$ ls -2019_06_05.request.log generated-sources maven-status surefire-reports -classes generated-test-sources simpleAnnotationStore test-classes -dependency maven-archiver simpleAnnotationStore.war work -``` - - Step 4: - * Run the SimpleAnnotationStore: - -```java -jar dependency/jetty-runner.jar simpleAnnotationStore.war``` - - Step 5: - * Navigate to http://localhost:8080/index.html - * And you should see Mirador - * Navigate to an item and make an annotation. Does it save? If not ask for help - - Step 6: - * We are now going to download a manifest and make it aviliable through the Chrome Web Server. - * Download the following manifest: https://damsssl.llgc.org.uk/iiif/2.0/4389767/manifest.json - * Save it into your `dhsi2019` directory - * Now open up this file in Atom - -![image](../images/annos_sas_manifest.png) - - * You may need to format the JSON. To do this go to the `Packages` menu then `Pretty Json`, then `Prettify` - -![image](../images/annos_atom_prettify.png) - - * Now Change the `@id` from `http://dams.llgc.org.uk/iiif/2.0/4389767/manifest.json` to `http://localhost:8887/manifest.json` - -![image](../images/annos_atom_id_update.png) - - * Now click save. Double check you can access the manifest at: http://localhost:8887/manifest.json - - Step 7: - * Now switch back to Mirador and add this manifest - * Go to http://localhost:8080/index.html - * Go to the list of manifests (click the big plus sign or if you are viewing a manifest click the four boxes at the top left and select 'newObject'). - * In the list of manifests paste the link to your manifest http://localhost:8887/manifest.json into the addNewObject text field and click `load`. - * You should now see: - -![image](../images/annos_mirador_addItem.png) - - Step 8: - * Add some annotations to this manifest. - - Step 9: - * We are now going to index the manifest and add a search API. - * Navigate to: http://localhost:8080/uploadManifest.html - * Upload your manifest (http://localhost:8887/manifest.json) - * If this was succesfull you should see the following page: - -![image](../images/annos_search_endpoint.png) - - * Copy the URL in the search bar so you can use it later. In my example above this would be `http://localhost:8080/search-api/localhost:8887/search` - * Now open up the Manifest in Atom and it should look like this: - -![image](../images/annos_atom_pre_search.png) - - * Now add the following JSON to the manifest after the `label`: - -``` -"service": { - - "profile": "http://iiif.io/api/search/0/search", - "@id": "SEARCH_ID", - "@context": "http://iiif.io/api/search/0/context.json" - -}, -``` - - * Now replace the SEARCH_ID with the URL you copied earlier. In my example it would look like: - -![image](../images/annos_search_api_atom.png) - - Step 10: - * Test your manifest with the Universal Viewer to see if has worked. - * Open up http://universalviewer.io/ - * and paste your manifest http://localhost:8887/manifest.json in the View a IIIF Manifest section - * Does it show a search box? - * Has it found an annotation? Note the search is case sensetive. - -Extras: - - * [Loading a Newspaper example with OCR](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/PopulatingAnnotations.md) - * [Download annotations](https://github.com/glenrobson/SimpleAnnotationServer/blob/master/doc/DownloadAnnotations.md) - * If you get here you can go back to day one and do the [Github Pages level0](../day-one/level0-github-hosting.html) tutorial. diff --git a/iiif-5-day-workshop/day-three/annotations-stores-results.md b/iiif-5-day-workshop/day-three/annotations-stores-results.md deleted file mode 100644 index 9ac0124f..00000000 --- a/iiif-5-day-workshop/day-three/annotations-stores-results.md +++ /dev/null @@ -1,87 +0,0 @@ -# Results - -Feel for the volunteers who did all 1,000 pages! - -Exercises: - * Navigate to somebody else's section, do you see the annotations? - * Take the Manifest and view it in http://projectmirador.org/. The manifest is https://iiif.gdmrdigital.com/nlw/bor.json - * Do you see the annotations? - * Take the Manifest to the Universal Viewer: https://universalviewer.io/ - * What do you see? - - -## Looking at the annotation: - -``` -{ - "@id" : "http://35.177.224.176:8888/annotation/1559731764132", - "@type" : "oa:Annotation", - "dcterms:created" : "2019-06-05T10:49:24", - "resource" : [ { - "@id" : "_:b2", - "@type" : "dctypes:Text", - "http://dev.llgc.org.uk/sas/full_text" : "Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala", - "format" : "text/html", - "chars" : "

    Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala

    " - } ], - "on" : { - "@id" : "_:b0", - "@type" : "oa:SpecificResource", - "within" : "https://iiif.gdmrdigital.com/nlw/bor.json", - "selector" : { - "@id" : "_:b1", - "@type" : "oa:FragmentSelector", - "value" : "xywh=488,1543,2735,327" - }, - "full" : "https://damsssl.llgc.org.uk/iiif/2.0/4642022/canvas/4642029.json" - }, - "motivation" : [ "oa:commenting" ], - "@context" : "http://iiif.io/api/presentation/2/context.json" -} - -``` - -Looking more closely at the Annotation body: - -``` -

    - Ty.Sub.Lt. - Eric Hugh Allan - R.N.R - Bombala -

    -``` - -This uses RDF/A which is linked data hidden inside HTML. The HTML is what Mirador displays in the annotation but it can also be loaded to a Linked Data database and queried. For example this is looking at all the places listed in the book and putting them on a heat map: - -![image](../images/annos_bor_stats_map.png) - -and this is looking at the numbers lost per ship: - -![image](../images/annos_bor_ships_lost.png) - -and doing a bit more research I found: - -![image](../images/annos_bor_sailors_lost.png) - -and a Newspaper article and blog post: - -![image](../images/annos_bor_newspaper.png) -![image](../images/annos_bor_article.png) - -A full export of the data is available at: https://github.com/NLW-paulm/BoR-annotations - -## Search - -So how did that work? - -Lets have a look at the Manifest: https://iiif.gdmrdigital.com/nlw/bor.json - -## Summary -Win, Win - - * Engaged volunteers - * Publicity for the collection - * Funding - * Item now searchable for the public - * Data available for integration diff --git a/iiif-5-day-workshop/day-three/annotations-stores.md b/iiif-5-day-workshop/day-three/annotations-stores.md deleted file mode 100644 index 7ba111b0..00000000 --- a/iiif-5-day-workshop/day-three/annotations-stores.md +++ /dev/null @@ -1,67 +0,0 @@ -# Annotation Stores - -Like image servers there are a number to choose from: - -https://github.com/IIIF/awesome-iiif#annotations - -Popular ones include: - * annotot - Simple IIIF annotations mounted in a Ruby on Rails applications by Jack Reed - * Elucidate - Java and Postgres annotation server by Digirati - * SimpleAnnotationServer - Java annotation server backed by an Apache Jena triple store, Sesame, or Solr. - developed while working at the NLW - - For this exercise we are going to be using the [SimpleAnnotationServer](https://github.com/glenrobson/SimpleAnnotationServer) and we are going to work on a copy of the National Library of Wales Book of Remembrance. You may remember this book from the Presentation API talk yesterday. The live version of the books is available at: - -http://hdl.handle.net/10107/4642022 - -but we are going to use the following version which has a annotation server connected to Mirador: - -http://sas.gdmrdigital.com/examples/bor/lcc-en.html - -Mirador doesn't cope well with multiple people annotating the same page so I will distribute the following sections to each of you: - - * Cavalry - * Corps of Lancers - * Grenadier Guards - * The Queen's (Royal West Surrey Regiment) - * The King's Own (Royal Lancaster Regiment) - * Northumberland Fusiliers - * Norfolk Regiment - * The Prince of Wales's Own (West Yorkshire Regiment) - * Canadian Expeditionary Force Service in France (right at the bottom of the book) - * New Zealand Expeditionary Force (also at the bottom) - -I am going to ask you to transcribe one page for the section that you are assigned. As part of this project we wanted to capture not just a transcription but also the fields to allow research so we customised Mirador to capture the different fields. - -To annotate a name: - -## Step 1: - * To navigate make sure the pen and paper at the top left is disabled - * Get the line in full view - * Click the pen and paper to start annotating - * Draw a box as well as you can around the name - -![image](../images/anno_bor_start.png) - - * Now type what you see (don't worry about the buttons yet). So in this example I would type `Ty.Sub.Lt. Eric Hugh Allan R.N.R Bombala` - -![image](../images/anno_bor_text.png) - - * Once you've typed everything double click on a word or highlight two words if required. - -![image](../images/anno_bor_highlight.png) - - * Now click the button that matches the type of the text. In this example I would click name and see the text go black: - -![image](../images/anno_bor_typed.png) - - * Now do the rest: - -![image](../images/anno_bor_finshed.png) - - * Then click save: - -![image](../images/anno_bor_view_anno.png) - - * Now complete the page - - diff --git a/iiif-5-day-workshop/day-three/collections.md b/iiif-5-day-workshop/day-three/collections.md deleted file mode 100644 index 42f59bd1..00000000 --- a/iiif-5-day-workshop/day-three/collections.md +++ /dev/null @@ -1,38 +0,0 @@ -# Collections - -## Description - -Collections are away to organize manifests into groups, allow us the ability to share groups of manifest with a single URL. - - -## Collection Tree Navigator for Mirador - -The collection tree navigator for Mirador came about to address the need of showing objects in nested collections to ease navigation and avoid server slow-down. Collection-level manifests are often very large and can contain many sub-collections within them. As such, it became important for users to navigate through collections easily and without losing context. - -The aeature allows users to: - -- View entire collections with sub-collections in a tree structure on manifest selection panel -- Easily navigate across collections - - -## Activity - -Let's create your and serve your own collection - -1. Find at least five manifests and organize them into a collection, following the IIIF guidelines - * [http://iiif.io/api/presentation/2.1/#collection](http://iiif.io/api/presentation/2.1/#collection) -1. Save your collection as `mycollection.json` in the `myManifests` folder on your Desktop. -1. Server your manifests and collections with `$ http-server --cors` -1. In the `example.html` file in the Mirador directory file configure mirador to load a collection. - ```json - "data": [ - { "collectionUri": "https://localhost:8080/mycollection.json"} - ] - ``` -1 Configure mirador to allow to browse your collection by changing the manifestsPanel module to the CollectionTreeManifestsPanel" - - ```json - "manifestsPanel": { - "module": "CollectionTreeManifestsPanel", - } - ``` diff --git a/iiif-5-day-workshop/day-three/exercise.md b/iiif-5-day-workshop/day-three/exercise.md deleted file mode 100644 index 90ac784e..00000000 --- a/iiif-5-day-workshop/day-three/exercise.md +++ /dev/null @@ -1,230 +0,0 @@ -## Annotations Exercise - -Let's try out some of the concepts we talked about previously. - -> This example is taken from a manifest and question Ethan Gruber of the American Numismatic Society had in the IIIF Slack. - -Here is a manifest we'll use as our starting point for working with annotations (you can also find this file here: https://gist.github.com/hadro/c499d26943c45bf38eacfaed07b0a8ea) - -``` -{ - "@context": "http://iiif.io/api/presentation/2/context.json", - "@id": "http://localhost:8887/coin-before.json", - "@type": "sc:Manifest", - "attribution": "American Numismatic Society", - "label": "Price 3210", - "description": "Obverse: Head of beardless Heracles right wearing lion skin headdress\nReverse: ΑΛΕΞΑΝΔΡΟΥ - Zeus seated on stool-throne left, eagle on outstretched right hand, sceptre in left hand", - "sequences": [ - { - "@type": "sc:Sequence", - "label": "Default sequence", - "canvases": [ - { - "@id": "http://localhost:8887/coin/canvas", - "@type": "sc:Canvas", - "label": "[Monnaie : Tétradrachme, Argent, Damascus, Koïlé Syrie, Alexandre III Le Grand]", - "height": 2610, - "width": 2610, - "images": [ - { - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f1", - "@type": "oa:Annotation", - "motivation": "sc:painting", - "on": "http://localhost:8887/coin/canvas", - "resource": { - "label": "Obverse", - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f1/full/full/0/native.jpg", - "@type": "dctypes:Image", - "format": "image/jpeg", - "height": 2610, - "width": 2610, - "service": { - "@context": "http://iiif.io/api/image/1/context.json", - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f1", - "profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2" - } - } - }, - { - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f2", - "@type": "oa:Annotation", - "motivation": "sc:painting", - "on": "http://localhost:8887/coin/canvas", - "resource": { - "label": "Reverse", - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f2/full/full/0/native.jpg", - "@type": "dctypes:Image", - "format": "image/jpeg", - "height": 2610, - "width": 2610, - "service": { - "@context": "http://iiif.io/api/image/1/context.json", - "@id": "http://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f2", - "profile": "http://library.stanford.edu/iiif/image-api/1.1/compliance.html#level2" - } - } - } - ] - } - ] - } - ] -} -``` - - - - -Try it! - -Copy the manifest above and save it to your dhsi2019 folder with the filename "coin.json". - -Now, to be able to view it from our local machine, we'll need a simple web server. - ---- - -## Chrome Web Server - -Go here (must do this in Google Chrome): -https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en - -Click "Launch App" if it says that in the top right (that means it's already installed, we just have to configure it); Click "Add to Chrome" if it's not installed already. Once it's installed, click the link and then click "Launch App" - -Where it says "Choose Folder", use that dialog window to select your "dhsi2019" folder on your computer. Once that's done, the Chrome Web Server console should read "Current: /dhsi2019" - -Click "Advanced Settings", and make sure "Set CORS headers" has a blue check next to it. - -Now the Web Server running in chrome should be all set up. - -## Viewing our coin manifest - -If you click this link, you should then see a web page that lists the contents of that folder in the browser: -http://127.0.0.1:8887/ - -Make sure you copied the [above manifest](https://gist.githubusercontent.com/hadro/c499d26943c45bf38eacfaed07b0a8ea/raw/0962500ab9d0d220d7177c5155ef9eccd0095f40/coin-before.json) into a file named “coin.json” in your "dhsi2019" folder, wich you’re using for your web server. - -Make sure you can open the JSON at http://localhost:8887/coin.json - -Open this link in a new tab: [LINK](./mirador.html) -This is a hosted version of Mirador that will work well with our annotations exercise. Keep this tab open with Mirador in it as we work through manifest and annotation exercises below (you may need to refresh the tab when loading a new manifest, or if you've changed the manifest since you last loaded it). - -Copy the link to your coin manifest: http://localhost:8887/coin.json -In the Mirador tab, click "AddItem". In the top right, where it says "addNewObject", paste the URL to your coin manifest there. You should see it added to the top of the list just below. Click on the coin thumbnail. - -This manifest already has two images on the single canvas. When you view it in Mirador only one shows up. The last image annotated onto the canvas covers over the the first image. - -To see the other side of the coin open up the layers panel in Mirador and turn off the visibility of the second image. The layers panel is the icon to the left of where it says "Price 3210", the three horizontal lines. - -Here’s a video of what this ought to look like: -http://ronallo.com/iiif-workshop-new/video/coin-before.mp4 - -## Modifying the Manifest - -We now want these to show up side-by-side on the same canvas. As you make changes you may need to reload the Mirador page and re-add the coin.json manifest back into Mirador. - -To make the coin faces side by side, you’ll need to do two things: - -- Change the dimensions of the canvas so that it can hold two images that are each 2610 pixels wide by 2610 pixels high. - -> What’s the width of the canvas needed to hold both images side-by-side? -> Where in the coin.json manifest do you need to change that value for the canvas? - -- Annotate each image onto a region of the canvas. - -> Change the `on` property to include information for where on the canvas the image ought to be placed. A fragment needs to be added to this URI to indicate the right portion of the canvas. - ->Consider taking a piece of paper to sketch out the layout and do the math. Note that counting pixels starts a zero. - - -## Answer - -> The width of the final canvas should be 5220 pixels wide. - -> The first image should be off to the left and the second image to the right using these values at the end of the on parameter for each image. -- first image: #xywh=0,0,2610,2610 -- second image: #xywh=2610,0,2610,2610 - -Compare your coin manifest to the [final manifest here]( -https://gist.githubusercontent.com/hadro/ccccd581071e948086c8a6200f951d9f/raw/dd0a1b80c9387e5391e8d433b569d306c136bc67/coin-after.json -). If you like, copy that JSON and save it as “coin.json” and load it into Mirador again (remember that you will have to turn on the layers to see the images, but now, when you turn each one on in turn, they should appear side by side) - -In the end you ought to see something like the following: - -![Full coin example](http://ronallo.com/iiif-workshop-new/images/coin-side-by-side.png) - - -## Adding an Annotation List - -Copy the text of this annotation list template and save it as a new file called "annotation-list.json" in your dhsi2019 folder: -https://gist.github.com/hadro/4c6f2eab360813f7f9eb59eac4393b62 - -This annotation list contains just one text annotation at this point, and specifies a box around Zeus's head. - -We need to do one more thing to get this annotation list to work -- add in a reference to it in our coin manifest. - -We do this via an element called "otherContent", which is a way of including annotations that are not additional images we're painting onto the canvas. - -An example looks like this: - -```json - "otherContent": [ - { - "@id": "http://localhost:8887/annotation-list.json", - "@type": "sc:AnnotationList" - } - ] -``` - -This goes after line 60 if you're using our coin manifest; make sure you add a comma after the end of the "images" list. What that does is simply tell the viewer that there is additional information in the form of an annotation list, and that it should look for the list at the URI identified in "@id". - -Look at your coin manifest here, and see if the "otherContent" appears in the right place (after the "images" section): -http://localhost:8887/coin.json - -(If that isn't working, try comparing to this finalized coin manifest and see if you can diagnose: https://gist.github.com/hadro/5ae8fbae0301c6589e5f8db42ef25681 or copy and paste that manifest content to continue to the next part.) - - -If that looks right, try adding that manifest again into the Mirador tab you have open ([Here's the link](./mirador.html) if you need it again). Now, after you turn on the layers again, click the icon that looks like speech bubbles in the upper left side of the screen. You should see an annotation box appear aroun Zeus's head on the right side of the image! - -## Adding Annotations - -Now we're going to extend that annotation list to add another one or more text annotations to our canvas. - -We've already got an annotation box around Zeus's head. Next, we're going to create an annotation around the eagle in Zeu's right hand. - -To start, we need to add another resource to our resource list in the annotation-list.json file. - -From that file, copy lines 6-16 to your clipboard. - -Then add a comma line 16, and hit return for a new line. - -Paste the contents of your clipboard. You should now have two identical sections within the "resources" element. - -Now that we've done that, think through what we need to change in this second annotation resource section to accomplish this. - -Make a note of the line numbers you think need to be updated to make a new annotation work. - -Answer: At the least, we need to update: -- Line 18 (the "id" of the new annotation) -- Line 24 (the "chars" or character content of the annotation) -- Line 26 (the fragment at the end of the "on" resource which tells Mirador where to draw the box) - -Line 18 needs to have a unique "id", so you can just update the last character to 2 instead of 1. - -Line 24 should describe our new annotation (maybe "Eagle in Zeus's hand") - -Line 26 needs new coordinates for the fragment. - -To do this, you can use this tool which will show you the x, y, width, and height you need for the fragment: -https://bl.ocks.org/hadro/raw/3c0f539d61345aa6fdb6fe7a4625f161/ -(Or if you want to try it on 'expert' mode, you can do it via manipulating the crop portion of the [IIIF Image API URL](https://gallica.bnf.fr/iiif/ark:/12148/btv1b8499946f/f2/full/full/0/native.jpg) directly until you find the right section you want :) ) - -But remember, since we've doubled the size of our canvas to include both sides of the coin, you'll have to do some math to make the numbers right for the fragment in the context of our canvas (hint: add 2610 to the x coordinate part of the fragment) - -Further work to think through: - -- What would you have to change to associate annotation lists with a multipage item or other kinds of manifest with more complex sequences? -- Can you have more than one annotation list? (Hint: read through what the specs say about including annotation lists) - -Finally, if that's all working for you, think through then how you might incorporate annotation lists into your own manifest and projects, and in what whay they might be useful to you. - - diff --git a/iiif-5-day-workshop/day-three/mirador/ZeroClipboard.swf b/iiif-5-day-workshop/day-three/mirador/ZeroClipboard.swf deleted file mode 100755 index d4e2561b..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/ZeroClipboard.swf and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.css b/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.css deleted file mode 100755 index 00177068..00000000 --- a/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.css +++ /dev/null @@ -1,3820 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -button { - overflow: visible; -} -button, -select { - text-transform: none; -} -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; -} -button[disabled], -html input[disabled] { - cursor: default; -} -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} -input { - line-height: normal; -} -input[type="checkbox"], -input[type="radio"] { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - padding: 0; -} -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; -} -input[type="search"] { - -webkit-appearance: textfield; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} -*:before, -*:after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -[role="button"] { - cursor: pointer; -} -.btn { - display: inline-block; - margin-bottom: 0; - font-weight: normal; - text-align: center; - vertical-align: middle; - -ms-touch-action: manipulation; - touch-action: manipulation; - cursor: pointer; - background-image: none; - border: 1px solid transparent; - white-space: nowrap; - padding: 6px 12px; - font-size: 14px; - line-height: 1.42857143; - border-radius: 4px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} -.btn:focus, -.btn:active:focus, -.btn.active:focus, -.btn.focus, -.btn:active.focus, -.btn.active.focus { - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px; -} -.btn:hover, -.btn:focus, -.btn.focus { - color: #333333; - text-decoration: none; -} -.btn:active, -.btn.active { - outline: 0; - background-image: none; - -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); - box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); -} -.btn.disabled, -.btn[disabled], -fieldset[disabled] .btn { - cursor: not-allowed; - opacity: 0.65; - filter: alpha(opacity=65); - -webkit-box-shadow: none; - box-shadow: none; -} -a.btn.disabled, -fieldset[disabled] a.btn { - pointer-events: none; -} -.btn-default { - color: #333333; - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default:focus, -.btn-default.focus { - color: #333333; - background-color: #e6e6e6; - border-color: #8c8c8c; -} -.btn-default:hover { - color: #333333; - background-color: #e6e6e6; - border-color: #adadad; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - color: #333333; - background-color: #e6e6e6; - border-color: #adadad; -} -.btn-default:active:hover, -.btn-default.active:hover, -.open > .dropdown-toggle.btn-default:hover, -.btn-default:active:focus, -.btn-default.active:focus, -.open > .dropdown-toggle.btn-default:focus, -.btn-default:active.focus, -.btn-default.active.focus, -.open > .dropdown-toggle.btn-default.focus { - color: #333333; - background-color: #d4d4d4; - border-color: #8c8c8c; -} -.btn-default:active, -.btn-default.active, -.open > .dropdown-toggle.btn-default { - background-image: none; -} -.btn-default.disabled:hover, -.btn-default[disabled]:hover, -fieldset[disabled] .btn-default:hover, -.btn-default.disabled:focus, -.btn-default[disabled]:focus, -fieldset[disabled] .btn-default:focus, -.btn-default.disabled.focus, -.btn-default[disabled].focus, -fieldset[disabled] .btn-default.focus { - background-color: #ffffff; - border-color: #cccccc; -} -.btn-default .badge { - color: #ffffff; - background-color: #333333; -} -.btn-primary { - color: #ffffff; - background-color: #337ab7; - border-color: #2e6da4; -} -.btn-primary:focus, -.btn-primary.focus { - color: #ffffff; - background-color: #286090; - border-color: #122b40; -} -.btn-primary:hover { - color: #ffffff; - background-color: #286090; - border-color: #204d74; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - color: #ffffff; - background-color: #286090; - border-color: #204d74; -} -.btn-primary:active:hover, -.btn-primary.active:hover, -.open > .dropdown-toggle.btn-primary:hover, -.btn-primary:active:focus, -.btn-primary.active:focus, -.open > .dropdown-toggle.btn-primary:focus, -.btn-primary:active.focus, -.btn-primary.active.focus, -.open > .dropdown-toggle.btn-primary.focus { - color: #ffffff; - background-color: #204d74; - border-color: #122b40; -} -.btn-primary:active, -.btn-primary.active, -.open > .dropdown-toggle.btn-primary { - background-image: none; -} -.btn-primary.disabled:hover, -.btn-primary[disabled]:hover, -fieldset[disabled] .btn-primary:hover, -.btn-primary.disabled:focus, -.btn-primary[disabled]:focus, -fieldset[disabled] .btn-primary:focus, -.btn-primary.disabled.focus, -.btn-primary[disabled].focus, -fieldset[disabled] .btn-primary.focus { - background-color: #337ab7; - border-color: #2e6da4; -} -.btn-primary .badge { - color: #337ab7; - background-color: #ffffff; -} -.btn-success { - color: #ffffff; - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success:focus, -.btn-success.focus { - color: #ffffff; - background-color: #449d44; - border-color: #255625; -} -.btn-success:hover { - color: #ffffff; - background-color: #449d44; - border-color: #398439; -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - color: #ffffff; - background-color: #449d44; - border-color: #398439; -} -.btn-success:active:hover, -.btn-success.active:hover, -.open > .dropdown-toggle.btn-success:hover, -.btn-success:active:focus, -.btn-success.active:focus, -.open > .dropdown-toggle.btn-success:focus, -.btn-success:active.focus, -.btn-success.active.focus, -.open > .dropdown-toggle.btn-success.focus { - color: #ffffff; - background-color: #398439; - border-color: #255625; -} -.btn-success:active, -.btn-success.active, -.open > .dropdown-toggle.btn-success { - background-image: none; -} -.btn-success.disabled:hover, -.btn-success[disabled]:hover, -fieldset[disabled] .btn-success:hover, -.btn-success.disabled:focus, -.btn-success[disabled]:focus, -fieldset[disabled] .btn-success:focus, -.btn-success.disabled.focus, -.btn-success[disabled].focus, -fieldset[disabled] .btn-success.focus { - background-color: #5cb85c; - border-color: #4cae4c; -} -.btn-success .badge { - color: #5cb85c; - background-color: #ffffff; -} -.btn-info { - color: #ffffff; - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info:focus, -.btn-info.focus { - color: #ffffff; - background-color: #31b0d5; - border-color: #1b6d85; -} -.btn-info:hover { - color: #ffffff; - background-color: #31b0d5; - border-color: #269abc; -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - color: #ffffff; - background-color: #31b0d5; - border-color: #269abc; -} -.btn-info:active:hover, -.btn-info.active:hover, -.open > .dropdown-toggle.btn-info:hover, -.btn-info:active:focus, -.btn-info.active:focus, -.open > .dropdown-toggle.btn-info:focus, -.btn-info:active.focus, -.btn-info.active.focus, -.open > .dropdown-toggle.btn-info.focus { - color: #ffffff; - background-color: #269abc; - border-color: #1b6d85; -} -.btn-info:active, -.btn-info.active, -.open > .dropdown-toggle.btn-info { - background-image: none; -} -.btn-info.disabled:hover, -.btn-info[disabled]:hover, -fieldset[disabled] .btn-info:hover, -.btn-info.disabled:focus, -.btn-info[disabled]:focus, -fieldset[disabled] .btn-info:focus, -.btn-info.disabled.focus, -.btn-info[disabled].focus, -fieldset[disabled] .btn-info.focus { - background-color: #5bc0de; - border-color: #46b8da; -} -.btn-info .badge { - color: #5bc0de; - background-color: #ffffff; -} -.btn-warning { - color: #ffffff; - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning:focus, -.btn-warning.focus { - color: #ffffff; - background-color: #ec971f; - border-color: #985f0d; -} -.btn-warning:hover { - color: #ffffff; - background-color: #ec971f; - border-color: #d58512; -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - color: #ffffff; - background-color: #ec971f; - border-color: #d58512; -} -.btn-warning:active:hover, -.btn-warning.active:hover, -.open > .dropdown-toggle.btn-warning:hover, -.btn-warning:active:focus, -.btn-warning.active:focus, -.open > .dropdown-toggle.btn-warning:focus, -.btn-warning:active.focus, -.btn-warning.active.focus, -.open > .dropdown-toggle.btn-warning.focus { - color: #ffffff; - background-color: #d58512; - border-color: #985f0d; -} -.btn-warning:active, -.btn-warning.active, -.open > .dropdown-toggle.btn-warning { - background-image: none; -} -.btn-warning.disabled:hover, -.btn-warning[disabled]:hover, -fieldset[disabled] .btn-warning:hover, -.btn-warning.disabled:focus, -.btn-warning[disabled]:focus, -fieldset[disabled] .btn-warning:focus, -.btn-warning.disabled.focus, -.btn-warning[disabled].focus, -fieldset[disabled] .btn-warning.focus { - background-color: #f0ad4e; - border-color: #eea236; -} -.btn-warning .badge { - color: #f0ad4e; - background-color: #ffffff; -} -.btn-danger { - color: #ffffff; - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger:focus, -.btn-danger.focus { - color: #ffffff; - background-color: #c9302c; - border-color: #761c19; -} -.btn-danger:hover { - color: #ffffff; - background-color: #c9302c; - border-color: #ac2925; -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - color: #ffffff; - background-color: #c9302c; - border-color: #ac2925; -} -.btn-danger:active:hover, -.btn-danger.active:hover, -.open > .dropdown-toggle.btn-danger:hover, -.btn-danger:active:focus, -.btn-danger.active:focus, -.open > .dropdown-toggle.btn-danger:focus, -.btn-danger:active.focus, -.btn-danger.active.focus, -.open > .dropdown-toggle.btn-danger.focus { - color: #ffffff; - background-color: #ac2925; - border-color: #761c19; -} -.btn-danger:active, -.btn-danger.active, -.open > .dropdown-toggle.btn-danger { - background-image: none; -} -.btn-danger.disabled:hover, -.btn-danger[disabled]:hover, -fieldset[disabled] .btn-danger:hover, -.btn-danger.disabled:focus, -.btn-danger[disabled]:focus, -fieldset[disabled] .btn-danger:focus, -.btn-danger.disabled.focus, -.btn-danger[disabled].focus, -fieldset[disabled] .btn-danger.focus { - background-color: #d9534f; - border-color: #d43f3a; -} -.btn-danger .badge { - color: #d9534f; - background-color: #ffffff; -} -.btn-link { - color: #337ab7; - font-weight: normal; - border-radius: 0; -} -.btn-link, -.btn-link:active, -.btn-link.active, -.btn-link[disabled], -fieldset[disabled] .btn-link { - background-color: transparent; - -webkit-box-shadow: none; - box-shadow: none; -} -.btn-link, -.btn-link:hover, -.btn-link:focus, -.btn-link:active { - border-color: transparent; -} -.btn-link:hover, -.btn-link:focus { - color: #23527c; - text-decoration: underline; - background-color: transparent; -} -.btn-link[disabled]:hover, -fieldset[disabled] .btn-link:hover, -.btn-link[disabled]:focus, -fieldset[disabled] .btn-link:focus { - color: #777777; - text-decoration: none; -} -.btn-lg { - padding: 10px 16px; - font-size: 18px; - line-height: 1.3333333; - border-radius: 6px; -} -.btn-sm { - padding: 5px 10px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-xs { - padding: 1px 5px; - font-size: 12px; - line-height: 1.5; - border-radius: 3px; -} -.btn-block { - display: block; - width: 100%; -} -.btn-block + .btn-block { - margin-top: 5px; -} -input[type="submit"].btn-block, -input[type="reset"].btn-block, -input[type="button"].btn-block { - width: 100%; -} -.fade { - opacity: 0; - -webkit-transition: opacity 0.15s linear; - -o-transition: opacity 0.15s linear; - transition: opacity 0.15s linear; -} -.fade.in { - opacity: 1; -} -.collapse { - display: none; -} -.collapse.in { - display: block; -} -tr.collapse.in { - display: table-row; -} -tbody.collapse.in { - display: table-row-group; -} -.collapsing { - position: relative; - height: 0; - overflow: hidden; - -webkit-transition-property: height, visibility; - -o-transition-property: height, visibility; - transition-property: height, visibility; - -webkit-transition-duration: 0.35s; - -o-transition-duration: 0.35s; - transition-duration: 0.35s; - -webkit-transition-timing-function: ease; - -o-transition-timing-function: ease; - transition-timing-function: ease; -} -.close { - float: right; - font-size: 21px; - font-weight: bold; - line-height: 1; - color: #000000; - text-shadow: 0 1px 0 #ffffff; - opacity: 0.2; - filter: alpha(opacity=20); -} -.close:hover, -.close:focus { - color: #000000; - text-decoration: none; - cursor: pointer; - opacity: 0.5; - filter: alpha(opacity=50); -} -button.close { - padding: 0; - cursor: pointer; - background: transparent; - border: 0; - -webkit-appearance: none; -} -.modal-open { - overflow: hidden; -} -.modal { - display: none; - overflow: hidden; - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1050; - -webkit-overflow-scrolling: touch; - outline: 0; -} -.modal.fade .modal-dialog { - -webkit-transform: translate(0, -25%); - -ms-transform: translate(0, -25%); - -o-transform: translate(0, -25%); - transform: translate(0, -25%); - -webkit-transition: -webkit-transform 0.3s ease-out; - -o-transition: -o-transform 0.3s ease-out; - transition: transform 0.3s ease-out; -} -.modal.in .modal-dialog { - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); -} -.modal-open .modal { - overflow-x: hidden; - overflow-y: auto; -} -.modal-dialog { - position: relative; - width: auto; - margin: 10px; -} -.modal-content { - position: relative; - background-color: #ffffff; - border: 1px solid #999999; - border: 1px solid rgba(0, 0, 0, 0.2); - border-radius: 6px; - -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); - -webkit-background-clip: padding-box; - background-clip: padding-box; - outline: 0; -} -.modal-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 1040; - background-color: #000000; -} -.modal-backdrop.fade { - opacity: 0; - filter: alpha(opacity=0); -} -.modal-backdrop.in { - opacity: 0.5; - filter: alpha(opacity=50); -} -.modal-header { - padding: 15px; - border-bottom: 1px solid #e5e5e5; -} -.modal-header .close { - margin-top: -2px; -} -.modal-title { - margin: 0; - line-height: 1.42857143; -} -.modal-body { - position: relative; - padding: 15px; -} -.modal-footer { - padding: 15px; - text-align: right; - border-top: 1px solid #e5e5e5; -} -.modal-footer .btn + .btn { - margin-left: 5px; - margin-bottom: 0; -} -.modal-footer .btn-group .btn + .btn { - margin-left: -1px; -} -.modal-footer .btn-block + .btn-block { - margin-left: 0; -} -.modal-scrollbar-measure { - position: absolute; - top: -9999px; - width: 50px; - height: 50px; - overflow: scroll; -} -@media (min-width: 768px) { - .modal-dialog { - width: 600px; - margin: 30px auto; - } - .modal-content { - -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); - } - .modal-sm { - width: 300px; - } -} -@media (min-width: 992px) { - .modal-lg { - width: 900px; - } -} -.clearfix:before, -.clearfix:after, -.modal-header:before, -.modal-header:after, -.modal-footer:before, -.modal-footer:after { - content: " "; - display: table; -} -.clearfix:after, -.modal-header:after, -.modal-footer:after { - clear: both; -} -.center-block { - display: block; - margin-left: auto; - margin-right: auto; -} -.pull-right { - float: right !important; -} -.pull-left { - float: left !important; -} -.hide { - display: none !important; -} -.show { - display: block !important; -} -.invisible { - visibility: hidden; -} -.text-hide { - font: 0/0 a; - color: transparent; - text-shadow: none; - background-color: transparent; - border: 0; -} -.hidden { - display: none !important; -} -.affix { - position: fixed; -} -/*! normalize.css v2.1.2 | MIT License | git.io/normalize */ - -/* ========================================================================== - HTML5 display definitions - ========================================================================== */ - -/** - * Correct `block` display not defined in IE 8/9. - */ - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; -} - -/** - * Correct `inline-block` display not defined in IE 8/9. - */ - -audio, -canvas, -video { - display: inline-block; -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ - -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address styling not present in IE 8/9. - */ - -[hidden] { - display: none; -} - -/* ========================================================================== - Base - ========================================================================== */ - -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ - -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ - -body { - margin: 0; -} - -/* ========================================================================== - Links - ========================================================================== */ - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ - -a:active, -a:hover { - outline: 0; -} - -/* ========================================================================== - Typography - ========================================================================== */ - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari 5, and Chrome. - */ - -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9, Safari 5, and Chrome. - */ - -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. - */ - -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari 5 and Chrome. - */ - -dfn { - font-style: italic; -} - -/** - * Address differences between Firefox and other browsers. - */ - -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; - border:0; - border-bottom:1px solid rgba(0,0,0,0.4); -} - -/** - * Address styling not present in IE 8/9. - */ - -mark { - background: #ff0; - color: #000; -} - -/** - * Correct font family set oddly in Safari 5 and Chrome. - */ - -code, -kbd, -pre, -samp { - font-family: monospace, serif; - font-size: 1em; -} - -/** - * Improve readability of pre-formatted text in all browsers. - */ - -pre { - white-space: pre-wrap; -} - -/** - * Set consistent quote types. - */ - -q { - quotes: "\201C" "\201D" "\2018" "\2019"; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ - -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ - -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* ========================================================================== - Embedded content - ========================================================================== */ - -/** - * Remove border when inside `a` element in IE 8/9. - */ - -img { - border: 0; -} - -/** - * Correct overflow displayed oddly in IE 9. - */ - -svg:not(:root) { - overflow: hidden; -} - -/* ========================================================================== - Figures - ========================================================================== */ - -/** - * Address margin not present in IE 8/9 and Safari 5. - */ - -figure { - margin: 0; -} - -/* ========================================================================== - Forms - ========================================================================== */ - -/** - * Define consistent border, margin, and padding. - */ - -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ - -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * 1. Correct font family not being inherited in all browsers. - * 2. Correct font size not being inherited in all browsers. - * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. - */ - -button, -input, -select, -textarea { - font-family: inherit; /* 1 */ - font-size: 100%; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ - -button, -input { - line-height: normal; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. - * Correct `select` style inheritance in Firefox 4+ and Opera. - */ - -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ - -button, -html input[type="button"], /* 1 */ -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ - -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * 1. Address box sizing set to `content-box` in IE 8/9. - * 2. Remove excess padding in IE 8/9. - */ - -input[type="checkbox"], -input[type="radio"] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome - * (include `-moz` to future-proof). - */ - -input[type="search"] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari 5 and Chrome - * on OS X. - */ - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * 1. Remove default vertical scrollbar in IE 8/9. - * 2. Improve readability and alignment in all browsers. - */ - -textarea { - overflow: auto; /* 1 */ - vertical-align: top; /* 2 */ -} - -/* ========================================================================== - Tables - ========================================================================== */ - -/** - * Remove most spacing between table cells. - */ - -table { - border-collapse: collapse; - border-spacing: 0; -} - - -/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} - -/*! jQuery UI - v1.11.4 - 2016-04-08 -* http://jqueryui.com -* Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/ -* Copyright jQuery Foundation and other contributors; Licensed MIT */ - -.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:0.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-disabled .ui-resizable-handle,.ui-resizable-autohide .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted black}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:link,.ui-button:visited,.ui-button:hover,.ui-button:active{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon,.ui-button-icons-only .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary,.ui-button-icons-only .ui-button-icon-primary{left:.5em}.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary,.ui-button-icons-only .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}input.ui-button::-moz-focus-inner,button.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:none;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:none}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url("data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==");height:100%;filter:alpha(opacity=25);opacity:0.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:bold;line-height:1.5;padding:2px 0.4em;margin:0.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:0.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:0.4em 2.1em 0.4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:none;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:none}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url("images/ui-bg_highlight-soft_75_cccccc_1x100.png") 50% 50% repeat-x;color:#222;font-weight:bold}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url("images/ui-bg_glass_75_e6e6e6_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #999;background:#dadada url("images/ui-bg_glass_75_dadada_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url("images/ui-bg_glass_65_ffffff_1x400.png") 50% 50% repeat-x;font-weight:normal;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url("images/ui-bg_glass_55_fbf9ee_1x400.png") 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url("images/ui-bg_glass_95_fef1ec_1x400.png") 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_222222_256x240.png")}.ui-state-default .ui-icon{background-image:url("images/ui-icons_888888_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-active .ui-icon{background-image:url("images/ui-icons_454545_256x240.png")}.ui-state-highlight .ui-icon{background-image:url("images/ui-icons_2e83ff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cd0a0a_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:4px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px} -/* qTip2 v2.2.1 | Plugins: tips modal viewport svg imagemap ie6 | Styles: core basic css3 | qtip2.com | Licensed MIT | Sat Sep 06 2014 23:12:07 */ - -.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;direction:ltr;box-shadow:none;padding:0}.qtip-content{position:relative;padding:5px 9px;overflow:hidden;text-align:left;word-wrap:break-word}.qtip-titlebar{position:relative;padding:5px 35px 5px 10px;overflow:hidden;border-width:0 0 1px;font-weight:700}.qtip-titlebar+.qtip-content{border-top-width:0!important}.qtip-close{position:absolute;right:-9px;top:-9px;z-index:11;cursor:pointer;outline:0;border:1px solid transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-icon .ui-icon,.qtip-titlebar .ui-icon{display:block;text-indent:-1000em;direction:ltr}.qtip-icon,.qtip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.qtip-icon .ui-icon{width:18px;height:14px;line-height:14px;text-align:center;text-indent:0;font:400 bold 10px/13px Tahoma,sans-serif;color:inherit;background:-100em -100em no-repeat}.qtip-default{border:1px solid #F1D031;background-color:#FFFFA3;color:#555}.qtip-default .qtip-titlebar{background-color:#FFEF93}.qtip-default .qtip-icon{border-color:#CCC;background:#F1F1F1;color:#777}.qtip-default .qtip-titlebar .qtip-close{border-color:#AAA;color:#111}.qtip-light{background-color:#fff;border-color:#E2E2E2;color:#454545}.qtip-light .qtip-titlebar{background-color:#f1f1f1}.qtip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.qtip-dark .qtip-titlebar{background-color:#404040}.qtip-dark .qtip-icon{border-color:#444}.qtip-dark .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-cream{background-color:#FBF7AA;border-color:#F9E98E;color:#A27D35}.qtip-cream .qtip-titlebar{background-color:#F0DE7D}.qtip-cream .qtip-close .qtip-icon{background-position:-82px 0}.qtip-red{background-color:#F78B83;border-color:#D95252;color:#912323}.qtip-red .qtip-titlebar{background-color:#F06D65}.qtip-red .qtip-close .qtip-icon{background-position:-102px 0}.qtip-red .qtip-icon,.qtip-red .qtip-titlebar .ui-state-hover{border-color:#D95252}.qtip-green{background-color:#CAED9E;border-color:#90D93F;color:#3F6219}.qtip-green .qtip-titlebar{background-color:#B0DE78}.qtip-green .qtip-close .qtip-icon{background-position:-42px 0}.qtip-blue{background-color:#E5F6FE;border-color:#ADD9ED;color:#5E99BD}.qtip-blue .qtip-titlebar{background-color:#D0E9F5}.qtip-blue .qtip-close .qtip-icon{background-position:-2px 0}.qtip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.qtip-bootstrap,.qtip-rounded,.qtip-tipsy{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.qtip-rounded .qtip-titlebar{-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.qtip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border:0 solid transparent;background:#4A4A4A;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4A4A4A),color-stop(100%,#000));background-image:-webkit-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-moz-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-ms-linear-gradient(top,#4A4A4A 0,#000 100%);background-image:-o-linear-gradient(top,#4A4A4A 0,#000 100%)}.qtip-youtube .qtip-titlebar{background-color:transparent}.qtip-youtube .qtip-content{padding:.75em;font:12px arial,sans-serif;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#4a4a4a, EndColorStr=#000000);-ms-filter:"progid:DXImageTransform.Microsoft.Gradient(GradientType=0,StartColorStr=#4a4a4a,EndColorStr=#000000);"}.qtip-youtube .qtip-icon{border-color:#222}.qtip-youtube .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-linear-gradient(top,#717171,#232323);background-image:-ms-linear-gradient(top,#717171,#232323);background-image:-o-linear-gradient(top,#717171,#232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.qtip-jtools .qtip-titlebar{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171, endColorstr=#4A4A4A);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#717171,endColorstr=#4A4A4A)"}.qtip-jtools .qtip-content{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A, endColorstr=#232323);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#4A4A4A,endColorstr=#232323)"}.qtip-jtools .qtip-content,.qtip-jtools .qtip-titlebar{background:0 0;color:#fff;border:0 dashed transparent}.qtip-jtools .qtip-icon{border-color:#555}.qtip-jtools .qtip-titlebar .ui-state-hover{border-color:#333}.qtip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#D9D9C2;color:#111;border:0 dashed transparent}.qtip-cluetip .qtip-titlebar{background-color:#87876A;color:#fff;border:0 dashed transparent}.qtip-cluetip .qtip-icon{border-color:#808064}.qtip-cluetip .qtip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.qtip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px #000}.qtip-tipsy .qtip-titlebar{padding:6px 35px 0 10px;background-color:transparent}.qtip-tipsy .qtip-content{padding:6px 10px}.qtip-tipsy .qtip-icon{border-color:#222;text-shadow:none}.qtip-tipsy .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-tipped{border:3px solid #959FA9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#F9F9F9;color:#454545;font-weight:400;font-family:serif}.qtip-tipped .qtip-titlebar{border-bottom-width:0;color:#fff;background:#3A79B8;background-image:-webkit-gradient(linear,left top,left bottom,from(#3A79B8),to(#2E629D));background-image:-webkit-linear-gradient(top,#3A79B8,#2E629D);background-image:-moz-linear-gradient(top,#3A79B8,#2E629D);background-image:-ms-linear-gradient(top,#3A79B8,#2E629D);background-image:-o-linear-gradient(top,#3A79B8,#2E629D);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8, endColorstr=#2E629D);-ms-filter:"progid:DXImageTransform.Microsoft.gradient(startColorstr=#3A79B8,endColorstr=#2E629D)"}.qtip-tipped .qtip-icon{border:2px solid #285589;background:#285589}.qtip-tipped .qtip-icon .ui-icon{background-color:#FBFBFB;color:#555}.qtip-bootstrap{font-size:14px;line-height:20px;color:#333;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.qtip-bootstrap .qtip-titlebar{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.qtip-bootstrap .qtip-titlebar .qtip-close{right:11px;top:45%;border-style:none}.qtip-bootstrap .qtip-content{padding:9px 14px}.qtip-bootstrap .qtip-icon{background:0 0}.qtip-bootstrap .qtip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.qtip-bootstrap .qtip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;filter:alpha(opacity=40)}.qtip:not(.ie9haxors) div.qtip-content,.qtip:not(.ie9haxors) div.qtip-titlebar{filter:none;-ms-filter:none}.qtip .qtip-tip{margin:0 auto;overflow:hidden;z-index:10}.qtip .qtip-tip,x:-o-prefocus{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:0 0;border:0 dashed transparent}.qtip .qtip-tip canvas{top:0;left:0}.qtip .qtip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed;left:0;top:0;width:100%;height:100%}#qtip-overlay.blurs{cursor:pointer}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#000;opacity:.7;filter:alpha(opacity=70);-ms-filter:"alpha(Opacity=70)"}.qtipmodal-ie6fix{position:absolute!important} -/*** -Spectrum Colorpicker v1.8.0 -https://github.com/bgrins/spectrum -Author: Brian Grinstead -License: MIT -***/ - -.sp-container { - position:absolute; - top:0; - left:0; - display:inline-block; - *display: inline; - *zoom: 1; - /* https://github.com/bgrins/spectrum/issues/40 */ - z-index: 9999994; - overflow: hidden; -} -.sp-container.sp-flat { - position: relative; -} - -/* Fix for * { box-sizing: border-box; } */ -.sp-container, -.sp-container * { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -/* http://ansciath.tumblr.com/post/7347495869/css-aspect-ratio */ -.sp-top { - position:relative; - width: 100%; - display:inline-block; -} -.sp-top-inner { - position:absolute; - top:0; - left:0; - bottom:0; - right:0; -} -.sp-color { - position: absolute; - top:0; - left:0; - bottom:0; - right:20%; -} -.sp-hue { - position: absolute; - top:0; - right:0; - bottom:0; - left:84%; - height: 100%; -} - -.sp-clear-enabled .sp-hue { - top:33px; - height: 77.5%; -} - -.sp-fill { - padding-top: 80%; -} -.sp-sat, .sp-val { - position: absolute; - top:0; - left:0; - right:0; - bottom:0; -} - -.sp-alpha-enabled .sp-top { - margin-bottom: 18px; -} -.sp-alpha-enabled .sp-alpha { - display: block; -} -.sp-alpha-handle { - position:absolute; - top:-4px; - bottom: -4px; - width: 6px; - left: 50%; - cursor: pointer; - border: 1px solid black; - background: white; - opacity: .8; -} -.sp-alpha { - display: none; - position: absolute; - bottom: -14px; - right: 0; - left: 0; - height: 8px; -} -.sp-alpha-inner { - border: solid 1px #333; -} - -.sp-clear { - display: none; -} - -.sp-clear.sp-clear-display { - background-position: center; -} - -.sp-clear-enabled .sp-clear { - display: block; - position:absolute; - top:0px; - right:0; - bottom:0; - left:84%; - height: 28px; -} - -/* Don't allow text selection */ -.sp-container, .sp-replacer, .sp-preview, .sp-dragger, .sp-slider, .sp-alpha, .sp-clear, .sp-alpha-handle, .sp-container.sp-dragging .sp-input, .sp-container button { - -webkit-user-select:none; - -moz-user-select: -moz-none; - -o-user-select:none; - user-select: none; -} - -.sp-container.sp-input-disabled .sp-input-container { - display: none; -} -.sp-container.sp-buttons-disabled .sp-button-container { - display: none; -} -.sp-container.sp-palette-buttons-disabled .sp-palette-button-container { - display: none; -} -.sp-palette-only .sp-picker-container { - display: none; -} -.sp-palette-disabled .sp-palette-container { - display: none; -} - -.sp-initial-disabled .sp-initial { - display: none; -} - - -/* Gradients for hue, saturation and value instead of images. Not pretty... but it works */ -.sp-sat { - background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(left, #fff, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to right, #fff, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr=#FFFFFFFF, endColorstr=#00CC9A81)"; - filter : progid:DXImageTransform.Microsoft.gradient(GradientType = 1, startColorstr='#FFFFFFFF', endColorstr='#00CC9A81'); -} -.sp-val { - background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); - background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); - background-image: -moz-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -o-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: -ms-linear-gradient(bottom, #000, rgba(204, 154, 129, 0)); - background-image: linear-gradient(to top, #000, rgba(204, 154, 129, 0)); - -ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#00CC9A81, endColorstr=#FF000000)"; - filter : progid:DXImageTransform.Microsoft.gradient(startColorstr='#00CC9A81', endColorstr='#FF000000'); -} - -.sp-hue { - background: -moz-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -ms-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -o-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: -webkit-gradient(linear, left top, left bottom, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); - background: -webkit-linear-gradient(top, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); - background: linear-gradient(to bottom, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); -} - -/* IE filters do not support multiple color stops. - Generate 6 divs, line them up, and do two color gradients for each. - Yes, really. - */ -.sp-1 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0000', endColorstr='#ffff00'); -} -.sp-2 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff00', endColorstr='#00ff00'); -} -.sp-3 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ff00', endColorstr='#00ffff'); -} -.sp-4 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffff', endColorstr='#0000ff'); -} -.sp-5 { - height:16%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0000ff', endColorstr='#ff00ff'); -} -.sp-6 { - height:17%; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff', endColorstr='#ff0000'); -} - -.sp-hidden { - display: none !important; -} - -/* Clearfix hack */ -.sp-cf:before, .sp-cf:after { content: ""; display: table; } -.sp-cf:after { clear: both; } -.sp-cf { *zoom: 1; } - -/* Mobile devices, make hue slider bigger so it is easier to slide */ -@media (max-device-width: 480px) { - .sp-color { right: 40%; } - .sp-hue { left: 63%; } - .sp-fill { padding-top: 60%; } -} -.sp-dragger { - border-radius: 5px; - height: 5px; - width: 5px; - border: 1px solid #fff; - background: #000; - cursor: pointer; - position:absolute; - top:0; - left: 0; -} -.sp-slider { - position: absolute; - top:0; - cursor:pointer; - height: 3px; - left: -1px; - right: -1px; - border: 1px solid #000; - background: white; - opacity: .8; -} - -/* -Theme authors: -Here are the basic themeable display options (colors, fonts, global widths). -See http://bgrins.github.io/spectrum/themes/ for instructions. -*/ - -.sp-container { - border-radius: 0; - background-color: #ECECEC; - border: solid 1px #f0c49B; - padding: 0; -} -.sp-container, .sp-container button, .sp-container input, .sp-color, .sp-hue, .sp-clear { - font: normal 12px "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Geneva, Verdana, sans-serif; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - -ms-box-sizing: border-box; - box-sizing: border-box; -} -.sp-top { - margin-bottom: 3px; -} -.sp-color, .sp-hue, .sp-clear { - border: solid 1px #666; -} - -/* Input */ -.sp-input-container { - float:right; - width: 100px; - margin-bottom: 4px; -} -.sp-initial-disabled .sp-input-container { - width: 100%; -} -.sp-input { - font-size: 12px !important; - border: 1px inset; - padding: 4px 5px; - margin: 0; - width: 100%; - background:transparent; - border-radius: 3px; - color: #222; -} -.sp-input:focus { - border: 1px solid orange; -} -.sp-input.sp-validation-error { - border: 1px solid red; - background: #fdd; -} -.sp-picker-container , .sp-palette-container { - float:left; - position: relative; - padding: 10px; - padding-bottom: 300px; - margin-bottom: -290px; -} -.sp-picker-container { - width: 172px; - border-left: solid 1px #fff; -} - -/* Palettes */ -.sp-palette-container { - border-right: solid 1px #ccc; -} - -.sp-palette-only .sp-palette-container { - border: 0; -} - -.sp-palette .sp-thumb-el { - display: block; - position:relative; - float:left; - width: 24px; - height: 15px; - margin: 3px; - cursor: pointer; - border:solid 2px transparent; -} -.sp-palette .sp-thumb-el:hover, .sp-palette .sp-thumb-el.sp-thumb-active { - border-color: orange; -} -.sp-thumb-el { - position:relative; -} - -/* Initial */ -.sp-initial { - float: left; - border: solid 1px #333; -} -.sp-initial span { - width: 30px; - height: 25px; - border:none; - display:block; - float:left; - margin:0; -} - -.sp-initial .sp-clear-display { - background-position: center; -} - -/* Buttons */ -.sp-palette-button-container, -.sp-button-container { - float: right; -} - -/* Replacer (the little preview div that shows up instead of the ) */ -.sp-replacer { - margin:0; - overflow:hidden; - cursor:pointer; - padding: 4px; - display:inline-block; - *zoom: 1; - *display: inline; - border: solid 1px #91765d; - background: #eee; - color: #333; - vertical-align: middle; -} -.sp-replacer:hover, .sp-replacer.sp-active { - border-color: #F0C49B; - color: #111; -} -.sp-replacer.sp-disabled { - cursor:default; - border-color: silver; - color: silver; -} -.sp-dd { - padding: 2px 0; - height: 16px; - line-height: 16px; - float:left; - font-size:10px; -} -.sp-preview { - position:relative; - width:25px; - height: 20px; - border: solid 1px #222; - margin-right: 5px; - float:left; - z-index: 0; -} - -.sp-palette { - *width: 220px; - max-width: 220px; -} -.sp-palette .sp-thumb-el { - width:16px; - height: 16px; - margin:2px 1px; - border: solid 1px #d0d0d0; -} - -.sp-container { - padding-bottom:0; -} - - -/* Buttons: http://hellohappy.org/css3-buttons/ */ -.sp-container button { - background-color: #eeeeee; - background-image: -webkit-linear-gradient(top, #eeeeee, #cccccc); - background-image: -moz-linear-gradient(top, #eeeeee, #cccccc); - background-image: -ms-linear-gradient(top, #eeeeee, #cccccc); - background-image: -o-linear-gradient(top, #eeeeee, #cccccc); - background-image: linear-gradient(to bottom, #eeeeee, #cccccc); - border: 1px solid #ccc; - border-bottom: 1px solid #bbb; - border-radius: 3px; - color: #333; - font-size: 14px; - line-height: 1; - padding: 5px 4px; - text-align: center; - text-shadow: 0 1px 0 #eee; - vertical-align: middle; -} -.sp-container button:hover { - background-color: #dddddd; - background-image: -webkit-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -moz-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -ms-linear-gradient(top, #dddddd, #bbbbbb); - background-image: -o-linear-gradient(top, #dddddd, #bbbbbb); - background-image: linear-gradient(to bottom, #dddddd, #bbbbbb); - border: 1px solid #bbb; - border-bottom: 1px solid #999; - cursor: pointer; - text-shadow: 0 1px 0 #ddd; -} -.sp-container button:active { - border: 1px solid #aaa; - border-bottom: 1px solid #888; - -webkit-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -moz-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -ms-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - -o-box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; - box-shadow: inset 0 0 5px 2px #aaaaaa, 0 1px 0 0 #eeeeee; -} -.sp-cancel { - font-size: 11px; - color: #d93f3f !important; - margin:0; - padding:2px; - margin-right: 5px; - vertical-align: middle; - text-decoration:none; - -} -.sp-cancel:hover { - color: #d93f3f !important; - text-decoration: underline; -} - - -.sp-palette span:hover, .sp-palette span.sp-thumb-active { - border-color: #000; -} - -.sp-preview, .sp-alpha, .sp-thumb-el { - position:relative; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==); -} -.sp-preview-inner, .sp-alpha-inner, .sp-thumb-inner { - display:block; - position:absolute; - top:0;left:0;bottom:0;right:0; -} - -.sp-palette .sp-thumb-inner { - background-position: 50% 50%; - background-repeat: no-repeat; -} - -.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=); -} - -.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=); -} - -.sp-clear-display { - background-repeat:no-repeat; - background-position: center; - background-image: url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==); -} - -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;height:1px !important;margin:-1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} - -/** - * This file is the entry point for Less processing - */ -.mirador-container .mirador-viewer, -.mirador-container .mirador-main-menu-bar, -.mirador-container .mirador-status-bar { - font-family: 'Open Sans', 'Lucida Grande', Verdana, Arial, sans-serif; -} -/* - * jquery-ui-dialog theming/customisation (overrides to reset neutral defaults) - */ -.mirador-container .ui-dialog-titlebar { - display: none; -} -.mirador-container .ui-dialog { - overflow: hidden; - padding: 0; -} -.mirador-container .slot.ui-dialog-content { - margin: 0; -} -.mirador-container .qtip-bootstrap { - border-radius: 2px; - padding: 0; - background-color: #fafafa; -} -.mirador-container .qtip-bootstrap .qtip-content { - padding: 0; - clear: both; -} -.mirador-container .qtip-viewer .qtip-content { - min-width: 275px; - max-height: 200px; - overflow: auto; -} -.mirador-container .qtip-content { - text-align: inherit; -} -.mirador-container .annotation-tooltip { - padding: 10px; -} -.mirador-container .annotation-editor { - cursor: move; -} -.mirador-container .annotation-display { - position: relative; - border-left: 0; - border-right: 0; - padding: 12px; - padding-bottom: 0; - border-bottom: 1px solid gray; -} -.mirador-container .annotation-display:last-child { - border: none; -} -.mirador-container .annotation-tooltip .button-container { - text-align: right; -} -.mirador-container .annotation-tooltip .save, -.mirador-container .annotation-tooltip .cancel { - margin-left: 12px; - /* padding: 5px 7px; */ - /* border-radius: 2px; */ - /* text-decoration: underline; */ - /* color: white; */ - /* background-color: black; */ - font-size: 12px; - text-decoration: underline; -} -.mirador-container .annotation-tooltip .save:hover, -.mirador-container .annotation-tooltip .cancel:hover { - /* padding: 5px 7px; */ - /* border-radius: 2px; */ - /* text-decoration: underline; */ - font-weight: bold; - /* color: white; */ - /* background-color: black; */ -} -.mirador-container .text-editor, -.mirador-container .tags-editor, -.mirador-container .select2-container { - padding: 5px; - display: block; - margin: 6px 0px 6px 0px; - border: 0; - background: #efefef; - box-shadow: inset 0 0 7px gray; - resize: vertical; - border: 1px solid gray; - width: 200px; -} -.mirador-container .text-editor .select2-selection--multiple, -.mirador-container .tags-editor .select2-selection--multiple, -.mirador-container .select2-container .select2-selection--multiple { - border: none; - background-color: inherit; - font-size: 16px; -} -.mirador-container .annotation-display.annotation-tooltip .button-container { - text-align: right; -} -.mirador-container .annotation-display .edit, -.mirador-container .annotation-display .delete { - font-size: 12px; - margin-left: 5px; - text-decoration: underline; -} -.mirador-container .annotation-display .text-viewer a { - border-bottom: 1px dotted #005ebd; -} -.mirador-container .annotation-display .text-viewer a:hover { - border-bottom: 1px dotted #dddddd; -} -.mirador-container .text-viewer p { - margin-top: 0; -} -.mirador-container .text-viewer p.user { - color: gray; - font-style: italic; - font-size: 11px; -} -.mirador-container .tags-viewer { - margin-bottom: 12px; -} -.mirador-container .qtip-bootstrap .tags-viewer span.tag { - background: lightGray; - color: #222; - border-radius: 6px; - padding: 0 5px; - margin-right: 5px; - margin-bottom: 5px; - text-align: center; - font-size: 12; - font-weight: bold; - border: 1px solid #aaa; - display: inline-block; -} -.mirador-container .mce-edit-area iframe { - height: 75px !important; -} -/** - * Styles which apply globally or do not really belong to any other - * particular .less file. - */ -.mirador-container a { - color: inherit; - /* blue colors for links too */ - text-decoration: inherit; - /* no underline */ -} -.mirador-container .mirador-loading { - background-color: #fff; - border: 1px solid #999; - padding: 20px; -} -.mirador-container .mirador-btn { - cursor: pointer; - display: inline-block; - height: 20px; - width: 20px; - margin-top: 9px; - /*margin-left: 3px;*/ -} -.mirador-container .mirador-btn.disabled { - opacity: 0.5; -} -.mirador-container .disabled { - opacity: 0.5; - pointer-events: none; -} -.mirador-container a.mirador-icon-annotations [class^="icon-"] { - display: block; - position: absolute; -} -.mirador-container a.mirador-icon-view-type [class^="icon-"] { - display: block; - position: absolute; -} -.mirador-container a.mirador-icon-empty-slot [class^="icon-"] { - display: block; - position: absolute; -} -.mirador-container .mirador-viewer { - position: absolute; - top: 33px; - bottom: 0; - left: 0; - right: 0; - overflow: hidden; - box-sizing: border-box; - -moz-border-sizing: border-box; - margin: 0; - padding: 0; - border: 0; -} -.mirador-container .mirador-viewer a.mirador-icon-annotations { - background: none; - color: #929191; - box-sizing: border-box; -} -.mirador-container .mirador-viewer a.mirador-icon-annotations:hover { - color: #000; -} -.mirador-container .mirador-viewer ul.dropdown { - display: none; - width: 160px; - z-index: 3; - opacity: 0.98; - background-color: #efefef; - text-align: center; - list-style: none; - position: absolute; - padding: 0; - margin-top: 10px; - height: auto; - box-shadow: 0px 2px 4px #b1b1b1; - border: 1px solid #b1b1b1; -} -.mirador-container .mirador-viewer .dropdown li { - margin: 0; - cursor: pointer; - box-sizing: border-box; - background-color: #dddddd; - padding: 10px; - width: 100%; - text-align: left; -} -.mirador-container .mirador-viewer .dropdown li:hover { - border-left: 3px solid deepskyblue; - background-color: #dddddd; - padding-left: 7px; - font-weight: bold; -} -.mirador-container .mirador-viewer a.mirador-icon-view-type, -.mirador-container .mirador-viewer a.mirador-icon-metadata-view, -.mirador-container .mirador-viewer a.mirador-osd-fullscreen { - background: none; - color: #929191; - box-sizing: border-box; - margin-right: 5px; - padding-bottom: 30px; -} -.mirador-container .mirador-viewer a.mirador-icon-window-menu, -.mirador-container .mirador-viewer a.mirador-icon-toc, -.mirador-container .mirador-viewer a.mirador-close-window { - float: left; - background: none; - color: #929191; - box-sizing: border-box; - margin-left: 5px; - padding-bottom: 30px; -} -.mirador-container a.mirador-icon-window-menu, -.mirador-container a.mirador-icon-view-type { - width: 30px; -} -.mirador-container .mirador-viewer a.mirador-icon-view-type:hover, -.mirador-container .mirador-viewer a.mirador-icon-metadata-view:hover, -.mirador-container .mirador-viewer a.mirador-icon-empty-slot:hover, -.mirador-container .mirador-viewer a.mirador-icon-window-menu:hover, -.mirador-container .mirador-viewer a.mirador-icon-toc:hover, -.mirador-container .mirador-viewer a.mirador-osd-fullscreen:hover { - color: #000; -} -.mirador-container .mirador-viewer a.mirador-icon-view-type.selected, -.mirador-container .mirador-viewer a.mirador-icon-toc.selected, -.mirador-container .mirador-viewer a.mirador-icon-metadata-view.selected { - color: #000; -} -.mirador-container .mirador-viewer a.mirador-icon-copy { - background: none; - /*color: @gray-91;*/ - box-sizing: border-box; -} -.mirador-container input[type="submit"], -.mirador-container input[type="text"] { - height: 25px; - border: 1px solid lightGray; - transition: border-color 0.3s ease-out; -} -.mirador-container input:focus { - outline: none; - border-color: deepskyblue; -} -.mirador-container input[type="submit"] { - color: gray; - background: #fff; -} -.mirador-container input[type="submit"]:hover { - outline: none; - border-color: deepskyblue; - color: #333; -} -.mirador-container { - /* Full screen - -------------------------------------------------------------------------- */ -} -.mirador-container:-webkit-full-screen, -.mirador-container:-moz-full-screen .mirador-container:-ms-fullscreen, -.mirador-container:fullscreen, -.mirador-container :-webkit-full-screen, -.mirador-container :-moz-full-screen :-ms-fullscreen, -.mirador-container :fullscreen { - height: 100%; - left: 0; - margin: 0; - top: 0; - width: 100%; -} -.mirador-container { - /* invisible layout slot styling */ - /* Slot Scaffolding */ -} -.mirador-container .workspace-container { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - overflow: hidden; - box-sizing: border-box; - margin: 3px; -} -.mirador-container .layout-slot { - position: absolute; - margin: 0; - padding: 0; - box-sizing: border-box; -} -.mirador-container .slot { - width: 100%; - height: 100%; - box-shadow: inset 0 0 35px #000; - overflow: hidden; - box-sizing: border-box; -} -.mirador-container .slot .remove-slot-option { - position: absolute; - margin: 10px; - color: gray; - cursor: pointer; -} -.mirador-container .slot .remove-slot-option:hover { - float: left; - margin: 10px; - color: lightGray; -} -.mirador-container .slot h1 { - color: gray; - text-align: center; - font-weight: normal; - margin: 0px; -} -.mirador-container .slot:hover h1 { - color: lightGray; -} -.mirador-container .plus { - font-size: 170px; - font-weight: bold; - margin-bottom: 2%; -} -.mirador-container .slotIconContainer { - position: relative; - top: 50%; - transform: translateY(-50%); - width: 100%; - overflow: hidden; - pointer-events: none; -} -.mirador-container .slot:hover, -.mirador-container .slot.focused, -.mirador-container .slot.draggedOver { - box-shadow: inset 0 0 35px #5edbff; -} -.mirador-container .slot.draggedOver .dropMeMessage, -.mirador-container .slot.draggedOver .dropIcon { - display: block; -} -.mirador-container .dropMeMessage, -.mirador-container .dropIcon { - display: none; -} -.mirador-container .slot.draggedOver .addItemText, -.mirador-container .slot.draggedOver .plus span { - display: none; -} -.mirador-container .addItemLink { - display: block; - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: 0; - cursor: pointer; -} -.mirador-container .dropMask { - position: absolute; - top: 0; - bottom: 0; - right: 0; - left: 0; - display: none; -} -.mirador-container .mirador-main-menu-bar { - background-color: #000; - border-bottom: 1px solid #555; - color: #fff; - height: 33px; - width: 100%; - /*padding: 4px;*/ - font-size: 14px; - top: 0; -} -.mirador-container .mirador-main-menu-bar .window-options-menu { - position: relative; - border-radius: 0; - display: none; - /*z-index: 10000;*/ -} -.mirador-container .mirador-main-menu { - float: right; - list-style: none; - margin: 0; - padding: 8px 12px 0 0; - text-align: right; - /* a:focus { - border-bottom: 2px solid deepskyblue; - outline: none; - }*/ -} -.mirador-container .mirador-main-menu li { - cursor: pointer; - float: left; - padding: 0 15px; -} -.mirador-container .mirador-main-menu a { - color: #fff; - font-weight: normal; - text-decoration: none; - opacity: 0.6; -} -.mirador-container .mirador-main-menu a:hover { - opacity: 1; -} -.mirador-container .mirador-main-menu a:active { - opacity: 1; - border-bottom: 2px solid deepskyblue; -} -.mirador-container .mirador-main-menu.user-buttons { - padding-right: 0; -} -.mirador-container .mirador-main-menu.user-logo { - padding-right: 0; - padding-left: 0; - float: left; -} -.mirador-container .mirador-window-options-menu { - list-style: none; - margin: 0; - padding: 10px 5px; -} -.mirador-container .mirador-window-options-menu li { - cursor: pointer; - padding: 3px 5px; -} -.mirador-container .window-manifest-title { - text-overflow: ellipsis; - max-width: 80%; - overflow: hidden; - white-space: nowrap; - padding-left: 10px; - margin: 8px 0px 8px 0px; - font-weight: bold; - font-size: 16px; -} -.mirador-container .window-manifest-navigation { - float: right; - width: 24%; - text-align: right; - padding-right: 10px; - font-size: 16px; -} -.mirador-container .mirador-status-bar { - background-color: #ccc; - border-top: 1px solid #000; - bottom: 0; - color: #000; - position: fixed; -} -.mirador-container .mirador-status-bar-msg-left, -.mirador-container .mirador-status-bar-msg-right { - color: #666; - float: left; - overflow: hidden; - padding: 4px 10px; - text-align: left; - text-overflow: ellipsis; - white-space: nowrap; - width: 40%; -} -.mirador-container .mirador-status-bar-msg-right { - float: right; - text-align: right; -} -.mirador-container .window { - position: absolute; - width: 100%; - height: 100%; - overflow: hidden; - background-color: #333; - top: 0%; -} -.mirador-container .manifest-info { - overflow: auto; - background: #fafafa; -} -.mirador-container .manifest-info .mirador-btn { - font-size: .8em; -} -.mirador-container .content-container { - position: absolute; - bottom: 0; - left: 0; - right: 0; - top: 0; - margin-top: 34px; - box-sizing: border-box; -} -.mirador-container .view-container { - margin-left: 280px; - height: 100%; - position: relative; - transition: all 0s ease; -} -.mirador-container .view-container.focus-max-width { - margin-left: 0px; -} -.mirador-container .view-container.focus-side-panel-minimized { - margin-left: 0px; -} -.mirador-container .overlay { - display: none; - position: absolute; - right: 0; - top: 0; - box-sizing: border-box; - background-color: rgba(255, 255, 255, 0.9); - z-index: 5; - width: 45%; - overflow-y: scroll; - height: 80%; - word-wrap: break-word; - font-size: 90%; -} -.mirador-container .thumbnail-view, -.mirador-container .image-view, -.mirador-container .book-view, -.mirador-container .scroll-view { - height: 100%; - width: 100%; - background-color: black; - display: none; - overflow-y: scroll; -} -.mirador-container .image-view, -.mirador-container .book-view { - overflow: hidden; -} -.mirador-container .scroll-view { - overflow-y: hidden; - overflow-x: scroll; -} -.mirador-container .focus-max-height { - height: 100%; -} -.mirador-container .focus-bottom-panel-minimized { - height: 95%; -} -.mirador-container .image-list { - right: 0; -} -.mirador-container .slot-controls { - left: 0; -} -.mirador-container .menu-divider { - color: #b1b1b1; - margin: 0px; - height: 0px; -} -.mirador-container .v-direction-rtl { - direction: rtl; -} -.mirador-container { - /* Disable outlines when canvas is focused - ---------------------------------------------------------------------------- */ - /* Canvas HUD - ----------------------- */ - /*.mirador-canvas-hud { - position:absolute; - left: 0; - top:0; - bottom:0; - right:0; - background: rgba(255, 0, 128, 0.5); - pointer-events: none; - }*/ - /* color picker custom style - ---------------------------------------------------------------------------- */ - /*.mirador-line-type ul { - color: @black-33; - margin-top: 0px; - } - - .mirador-line-type li { - text-shadow: none; - font-size: 10px; - }*/ -} -.mirador-container canvas { - outline: none; - -webkit-tap-highlight-color: rgba(255, 255, 255, 0); - /* mobile webkit */ -} -.mirador-container .mirador-osd { - background-color: #000; - width: 100%; - height: 100%; -} -.mirador-container .hud-control { - color: white; - text-shadow: 0 0 5px #000; - /*transition: all 0.3s ease;*/ - opacity: 0.6; - font-size: 18px; - z-index: 2; -} -.mirador-container .hud-container { - color: white; - text-shadow: 0 0 5px #000; - transition: all 0.3s ease; - font-size: 18px; - z-index: 2; -} -.mirador-container .hud-control.hud-disabled { - opacity: 0.3; -} -.mirador-container .hud-control:not(.hud-disabled):hover { - /*transition: all 0.3s ease;*/ - cursor: pointer; - opacity: 1; -} -.mirador-container .hud-control.selected { - opacity: 1; - /*transition: none;*/ -} -.mirador-container .hud-control.hidden { - opacity: 0; -} -.mirador-container .mirador-osd-previous { - position: absolute; - left: 1%; - top: 50%; - margin-top: -35px; - width: 40px; - -webkit-transform: translateY(0px); - -moz-transform: translateY(0px); - -ms-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-previous.bottom-panel-open { - -webkit-transform: translateY(-65px); - -moz-transform: translateY(-65px); - -ms-transform: translateY(-65px); - -o-transform: translateY(-65px); - transform: translateY(-65px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-next { - position: absolute; - right: 1%; - top: 50%; - margin-top: -35px; - -webkit-transform: translateY(0px); - -moz-transform: translateY(0px); - -ms-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-next.bottom-panel-open { - -webkit-transform: translateY(-65px); - -moz-transform: translateY(-65px); - -ms-transform: translateY(-65px); - -o-transform: translateY(-65px); - transform: translateY(-65px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-toggle-bottom-panel { - position: absolute; - bottom: 0; - right: 50%; - margin-right: -25px; - -webkit-transform: translateY(0px); - -moz-transform: translateY(0px); - -ms-transform: translateY(0px); - -o-transform: translateY(0px); - transform: translateY(0px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-toggle-bottom-panel.bottom-panel-open { - -webkit-transform: translateY(-130px); - -moz-transform: translateY(-130px); - -ms-transform: translateY(-130px); - -o-transform: translateY(-130px); - transform: translateY(-130px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-pan-zoom-controls { - position: absolute; - width: 100px; - height: 65px; - bottom: 0; - right: 0; - margin: 1%; -} -.mirador-container .mirador-pan-zoom-controls.bottom-panel-open { - -webkit-transform: translateY(-130px); - -moz-transform: translateY(-130px); - -ms-transform: translateY(-130px); - -o-transform: translateY(-130px); - transform: translateY(-130px); - transition: all 0.2s ease-out; -} -.mirador-container .mirador-osd-up { - position: absolute; - right: 20px; - top: 0; -} -.mirador-container .mirador-osd-right { - position: absolute; - right: 0; - top: 20px; -} -.mirador-container .mirador-osd-down { - position: absolute; - right: 20px; - top: 40px; -} -.mirador-container .mirador-osd-left { - position: absolute; - right: 40px; - top: 20px; -} -.mirador-container .mirador-osd-zoom-in { - font-size: 130%; - position: absolute; - right: 70px; - top: 5px; -} -.mirador-container .mirador-osd-zoom-out { - font-size: 130%; - position: absolute; - right: 70px; - top: 30px; -} -.mirador-container .mirador-osd-go-home { - position: absolute; - right: 20px; - top: 20px; -} -.mirador-container .mirador-osd-context-controls { - position: absolute; - top: 10px; - left: 10px; - transition: none; - /*width: 100%*/ -} -.mirador-container .mirador-osd-context-controls > div { - clear: both; -} -.mirador-container .mirador-osd-context-controls > div > a:first-child { - margin-bottom: 10px; -} -.mirador-container .mirador-osd-context-controls a { - float: left; - margin: 0 10px 0 0; - font-weight: normal; -} -.mirador-container .mirador-annotation-controls { - position: absolute; - top: 0px; - left: 0px; -} -.mirador-container .mirador-manipulation-controls { - min-width: 364px; -} -.mirador-container .mirador-mirror { - -moz-transform: scale(-1, 1); - -webkit-transform: scale(-1, 1); - -o-transform: scale(-1, 1); - transform: scale(-1, 1); - filter: FlipH; -} -.mirador-container .mirador-osd-color-picker * { - text-shadow: none; -} -.mirador-container .sp-dd { - display: none; -} -.mirador-container .mirador-osd-color-picker .dropdown-icon { - font-size: .8em; - height: 30px; - vertical-align: middle; -} -.mirador-container .mirador-osd-color-picker .sp-container { - width: 300px; - border-color: #ccc; - opacity: 0.9; - border-radius: 3px; -} -.mirador-container .mirador-osd-color-picker .sp-preview { - height: 10px; -} -.mirador-container .mirador-osd-color-picker .sp-replacer { - border-color: #ccc; - height: 11px; - border-radius: 3px; - cursor: default; -} -.mirador-container .mirador-osd-color-picker .material-icons { - float: left; - font-size: 12px; - margin: 0 5px 0 0; -} -.mirador-container .hud-control.mirador-line-type { - height: 11px; - border-radius: 3px; - margin: 2px 11px 0 0; - padding: 4px; - width: 57px; - border: 1px solid #ccc; - background: #eee none repeat scroll 0 0; - text-shadow: none; - color: #333; -} -.mirador-container .mirador-line-type ul.dropdown.type-list { - margin-top: -14px; - border-radius: 3px; - margin-left: -5px; - font-size: 10px; - box-shadow: none; - width: 140px; -} -.mirador-container .mirador-line-type ul i { - display: inline-block; - width: 25px; - height: 1em; - background: no-repeat; - margin-right: 10px; -} -.mirador-container .mirador-line-type .mirador-border-icon { - font-size: 12px; - margin: 0 5px 0 0; - float: left; -} -.mirador-container .mirador-line-type .border-type-image { - display: inline-block; - width: 25px; - height: 1em; - background: no-repeat; - margin: 0 5px 2px 0; -} -.mirador-container .mirador-line-type .dropdown-icon { - font-size: .8em; - height: 30px; - vertical-align: middle; -} -.mirador-container { - /* scale - ----------------*/ - /* image choice controls - ------------------------*/ -} -.mirador-container .mirador-image-view-nav-toolbar { - position: relative; - float: right; - margin-right: 5px; -} -.mirador-container .mirador-image-view-bg { - background-color: #000; -} -.mirador-container .mirador-image-scale { - bottom: 25px; - display: block; - position: absolute; - z-index: 2; -} -.mirador-container .axis path, -.mirador-container .axis line { - fill: none; - shape-rendering: crispEdges; - stroke: white; - stroke-width: 2px; -} -.mirador-container text { - fill: white; - text-shadow: 0px 0px 3px #000; -} -.mirador-container .mirador-image-dimensions { - margin-right: 10px; - margin-top: 7px; - position: absolute; - right: 0; - top: 0; -} -.mirador-container .mirador-image-view-physical-dimensions { - border: none; - font-weight: bold; - height: 16px; - margin: 0; - outline: none; - overflow-wrap: normal; - overflow: hidden; - padding: 0; - resize: none; - vertical-align: top; - width: 40px; - text-align: center; -} -.mirador-container .mirador-image-view-physical-dimensions:hover, -.mirador-container .mirador-image-view-physical-dimensions:focus, -.mirador-container .mirador-image-dimensions.noDimensionsSet .mirador-image-view-physical-dimensions { - border-bottom: 2px solid orangered; - height: 16px; - margin-bottom: -2px; - transition: all 0.2s ease-out; -} -.mirador-container .noDimensionsWarning { - display: none; - margin-right: 10px; -} -.mirador-container .mirador-image-dimensions.noDimensionsSet .noDimensionsWarning { - color: rgba(0, 0, 0, 0.5); - display: inline-block; -} -.mirador-container .mirador-image-view-physical-dimensions:focus { - background-color: rgba(200, 200, 200, 0.7); - box-shadow: 0 0 4px rgba(200, 200, 200, 0.7); - -webkit-transform: scale(1.2); - -moz-transform: scale(1.2); - transform: scale(1.2); -} -.mirador-container .mirador-image-dimensions .units { - cursor: context-menu; -} -.mirador-container .mirador-image-dimensions .units:hover { - height: 16px; - border-bottom: 2px solid orangered; - margin-bottom: -2px; - transition: all 0.2s ease-out; -} -.mirador-container .mirador-image-dimensions .unit-selector { - position: absolute; - display: none; -} -.mirador-container .mirador-image-dimensions .unit-selector.active { - display: block; -} -.mirador-container .mirador-image-scale.hidden { - display: none; -} -.mirador-container .mirador-image-view-choices { - list-style: none; - max-height: 350px; - overflow: auto; - padding: 0; -} -.mirador-container .mirador-image-view-choices li { - margin: 0; - padding: 0; -} -.mirador-container .mirador-image-view-choices li a { - padding-left: 12px; -} -.mirador-container .mirador-image-view-choice { - background-repeat: no-repeat; - height: 6px; - background-position: 0px 6px; - width: 6px; -} -.mirador-container .mirador-image-view-choice { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RUQ5OEI2ODFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RUQ5OEI2OTFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRFRDk4QjY2MUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRFRDk4QjY3MUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+fRx/ZQAAAHRJREFUeNpi/P//P0NnZ2cNAwNDOgMEzCwvL29h5uTkrFFSUkqOiorSMjMzm/L27ds5W7Zs4WUCqfT09NTh4eH5BsIgNkiMiQENMDIy/gdRIImZO3bsuPL161fOz58/c23fvv0qSIwRankt1PK/UMvbAAIMALeqLWb/azLQAAAAAElFTkSuQmCC); -} -.mirador-container .mirador-image-view-choice-selected { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RUQ5OEI2QzFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RUQ5OEI2RDFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRFRDk4QjZBMUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRFRDk4QjZCMUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+9DJqAgAAAF1JREFUeNpitLS0ZHj69GktAwNDJgMETJeWlm5mZmJiAgk2ATEvFDt+/vz5H6OcnNwzIEeSARU8Z2LADhiZ+fn5uUDa0SS6mbW0tA4BzfwP5GgC8Ucg7gJa3gIQYAChCRXFhBXUngAAAABJRU5ErkJggg==); -} -.mirador-container ul.scroll-listing-thumbs { - clear: both; - list-style: none; - padding: 0; - white-space: nowrap; -} -.mirador-container ul.scroll-listing-thumbs li { - box-sizing: border-box; - margin: 0 0 15px 0; - padding: 10px 10px 10px 10px; - /*transition: all 0.05s ease-out;*/ - display: inline-block; -} -.mirador-container ul.scroll-listing-thumbs li img { - background-color: #eee; - min-height: 25px; - min-width: 25px; - margin: 0 auto; - display: block; -} -.mirador-container ul.scroll-listing-thumbs li .thumb-label { - clear: both; - color: #999; - font-size: 12px; - margin: 0 auto; - max-width: 200px; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: center; -} -.mirador-container .mirador-viewer ul.listing-thumbs { - clear: both; - list-style: none; - overflow: auto; - padding: 0; -} -.mirador-container .mirador-viewer ul.listing-thumbs li { - box-sizing: border-box; - float: left; - margin: 0 0 15px 0; - padding: 10px 10px 10px 10px; - /*transition: all 0.05s ease-out;*/ -} -.mirador-container .mirador-viewer ul.listing-thumbs li img { - background-color: #eee; - min-height: 25px; - min-width: 25px; - margin: 0 auto; - display: block; - box-sizing: border-box; - /*transition: all 0.2 ease-out;*/ -} -.mirador-container .mirador-viewer ul.listing-thumbs li img:hover { - border: 3px solid rgba(0, 191, 255, 0.7); - transform: scale(1.1); - cursor: pointer; - transition: all 0.2 ease-out; -} -.mirador-container .mirador-viewer ul.listing-thumbs li .thumb-label { - clear: both; - color: #999; - font-size: 12px; - margin: 0 auto; - max-width: 125px; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: center; -} -.mirador-container .mirador-viewer .thumbnails-view-slider { - float: left; - margin: 10px 15px; - width: 60px; -} -.mirador-container .mirador-thumbnails-view-nav-toolbar { - float: right; - margin-right: 5px; -} -.mirador-container .mirador-widget-toolbar .ui-slider-horizontal { - height: .4em; -} -.mirador-container .mirador-widget-toolbar .ui-slider-handle { - top: -0.5em; -} -.mirador-container .hud-control .ui-slider-handle .percent { - position: absolute; - left: 17px; - top: -0.3em; - display: block; - color: white; - text-shadow: 0 0 3px #000; -} -.mirador-container .hud-control .ui-slider, -.mirador-container .ui-slider-vertical { - width: 3px; - margin-left: 27px; - margin-bottom: 20px; - height: 100px; -} -.mirador-container .hud-control .ui-slider-vertical .ui-slider-handle { - width: 0.7em; - height: 0.7em; - border-radius: 40px; - margin-bottom: -0.35em; -} -.mirador-container .hud-control .ui-slider-vertical .ui-slider-handle:focus { - outline: 0; -} -.mirador-container .hud-control .ui-slider-range { - background: deepskyblue; -} -.mirador-container .thumbnail-rtl { - float: right !important; -} -@media screen and (max-width: 768px) { - .mirador-container #load-controls form { - float: none; - } - .mirador-container #url-load-form { - margin-bottom: 5px; - } -} -.mirador-container #manifest-select-menu { - position: absolute; - margin: 6px; - display: block; - left: 0; - right: 0; - bottom: 0; - top: 0; - display: none; - overflow: hidden; - z-index: 18000; - /* Must be higher than Qtip elements. */ - background-color: #fff; - box-shadow: 0 0 6px #333; -} -.mirador-container #manifest-select-menu .container { - position: relative; - width: 100%; - height: 100%; - padding: 10px 4px 10px 10px; - box-sizing: border-box; - overflow: hidden; - margin: 0 auto; -} -.mirador-container #manifest-select-menu .remove-object-option { - cursor: pointer; - display: inline-block; - font-size: .9em; - font-weight: bold; - transition: color 0.2s ease-out; -} -.mirador-container #manifest-select-menu .remove-object-option:hover { - color: #929191; -} -.mirador-container .items-listing { - margin: 0; - padding-left: 0; - box-sizing: border-box; -} -.mirador-container .items-listing li { - list-style-type: none; - overflow: hidden; - border-bottom: 1px solid lightGray; - padding-top: 10px; - padding-bottom: 10px; - position: relative; - padding-left: 5px; - transition: background-color 0.3s ease-out; -} -.mirador-container .items-listing li:hover { - background-color: #dddddd; - cursor: pointer; -} -.mirador-container .manifest-load-status-indicator { - width: 100%; - padding: 10px; - box-sizing: border-box; - overflow: hidden; - background: rgba(255, 255, 255, 0.94); - position: absolute; -} -.mirador-container .request-status-bar { - background: deepskyblue; - width: 10px; - height: 50px; - display: inline-block; - margin-left: 5px; - vertical-align: bottom; - transition: all 0.1s ease-out; -} -.mirador-container .request-status-bar.pending { - background: gray; - transition: all 0.1s ease-out; -} -.mirador-container .loading-status { - display: block; -} -.mirador-container .request-status-bar:nth-child(2) { - margin-left: 0; -} -.mirador-container .repository-label { - border-top: 1px solid rgba(0, 0, 0, 0.7); - padding-top: 3px; - position: absolute; - bottom: 0; - width: 100%; -} -.mirador-container .select-metadata { - width: 45%; - max-width: 450px; - min-width: 300px; - position: relative; - /*width:200px; - text-overflow: ellipsis; - white-space: nowrap; - overflow:hidden; - position: relative;*/ -} -.mirador-container .repo-image { - position: relative; - width: 80px; - height: 80px; - overflow: hidden; - opacity: 0.5; -} -.mirador-container .repo-image img { - position: absolute; - width: 100%; - top: 0; -} -.mirador-container .repo-image span.default-logo { - position: absolute; - width: 100%; - height: 100%; - top: 0; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAACuwEE+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAE/JJREFUeNrsnX+olFd6xz9nGC4XERGxIiJBUgmpmDQk2WCzaWqsiPmBbLNpPLPW/UHChiRtNt25IVlkG1wJacp9DQntbgPbbOhuMrNJ1lprVWzIusHaRSSVIGGRrAQRERERkdvL5TJP/3jPtG/efX+c875n5o56HrjM3Hl/nvN+n9/PeV4lIgQKZEuNMAWBAmACBcAECoAJFAATKAAmUKAAmEABMIECYAIFwAQKgAkUABMoUABMoACYQAEwgQJgAgXABLpeqVnlIKVUmLmrkCYmJhCRhhEUY8D05ORkb+CACXRVAWQcuAG4XURuAVYDy4FlwIPAxwEw1zG1222AJcBaEbkfuEcptUJEmmnNYKQNATDXJ1DGgHuBrcBDwMIsG7Vu0X8AzNUPlHnAV4DvALcnn6lSCt+rQgJgrl6gNIENwIvAnUXSJP0ZAHP9gWU58DLwKDBWJkn6231IHK+A0Vr3z9lH+6xSqtfpdObSAOzfzzgwDcwCvSiKnM/XarUaItKfsx7Q63a7vWGNx3g9G4A3gBW2dolPCaOqnCRtbWut5xs9+iBwK7AYuAJ8DhwH9iulDnU6ndkh6vX1wP3AXcaNHAemgJPAvwNvRVF03pIJbgS+BtwHrFBKzRORC+Zc/wXsBj7rdruDBEsDeEZEXgbG+88gKTmSEiT5W3K/1DFfmpycPDY0wGitG8Am4NUk4jOoB5wGfgS82e12LwwIKEuBbwNPmDhDEZ0Htiml3swLXhlG2A48ZQCXR7PAR8BrwL5utzvreVxNo4K+S4XofIFKGh5gWq0WIvIM8IpSajwP7Rk3+zmwQyn1s06nM+PRpfy6MQCXp7krLZ4T9zID/C2wPYqiXgosC4EOsDFr0nM+Z4FDwPPdbvdjj2B5BXhWKdXIGkfeeLOkTUrSOAOmci5JRNYBLwHjRaBL60+l1ArgDRF5W2u91MOELgN+CvxIKbU879r9vxTwx4AXgIfTtooZ28a8h5Dz2VRKrQd+qbV+Smtdy0bsqyHz1yizQ5LjtHkmVagSYMxEbAfmK6UKc0v9bal9mkqpR4D9WutVrVarkkHbbrdXAvuNt9CsODljwI52uz2eOOZ24JvpcSXHmvWZ2H+BUU+vaq3n1WDKDcCO/th8uslVj60qYW4F1mRxr+PnbcC/ishNLqCZmJjA2Ez7zb04TWTGfjcBaxO7bAXmpcdVNs4UZzeBvwRe01qPV2CIFcbmm1f34fv0kqoCZq1SqpnkrCLOK/lcCfyLiCx14I4lwL8BKy2kmY231wD+uN1uo7UeA+7JO2eZhMn4/XFgh4t6arfbfZW4wsVbdZTyQwXMH7hwnsXnKuCfbDjRqI6fEGdda3FSar/VZj4WGDfceRwF8/As8BcOUnQ98IgvtTIKEmaBBWc5fQIPAM8aV70oEPdds+/vcI0tJ+XstyhhCI95lDB99RSJyGpLj+8lcx+FEqVgLgufyVwABs8Spk/PZ0mOlO30XB6XudowOXPRcPCKrOfBAPLVVqs1VjK1m4hrV0rvu2guS+5l6IC5ksVZHv4WAttbrVYzJx7xIrAw69gyrs/aL8Wpl82kzgAznsfVv8ZaEXk4TzUZN/pppVQjy/uykWYF1878bViA+W0dEVeC9AdEZE3G73dmxUXqpjUS9JmJSF82UWDvZByF50RkLGdeVicNbhfDdVhls1UBc1xEerYiMk8k5mwfA54wOZyk7fJY0tXNClIVqQmL/f87iiK63e408GnWflXUVE4oYW2OfbYZaOa580XjsNjvnIgcEJF9IvKJiEwPEzC/Jk4uWnGBq+FIXOexJHGKhcBDlmLfVU1AnMU+nLjef1Th5jIj01yzAWxJMkQigLip6riKVDDwY+APoyi6P4qiB4E7gFuMVHWiqqHri8AB4NGyfIVDjilJi01gcI/5/y5gSZnRlr6mg3o6JiInE5sOAhdFZFEyw5seZ5aqLcjbJK+5nv8vt+jTjcCqOiH9nO17gCejKPq/hKj5/hnA5OTk4CWMSeP/hLjepbZLncEZDeDLiUveBTTyOMpGqhWE8XvAGzt37kwefhrY6zN0kLrmUhNd/kIwtD/GstSDreQhzqJ/PwmWOXOrgQ+Bo7Yupu3/id+TE/r7ee6irZ1R8P0EcT1LmiFeE5Ep17RA3n6ptEHDSJSk/fJll3EU7ZfYfsL8zbnRS7fbnQG2i8h0UZKuLOhUwP1LEu7nEhc9brufKUfYEUVRlj12HHinyG7JCpTZuMH9MSW+jwOrbNxgl1ACcMxIUEZBwgB8AHTz0O5qU6RofvL+8ri2pueyO2EnfYE6nU4P2CEiZ11tirz5SNHCZOQcuKFMgrkG74DfVilFHRhgTD3rNuJSxcKJs40TJMB2KcEdU1nGpc05UxIluekU0I6iaKbg2NPEyzcqcWkJk1xMSZsFeQZ1WpLZFHwbujQqcZjkDZ4FHhORyx5iFEmOOpsoHj+V9TBsCoWy9jP3+g1j3OZSp9NBKbUL2Fk1NVBwv2cSm5cBYzb2Sln1v880wEAAYyb1MPAtYMqXRwH8Z+IyvwJ6WarOZXLMcdPmXg/biOtOp9NTSm0Dfgb0XJOPWTaOuYfjic2L0tKkbi5p1CK9vwMaYBewte9Z2IAjT12JyCUTC+nTYeBUuuq9LC+S3kdErhjJsttFt5va4yf6oKkbwDO2XzL9sCRrbHnutM11BpUq8NYfxriiu4CvisiZKnmdhKh9J2kXRVF0GYj6D6u/XxlnpdTFaeCrwLvpgm/L8U0BT4rITuLi8UoPx4TkX06tZxrPs1HyjHuXeR1JwPRBo5Q6APypyVnMWk5i8vMI8GLGGp+3ROSfk6opL7aS+m3WeEL3RVF0sI7X0O12p5RS3wO2iMgpVy/J3MvLZoxJ+j0b9eJaajEI8r5U1qink1rrPwMeEZHnTYyhWbI0omdE9bey1i1FUTTdbrf/yuj/x/slogXh+VkTh3gF2Osr2mkW472vtT4MtEXkm8DiopSI+T5FXHb5d2lmSC4fsWEum7RLHuhM+ecik544Umb4DxwwqcDeO1rr3cR1IFuB9SKyKCHZeiLSI85+/0N8WDc3ixpF0ZV2u/00cQ3wX5tw+pg5X8/8nRORg8Rrij4qcptrju9cq9V6TkReNYyxmbh7wlhqfFeAfcSL/Y5mrY50lQauxq9ZYjsG3E1c4P6ASU98yRUwlReymVLKhu0qP5OdHTMh/xuMxJkCfgOcdV2DbcLpC4Gb+eLS3DNKqVnbpJopiZxJqyqtddPcU6m9Yxb1Nfr3o5RabOb1vAnNXylaRjsxMRERl556JRF50jgMLUArpW5MbXdeyFZHwiwAfqG1/hWwSyn1adHkmgmbwVN+wzzgS8SlFk5kqvduJa4/uRf4k7QhS1zI9aTW+m3gQNHyXgP0ngnGHfEc4LNi4JxzfN94YE1frnezxk02RGSVUmqdiDwvIsfM5O5VSp2z4cxhktHdNxA3DWgBtyqlxkXkQk6eaExENiqlNojIBa31AeBt4IhS6orPjhR123AUHLvMd5ym6WnA84B7ReRe4IKIfKC17gCHlVIX56rdh9HdS4yts8V8LnB8QA3DpV8Xka8Bp0Rkl9b6PeDTIpurzgPPusei2pyR7w+TN0hjT2gReRT4XET2GvAc9zG5liCZB6wRkRbxYvplmFoTmwhqQWCsaWywF4hbbxzXWv+cOIl5pmqvmKzWHUVznrePZXFaLeA0fYrR1M02RORGpdQzIvIUcMJM7rtKqdM+e8UkGgetFJEtxIvrb8ZyyUiZC5vzOQ+4Wyl1t4jsAA4ZlXwQuOwCnipLZVzjMr5U08Dc6tRNNYmLn29TSr0oIocMePYCF6o24jHSZJmxSzYbt7HpyoE2kdGSkoUFSqlNwCYROQfsMVL1CDBTNr6sRkA2TGrZgsRa8swpYPIGZ8LgG83fReCA1vptpdSHnU5n2lKazAc2GmmyznhspSrGheOy7Iec8aSP6Tc1epy4brartX6vzIu08Zh8SZSRkTAVlscuMoakFpHTWuv3gZ8DH6dFuvFy7jYezsPENSSNvDZdeQXYLpzmUiWYsb0B3CQifwO8ICJHjcrabbzI5APs2QDSRYIU2T91gNP0rHqqUoO4U8EEca+XO4B03GORAdMyV46sY8NYqqQySdvvCHEPcIuIPJ3abb7N+atKlLog8QoYl+UWNstQ+jZIFqjy8kdZHFRml5RJmLycUNH48vZPbWtmXKtZdB1bxnVt7DRUCZPRisxpgK4TYmOoVc3J2Ijwon2LJEJRPMWnJPMo7UtVQW17ZRjrel3qQFzbfdhIGZtz2hRzlakMX1K+yryMkls9lPLCGi3LCl1w3/ZQ1RLTqsw0Cu0+nFHvut7ah5dWlzNd77+qhPHtnY6shKmz6L4KWGzcRheDfABhAqftZcDN6+RdFi+yiSdVDd41fIrCuoEll9JC25pem+UorqK8YhsTq+tk1fBm/W9THppjiE8DR0WkTVyLNLdxmEHmN2zXS/tYs1MXFC7jK4ga15rrBM0SZ9n3mFjWiSiKpsG9e4M3ozdP1JXlP+rYFenzF72kwdVFLxuPbUbYBgyuKsImR2S+XwL2isjbxOuwrsy5l2TTxdKmFUcdUFYBVx1j0tb2yguWlQXYiuI3jstMtkVR9MORiMPYqATfNkwVlWRzf1VtGF8hg0GoJPPde9XjUCWMzadLMrBu9NjGtij6Pe9aVSRoWZCwKN2Qdy+DiPw2fEgW1wDSIAbkem6XzhJ14xs+4h9lKYlR76JZ2mCnavyh6sCrxHSq2DWDoDrXHxZQvHpJRV6D6/9lk+Cj2Nl2v2F5SUUBtqLffFbSDRUweZKjCnDqinefEqaskU+Z3eHiJVX9rUiyDgI83sobfAbyXEoIBi1hXAN1c6GahqlWa68aGLYOrTNBLscNamw5oYPLNmuNylTQVaGS6q6Vyfq/Kie6pgZclpm4gq/swbtKbhcpPZJeUnLwdd5ZVMXar+rm+rhmWbtYm/IG1xjMXHtGA4vD1C0HsJ2oGi3LKl3PFXCuLn5WGcM117LMpjbD1TCskCsZSsyijmQa1P1VkWQjZcP4+r+qfq/idbiWHLicyzU2YtHi3nsR/JwApu5yzfSnS5zChQNLln54H58LAH1JBJuWZSMZuBvEuVxVVZVcV5lbXdWmKQONrwc7DG9pTpfKuhiHNgvmisDjCsQiA7LmElpnaVg1JjSSEsam64BNnMbVoC7iKlcuriPVfAQLXWpf5pq8x2FcjMKqEzHMOEzV6kEfHs8oxV+8AaaqWqoivl1BlldQVGXibUszqqxLcqltrhIkHdnAXV2d72LcVglS1bFjXMBdZV2S6+uBqkjYObVh0v3+fcVhfMR+fF3LJgZStF56WDUqw4zHDKTdxyAGW8Y9Ng+06muFfdpULm/GLXIKbNuUjLRbPch+az4Xutmcs6xr1aDGV3SP10S22lccxsXDcUnG2STrXG2YKuMtslNsgoRV53Nk4zCDVkk2S2IHsebZxbPxOW6fLctGLg5TJ/YxTO4YRKxnGC02Rom8rHwsW2BlY6wOUw/bgGNUIqvXHGDqRl19cmJoWTZ4uqraffi2F1xyX1WbJ2dtH8aS1msiDlPWvtT2Ibq0Wrdx+W0MXpfssWt23GYdV5GLn7V95OIwPpKGdWpRXd4WX0Vsu5Q3+FIRRa60bR/iQaungdT0hpZl1dSt75Zl170Nc622LLOt36nRsmx0vKQyD8W1+5QP1WG75rnOeOrEYbJskzprpIa5zCS0LBsyaIbcsmw0A3fDsmGu1ZZlNud0VUmDUkuhZdkItCwri5bb7BNalnkyvm32n+uWZXXWU4eWZddhy7JhBU7nOnDXw7xN/mptWWZoioz2pCIyC/TM23Fzr3G9tSyrI2EuAX8kIt8BjhK3J891E315TumODOmkX1bRUkYXhxngI+Ax4I4oimYzrrPXjO914GyZNLS9lyLJmrVf0W85krUHnAR+QPzW3tGQMOYll2eB17XWPxSRVUBLRL5C/DLwRlVPaUAty3rACeA94F3gsyiKegXjmwWOaq2PAt8TkfVmfOuBxT7tsbrSwRx7xgCkA/wamImiaPS8JIButzsLfKK1/gR4CVgDbAE2KKWWDUJvO0zu6cREHlNKTbu8kMG8c3oK2NNqtfaKyFLgAeK3264xLzx3AkeRSnJpWQZcAg6ZdwkcAi4MAiTeAZOa3CvAB61W60MRWWw4civxK4QXDKll2QWjcvoTedHHRJr3Tp8Ffqy1fgtYKSKPAn9upOqYbQDONfaT+G1KRI4Tv5VkN3CmSFKONGAyJvc88I7WugusJH5z/GZgtVJqvGpDv5x9p4CPzUTuAU4PktuMVP0N8AOt9SRwlwHOQ8DytH1YVHJg8faVWRE5BewyKvVEFEUzc+GVNYdxEfPS8pPApNb6deA2A5xHRGS5UqrhApQE584Cp4Au8Aul1KeTk5Ozw57Ebrc7BRxqtVqHRGQbsE5EvgGsA+a7vBI58b0HXAT2ichPgSPA1KBVzkgAJjW5Mwljsj+5W4CNwCLLSO15EdlrVM7hQRl4FR2BS8AurfUuYJmIPGzsnTuTKquAIaZE5JCxufb5UqdXLWBS9s40sK/Vau0znscm4D7DXVlieR+wHzgIXBqlicwZ31ng77XW/wjcDGwG/idj956IHDMgeX/YdslVAZgMzrwAvNlqtd4i+z0/F4HHRnUiLeydE1rrEzmxr5eMtJ0ZZSYAUGE5RSAXaoQpCBQAEygAJlAATKAAmEABMIECBcAECoAJFAATKAAmUABMoACYQIECYAIFwAQKgAkUABMoACbQ9Ur/OwDPb/OYDgsfJAAAAABJRU5ErkJggg==); - background-size: 80px 80px; - background-repeat: no-repeat; -} -.mirador-container .items-listing h3, -.mirador-container .items-listing h4 { - margin: 0; - font-weight: normal; - color: rgba(0, 0, 0, 0.7); -} -.mirador-container .items-listing h3 { - color: rgba(0, 0, 0, 0.8); - margin-top: 2px; - font-size: 1em; -} -.mirador-container .manifest-title h3 { - line-height: 1.2em; - height: 3.6em; - position: relative; - overflow: hidden; -} -.mirador-container .manifest-title h3:after { - content: ""; - text-align: right; - position: absolute; - bottom: 0; - right: 0; - width: 20%; - height: 1.2em; - /*background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1) 50%);*/ -} -.mirador-container .item-info { - position: absolute; - bottom: 0; - display: table; - width: 100%; -} -.mirador-container .item-info-row { - display: table-row; -} -.mirador-container .repo-label, -.mirador-container .canvas-count { - display: table-cell; - white-space: nowrap; - font-size: .85em; - vertical-align: bottom; - color: gray; -} -.mirador-container .canvas-count { - text-align: right; -} -.mirador-container .repo-image, -.mirador-container .select-metadata, -.mirador-container .preview-images { - float: left; - margin-right: 15px; - height: 80px; -} -.mirador-container .preview-thumb { - display: inline-flex; - position: absolute; -} -.mirador-container .preview-images { - margin-right: 0; -} -.mirador-container .preview-image { - background-color: gray; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.7); - float: left; - margin-right: 15px; - min-height: 25px; - min-width: 25px; - /*transition: all 0.1s ease-out; ?*/ -} -.mirador-container .preview-image:hover { - box-shadow: 0px 0px 5px #00bfff; - transform: scale(1.1); - transition: all 0.6 ease-out; -} -.mirador-container .remaining { - line-height: 80px; - opacity: 0.5; - text-align: center; - box-sizing: border-box; - vertical-align: middle; - width: 20px; -} -.mirador-container #load-controls { - margin-top: 20px; -} -.mirador-container #load-controls:after { - content: ""; - display: table; - clear: both; -} -.mirador-container #manifest-search-form { - float: left; -} -.mirador-container #manifest-search-form label { - margin-right: 6px; -} -.mirador-container #url-load-form { - float: right; -} -.mirador-container #url-load-form input[type="text"] { - width: 250px; - margin: 0 5px; -} -.mirador-container #load-controls input[type="submit"] { - height: 29px; -} -.mirador-container #manifest-search i { - position: absolute; - left: 0; - color: #000; -} -.mirador-container #manifest-search-form input:focus, -.mirador-container #url-load-form input:focus, -.mirador-container #url-load-form input[type="submit"]:hover { - outline: none; - border-color: deepskyblue; -} -.mirador-container #manifest-search i { - width: 25px; - height: 25px; - color: red; - border: 1px solid red; -} -.mirador-container .select-results { - height: 100%; - overflow-y: scroll; - margin-top: 10px; - border-top: 1px solid gray; -} -.mirador-container #workspace-select-menu { - position: absolute; - height: 100%; - width: 100%; - background-color: rgba(255, 255, 255, 0.94); - display: none; - overflow: hidden; - z-index: 6; -} -.mirador-container #workspace-select-menu { - background-color: #333; - text-align: center; - padding: 20%; - padding-top: 0; - box-sizing: border-box; -} -.mirador-container #workspace-select-menu h1 { - color: lightGray; - padding-bottom: 3%; - font-weight: normal; -} -.mirador-container #workspace-select-menu h2, -.mirador-container #workspace-select-menu h3 { - color: lightGray; -} -.mirador-container .select-grid { - width: 60%; - min-width: 300px; - position: relative; - margin: auto; -} -.mirador-container .grid-row { - content: ""; - display: table; - clear: both; - margin: 0 auto; -} -.mirador-container .grid-item { - height: 50px; - width: 50px; - float: left; - padding: 4px; - display: block; -} -.mirador-container .grid-item .grid-icon { - background: gray; - height: 50px; - width: 50px; - border-radius: 7px; - display: block; - transition: all 0.2s ease-out; - margin: auto; -} -.mirador-container .grid-item.hovered .grid-icon { - background: deepskyblue; - box-shadow: 0 0 10px #000; - transform: scale(1.1) translateY(-10px) translateX(-5px); - transition: all 0.2s ease-out; -} -.mirador-container .grid-text { - display: none; -} -.mirador-container { - /* - .toc li:hover > h2 a { - font-weight: bold; - } - */ -} -.mirador-container .sidePanel { - position: absolute; - width: 280px; - left: 0; - bottom: 0; - top: 0; - background-color: #efefef; - border-right: 1px solid lightGray; - box-sizing: border-box; - overflow: hidden; - transition: all 0.3s ease; - padding: 10px; - opacity: 1; - transition: all 0.2s ease-out; - transform: translateX(0); -} -.mirador-container .sidePanel .tabGroup { - list-style-type: none; - margin: 0; - padding: 0; -} -.mirador-container .sidePanel .tab { - padding: 8px; - margin-right: 2px; - display: inline-block; - cursor: pointer; - background: #dddddd; - border-width: 1px 1px 0 1px; - border-color: #b1b1b1; - border-style: solid; - color: #666; - font-size: .9em; -} -.mirador-container .sidePanel .tab:not(.selected):hover { - background: lightGray; - color: #333; -} -.mirador-container .sidePanel .tab.selected { - font-weight: bold; - color: #333; - background: #efefef; - border-top-width: 1px; - border-top-style: solid; - border-top-color: deepskyblue; -} -.mirador-container .sidePanel .annotationListItem { - list-style-type: none; - border-left: 0; - border-right: 0; - padding: 10px 10px 0 10px; -} -.mirador-container .sidePanel .annotationListItem:after { - content: ""; - height: 1px; - background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #939393 50%, rgba(0, 0, 0, 0) 100%); - display: block; - margin-top: 10px; -} -.mirador-container .sidePanel .annotationListItem.focused { - background-color: #dddddd; - border-left: 3px solid lightBlue; -} -.mirador-container .sidePanel .annotationListItem:hover { - background-color: #dddddd; - border-left: 3px solid lightBlue; -} -.mirador-container .sidePanel .annotationListItem.selected { - background-color: #ccc; - border-left: 3px solid deepskyblue; -} -.mirador-container .sidePanel a:hover { - text-decoration: none; -} -.mirador-container .sidePanel h2 { - font-size: 1em; -} -.mirador-container .sidePanel h3 { - font-size: .9em; -} -.mirador-container .sidePanel h4 { - font-size: .8em; -} -.mirador-container .sidePanel h1, -.mirador-container .sidePanel h2, -.mirador-container .sidePanel h3, -.mirador-container .sidePanel h4 { - margin: 0; - padding: 0; - font-weight: normal; -} -.mirador-container .sidePanel.minimized { - transition: all 0.2s ease-out; - transform: translateX(-280px); - opacity: 0; - border: none; -} -.mirador-container .tabContentArea { - position: relative; - width: 270px; - height: 100%; - float: left; - background-color: #efefef; - border-right: 1px solid lightGray; - box-sizing: border-box; - overflow: hidden; - transition: all 0.3s ease; - margin-top: 8px; -} -.mirador-container .annotationsPanel ul { - padding: 0; - margin: 0; -} -.mirador-container .toc { - margin: 0; - overflow-y: scroll; - width: 270px; - padding: 0; - position: absolute; - box-sizing: border-box; - left: 0; - top: 0px; - bottom: 0; - list-style-type: none; - margin-bottom: 30px; - /* fix overflow-y bug when .tabGroup is present */ -} -.mirador-container .toc a.toc-link { - color: black; - padding: 8px; - padding-left: 8px; - display: block; -} -.mirador-container .toc a.toc-link:hover { - cursor: pointer; - background-color: #dddddd; - display: block; - overflow: hidden; -} -.mirador-container .toc ul { - margin: 0; - padding: 0; - box-sizing: border-box; - list-style-type: none; - width: 100%; -} -.mirador-container .toc li { - cursor: pointer; - box-sizing: border-box; - display: block; - position: relative; - margin-left: 8px; - margin-bottom: 5px; - border-left: 4px solid #efefef; -} -.mirador-container .toc li.selected { - cursor: pointer; - overflow: hidden; - border-left: 4px solid deepskyblue; - transition: all 0.2s ease-out; -} -.mirador-container .toc > li { - margin-left: 0; -} -.mirador-container .toc-link i { - color: rgba(0, 0, 0, 0.4); - margin-right: 0.4em; - transition: all 0.2s linear; -} -.mirador-container .toc-link i:hover { - color: black; -} -.mirador-container .toc-caret { - padding: 0.4em; - margin: -0.4em; -} -.mirador-container .toc li.has-child i.star { - display: none; -} -.mirador-container .toc li.leaf-item i.toc-caret { - display: none; -} -.mirador-container .toc li.leaf-item i.star { - display: inline-block; -} -.mirador-container .toc li.selected > h2 .toc-link, -.mirador-container .toc li.selected > h3 .toc-link, -.mirador-container .toc li.selected > h4 .toc-link, -.mirador-container .toc li.selected > h5 .toc-link { - font-weight: bold; -} -.mirador-container .toc li.selected > h2 .toc-link .star, -.mirador-container .toc li.selected > h3 .toc-link .star, -.mirador-container .toc li.selected > h4 .toc-link .star, -.mirador-container .toc li.selected > h5 .toc-link .star, -.mirador-container .toc li.hovered > h2 .toc-link .star, -.mirador-container .toc li.hovered > h3 .toc-link .star, -.mirador-container .toc li.hovered > h4 .toc-link .star, -.mirador-container .toc li.hovered > h5 .toc-link .star { - color: black; -} -.mirador-container .toc li.open > h2 .toc-link .toc-caret, -.mirador-container .toc li.open > h3 .toc-link .toc-caret, -.mirador-container .toc li.open > h4 .toc-link .toc-caret, -.mirador-container .toc li.open > h5 .toc-link .toc-caret { - transition: all 0.2s linear; - transform: rotate(90deg); - -webkit-transform: rotate(90deg); - -moz-transform: rotate(90deg); - -ms-transform: rotate(90deg); - -o-transform: rotate(90deg); - /* Internet Explorer */ - filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -} -.mirador-container .toc li.hovered { - border-left: 4px solid deepskyblue; -} -.mirador-container .toc li:hover { - border-left: 4px solid #99e5ff; -} -.mirador-container .toc-link:hover .star { - color: black; -} -.mirador-container { - /* - .annotation:hover { - border: 3px solid orangered; - opacity: 0.5; - box-shadow: 0px 0px 15px @black; - } - - .annotation.selected:hover { - border: 3px solid orangered; - opacity: 1; - box-shadow: 0px 0px 8px @black-a70; - } - */ -} -.mirador-container .annotationListPanel { - background-color: #f0f0f0; - width: 200px; - height: 100%; - position: absolute; - right: 0; - top: 0; - margin: 0; - padding: 0; - z-index: 2; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); - border-left: 1px solid gray; -} -.mirador-container .annotationPanelHeader { - padding: 0 10px; -} -.mirador-container .annotationListPanel ul { - position: absolute; - bottom: 0; - top: 80px; - border-top: 1px solid #fff; - list-style: none; - overflow: scroll; - overflow-x: hidden; - margin-bottom: 0; - padding: 0; - width: 100%; -} -.mirador-container .annotationListPanel ul li { - font-size: 80%; - margin: 0; - padding: 10px; - border-bottom: 1px solid #fff; - box-sizing: border-box; -} -.mirador-container .annotationListPanel ul li:hover { - background-color: lightGray; - cursor: pointer; - border-left: 2px solid orangered; - padding-left: 8px; -} -.mirador-container .annotationListPanel ul li.selected { - color: #fff; - background-color: gray; - cursor: pointer; - border-left: 3px solid orangered; - padding-left: 7px; -} -.mirador-container .annotationListPanel ul li.hovered { - background-color: lightGray; - cursor: pointer; - border-left: 2px solid orangered; - padding-left: 8px; -} -.mirador-container .annotationListPanel ul li p { - margin: 0; -} -.mirador-container .annotationListPanel ul li p:hover { - margin: 0; - cursor: pointer; -} -.mirador-container .annotationListPanel ul li a { - display: block; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; -} -.mirador-container .annotationListPanel .resizeGrip { - position: absolute; - left: -7px; - bottom: 0; - top: 0; - width: 12px; - z-index: 3; - background: none; - display: block; - cursor: ew-resize; -} -.mirador-container .annotation, -.mirador-container .osd-select-rectangle { - border: 2px solid deepskyblue; - box-shadow: 0px 0px 5px #fff; - box-sizing: border-box; -} -.mirador-container .annotation.selected { - border: 3px solid orangered; - box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.7); -} -.mirador-container .annotation.hovered { - border: 3px solid orangered; - opacity: 0.5; - box-shadow: 0px 0px 15px #000; -} -.mirador-container .annotationDetails { - box-sizing: border-box; - position: absolute; - bottom: 0; - left: 0; - width: 100%; - padding: inherit; - padding-top: 25px; - color: white; - overflow: hidden; - height: 20%; - z-index: 2; - background: -moz-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 13%, rgba(0, 0, 0, 0.77) 100%); - /* FF3.6+ */ - background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(0, 0, 0, 0)), color-stop(13%, rgba(0, 0, 0, 0.77)), color-stop(100%, rgba(0, 0, 0, 0.77))); - /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 13%, rgba(0, 0, 0, 0.77) 100%); - /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 13%, rgba(0, 0, 0, 0.77) 100%); - /* Opera 11.10+ */ - background: -ms-linear-gradient(top, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 13%, rgba(0, 0, 0, 0.77) 100%); - /* IE10+ */ - background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.77) 13%, rgba(0, 0, 0, 0.77) 100%); - /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#c4000000', GradientType=0); - /* IE6-9 */ -} -.mirador-container .annotationDetailToggle { - float: right; - margin: 32px; - margin-top: 0; - cursor: pointer; -} -.mirador-container .osd-annotation-overlay { - display: none; -} -.mirador-container .displayBottomPanelButton { - box-sizing: border-box; - position: absolute; - bottom: 0; - left: 0; - width: 100%; - padding: inherit; - color: #fff; - height: 75px; - z-index: 2; -} -.mirador-container .annotationDetails p { - width: 80%; - font-size: 1.3em; - font-weight: bold; - display: block; - margin: 0 auto; -} -.mirador-container #bookmark-panel { - position: absolute; - height: 20%; - width: 30%; - background-color: rgba(255, 255, 255, 0.94); - display: none; - overflow: hidden; - z-index: 6; - right: 0; - top: 0; - padding: 10px; -} -.mirador-container #bookmark-panel span { - width: 100%; - padding-left: 2%; -} -.mirador-container #bookmark-panel input { - width: 80%; - margin-right: 3px; -} -.mirador-container #bookmark-panel h3 { - text-align: center; -} -.mirador-container .mirador-viewer .sub-title { - border-bottom: 1px solid #b1b1b1; - color: #333; - font-weight: bold; - margin: 10px 20px 5px 20px; - padding: 0 5px 5px 0; - font-size: 120%; - text-transform: uppercase; -} -.mirador-container .mirador-viewer .metadata-listing { - width: 100%; - margin: 0; - padding: 0px 20px 10px 20px; - box-sizing: border-box; -} -.mirador-container .mirador-viewer .metadata-item { - padding: 10px 0 5px 0; -} -.mirador-container .mirador-viewer .metadata-label, -.mirador-container .mirador-viewer .metadata-value { - line-height: 1.5; -} -.mirador-container .mirador-viewer .metadata-label { - color: #666; - font-style: italic; - text-transform: uppercase; -} -.mirador-container .mirador-viewer .metadata-value { - vertical-align: bottom; -} -.mirador-container .mirador-viewer .metadata-listing a { - border-bottom: 1px dotted #005ebd; -} -.mirador-container .mirador-viewer .metadata-listing a:hover { - border-bottom: 1px dotted #dddddd; -} -.mirador-container .mirador-metadata-view-nav-toolbar { - float: right; - margin-right: 5px; -} -.mirador-container .metadata-logo { - max-height: 120px; - max-width: 100%; -} -.mirador-container .bottomPanel { - background-color: rgba(0, 0, 0, 0.7); - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 130px; - z-index: 4; - overflow: hidden; - display: none; - transition: transform 0.3s ease; -} -.mirador-container .bottomPanel.minimized { - transform: translateY(130px); -} -.mirador-container .panel-thumbnail-view { - position: absolute; - height: 100%; - width: 100%; - overflow-x: scroll; - overflow-y: hidden; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs { - clear: both; - list-style: none; - padding: 0; - white-space: nowrap; - margin-top: 10px; - margin-bottom: 4px; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li { - box-sizing: border-box; - padding: 0px 10px 0px 10px; - display: inline-block; - margin-bottom: 11px; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li.highlight { - padding-left: 8px; - padding-right: 8px; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img { - background-color: gray; - min-height: 25px; - min-width: 25px; - margin: 0 auto; - display: block; - box-sizing: border-box; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img.thumbnail-image { - background-color: gray; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.6); - float: left; - margin-right: 15px; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img.thumbnail-image.highlight { - border: 2px solid deepskyblue; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img:hover { - border: 2px solid rgba(0, 191, 255, 0.7); - transform: scale(1.1); - cursor: pointer; -} -.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li .thumb-label { - clear: both; - color: #999; - font-size: 12px; - margin: 0 auto; - max-width: 75px; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - text-align: center; -} -.mirador-container .layersPanel h3 { - margin: 10px 0; -} -.layersPanel { - position: absolute; - width: 285px; - left: 0; - right: 0; - top: 0; - bottom: 0; - overflow-y: scroll; -} -.layersPanel .layers-listing { - padding: 0; - list-style-type: none; - margin-top: 0; -} -.layersPanel .layers-list-item { - zoom: 1; - border-top: 1px solid #b1b1b1; - padding: 10px 10px 10px 0; - margin-right: 20px; -} -.layersPanel .layers-list-item:before, -.layersPanel .layers-list-item:after { - content: ""; - display: table; -} -.layersPanel .layers-list-item:after { - clear: both; -} -.layersPanel .layers-list-item > h4 { - margin-bottom: 5px; -} -.layersPanel .layers-list-item .thumb-container { - position: relative; - float: left; - width: 60px; - height: 60px; - margin-right: 10px; -} -.layersPanel .layers-list-item .thumb-container img { - position: relative; - margin: 0 auto; - max-height: 60px; - max-width: 60px; - display: block; - opacity: 0; - border: 1px solid gray; - box-shadow: inset 0 0 12px gray; - top: 50%; - transform: translateY(-50%); -} -.layersPanel .layers-list-item .thumb-container img.loaded { - transition: all 0.2s ease-out; - opacity: 1; -} -.layersPanel .layers-list-item .thumb-container .spinner, -.layersPanel .layers-list-item .thumb-container .failed, -.layersPanel .layers-list-item .thumb-container .thumb-failed { - position: absolute; - display: inline-block; - width: 100%; - margin: 0 auto; - top: 50%; - transform: translateY(-50%); - opacity: 0; - transition: all 0.2s ease-out; - color: #666; -} -.layersPanel .layers-list-item .thumb-container.awaiting-thumbnail .spinner { - opacity: 1; -} -.layersPanel .layers-list-item.requested .spinner { - opacity: 1; - transition: all 0.2s ease-out; -} -.layersPanel .layers-list-item.requested .thumb-container img { - transition: all 0.2s ease-out; - opacity: 0.5; -} -.layersPanel .layers-list-item.failed .failed { - opacity: 1; - transition: all 0.2s ease-out; -} -.layersPanel .layers-list-item.failed .thumb-container img { - transition: all 0.2s ease-out; - opacity: 0.5; -} -.layersPanel .layers-list-item.failed .thumb-failed { - opacity: 0; -} -.layersPanel .layers-list-item.failed .thumb-container.awaiting-thumbnail .spinner { - opacity: 0; - transition: all 0.2s ease-out; -} -.layersPanel .layers-list-item .visibility-toggle { - margin-bottom: 10px; -} -.layersPanel .disabled-overlay { - display: none; -} -.layersPanel.inactive > *:not(.disabled-overlay) { - display: none; -} -.layersPanel.inactive .disabled-overlay { - padding: 10px; - display: block; - box-sizing: border-box; - color: dimgray; -} -.mirador-container .search-results { - padding: 0 5px 0 0; - margin: 0; - position: absolute; - height: 100%; -} -.mirador-container .search-results select { - margin: 5px 0 10px 0; -} -.mirador-container .search-results-list { - position: relative; - height: 100%; -} -.mirador-container .search-results-list .search-results-messages { - border-top: 1px solid #b1b1b1; - padding-top: 10px; - margin-top: 10px; -} -.mirador-container .search-results-list .search-results-count { - font-size: .85em; -} -.mirador-container .search-results-list .search-results-container { - overflow-y: scroll; - position: absolute; - height: 70%; -} -.mirador-container .search-results-list .result-wrapper { - margin-bottom: 5px; -} -.mirador-container .search-results-list .result-wrapper .result-paragraph .highlight { - background-color: #ffff00; -} - -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url('../fonts/MaterialIcons-Regular.eot'); /* For IE6-8 */ - src: local('Material Icons'), - local('MaterialIcons-Regular'), - url('../fonts/MaterialIcons-Regular.woff2') format('woff2'), - url('../fonts/MaterialIcons-Regular.woff') format('woff'), - url('../fonts/MaterialIcons-Regular.ttf') format('truetype'); -} - -.material-icons { - font-family: 'Material Icons'; - font-weight: normal; - font-style: normal; - font-size: 24px; /* Preferred icon size */ - display: inline-block; - width: 1em; - height: 1em; - line-height: 1; - text-transform: none; - letter-spacing: normal; - word-wrap: normal; - white-space: nowrap; - direction: ltr; - - /* Support for all WebKit browsers. */ - -webkit-font-smoothing: antialiased; - /* Support for Safari and Chrome. */ - text-rendering: optimizeLegibility; - - /* Support for Firefox. */ - -moz-osx-font-smoothing: grayscale; - - /* Support for IE. */ - font-feature-settings: 'liga'; -} diff --git a/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.min.css b/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.min.css deleted file mode 100755 index 7f986d5b..00000000 --- a/iiif-5-day-workshop/day-three/mirador/css/mirador-combined.min.css +++ /dev/null @@ -1,12 +0,0 @@ -/*! - * Bootstrap v3.3.7 (http://getbootstrap.com) - * Copyright 2011-2016 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}[role=button]{cursor:pointer}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#337ab7;font-weight:400;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.in{opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.clearfix:after,.clearfix:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before{content:" ";display:table}.clearfix:after,.modal-footer:after,.modal-header:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}/*! normalize.css v2.1.2 | MIT License | git.io/normalize */article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}h1{font-size:2em;margin:.67em 0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;border:0;border-bottom:1px solid rgba(0,0,0,.4)}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}q{quotes:"\201C" "\201D" "\2018" "\2019"}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0}button,input{line-height:normal}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}textarea{overflow:auto;vertical-align:top}table{border-collapse:collapse;border-spacing:0}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(../fonts/fontawesome-webfont.eot?v=4.7.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont.woff2?v=4.7.0) format('woff2'),url(../fonts/fontawesome-webfont.woff?v=4.7.0) format('woff'),url(../fonts/fontawesome-webfont.ttf?v=4.7.0) format('truetype'),url(../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-close:before,.fa-remove:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-cog:before,.fa-gear:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-repeat:before,.fa-rotate-right:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-exclamation-triangle:before,.fa-warning:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-cogs:before,.fa-gears:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-floppy-o:before,.fa-save:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-sort:before,.fa-unsorted:before{content:"\f0dc"}.fa-sort-desc:before,.fa-sort-down:before{content:"\f0dd"}.fa-sort-asc:before,.fa-sort-up:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-gavel:before,.fa-legal:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-bolt:before,.fa-flash:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-clipboard:before,.fa-paste:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-chain-broken:before,.fa-unlink:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:"\f150"}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:"\f151"}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:"\f152"}.fa-eur:before,.fa-euro:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-inr:before,.fa-rupee:before{content:"\f156"}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:"\f157"}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:"\f158"}.fa-krw:before,.fa-won:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-try:before,.fa-turkish-lira:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-bank:before,.fa-institution:before,.fa-university:before{content:"\f19c"}.fa-graduation-cap:before,.fa-mortar-board:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:"\f1c5"}.fa-file-archive-o:before,.fa-file-zip-o:before{content:"\f1c6"}.fa-file-audio-o:before,.fa-file-sound-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:"\f1d0"}.fa-empire:before,.fa-ge:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-paper-plane:before,.fa-send:before{content:"\f1d8"}.fa-paper-plane-o:before,.fa-send-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-bed:before,.fa-hotel:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-y-combinator:before,.fa-yc:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-television:before,.fa-tv:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:"\f2a3"}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-sign-language:before,.fa-signing:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-address-card:before,.fa-vcard:before{content:"\f2bb"}.fa-address-card-o:before,.fa-vcard-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}/*! jQuery UI - v1.11.4 - 2016-04-08 -* http://jqueryui.com -* Includes: core.css, draggable.css, resizable.css, selectable.css, sortable.css, accordion.css, autocomplete.css, button.css, datepicker.css, dialog.css, menu.css, progressbar.css, selectmenu.css, slider.css, spinner.css, tabs.css, tooltip.css, theme.css -* To view and modify this theme, visit http://jqueryui.com/themeroller/ -* Copyright jQuery Foundation and other contributors; Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:after,.ui-helper-clearfix:before{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-draggable-handle{-ms-touch-action:none;touch-action:none}.ui-resizable{position:relative}.ui-resizable-handle{position:absolute;font-size:.1px;display:block;-ms-touch-action:none;touch-action:none}.ui-resizable-autohide .ui-resizable-handle,.ui-resizable-disabled .ui-resizable-handle{display:none}.ui-resizable-n{cursor:n-resize;height:7px;width:100%;top:-5px;left:0}.ui-resizable-s{cursor:s-resize;height:7px;width:100%;bottom:-5px;left:0}.ui-resizable-e{cursor:e-resize;width:7px;right:-5px;top:0;height:100%}.ui-resizable-w{cursor:w-resize;width:7px;left:-5px;top:0;height:100%}.ui-resizable-se{cursor:se-resize;width:12px;height:12px;right:1px;bottom:1px}.ui-resizable-sw{cursor:sw-resize;width:9px;height:9px;left:-5px;bottom:-5px}.ui-resizable-nw{cursor:nw-resize;width:9px;height:9px;left:-5px;top:-5px}.ui-resizable-ne{cursor:ne-resize;width:9px;height:9px;right:-5px;top:-5px}.ui-selectable{-ms-touch-action:none;touch-action:none}.ui-selectable-helper{position:absolute;z-index:100;border:1px dotted #000}.ui-sortable-handle{-ms-touch-action:none;touch-action:none}.ui-accordion .ui-accordion-header{display:block;cursor:pointer;position:relative;margin:2px 0 0 0;padding:.5em .5em .5em .7em;min-height:0;font-size:100%}.ui-accordion .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-icons .ui-accordion-icons{padding-left:2.2em}.ui-accordion .ui-accordion-header .ui-accordion-header-icon{position:absolute;left:.5em;top:50%;margin-top:-8px}.ui-accordion .ui-accordion-content{padding:1em 2.2em;border-top:0;overflow:auto}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-button{display:inline-block;position:relative;padding:0;line-height:normal;margin-right:.1em;cursor:pointer;vertical-align:middle;text-align:center;overflow:visible}.ui-button,.ui-button:active,.ui-button:hover,.ui-button:link,.ui-button:visited{text-decoration:none}.ui-button-icon-only{width:2.2em}button.ui-button-icon-only{width:2.4em}.ui-button-icons-only{width:3.4em}button.ui-button-icons-only{width:3.7em}.ui-button .ui-button-text{display:block;line-height:normal}.ui-button-text-only .ui-button-text{padding:.4em 1em}.ui-button-icon-only .ui-button-text,.ui-button-icons-only .ui-button-text{padding:.4em;text-indent:-9999999px}.ui-button-text-icon-primary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 1em .4em 2.1em}.ui-button-text-icon-secondary .ui-button-text,.ui-button-text-icons .ui-button-text{padding:.4em 2.1em .4em 1em}.ui-button-text-icons .ui-button-text{padding-left:2.1em;padding-right:2.1em}input.ui-button{padding:.4em 1em}.ui-button-icon-only .ui-icon,.ui-button-icons-only .ui-icon,.ui-button-text-icon-primary .ui-icon,.ui-button-text-icon-secondary .ui-icon,.ui-button-text-icons .ui-icon{position:absolute;top:50%;margin-top:-8px}.ui-button-icon-only .ui-icon{left:50%;margin-left:-8px}.ui-button-icons-only .ui-button-icon-primary,.ui-button-text-icon-primary .ui-button-icon-primary,.ui-button-text-icons .ui-button-icon-primary{left:.5em}.ui-button-icons-only .ui-button-icon-secondary,.ui-button-text-icon-secondary .ui-button-icon-secondary,.ui-button-text-icons .ui-button-icon-secondary{right:.5em}.ui-buttonset{margin-right:7px}.ui-buttonset .ui-button{margin-left:0;margin-right:-.3em}button.ui-button::-moz-focus-inner,input.ui-button::-moz-focus-inner{border:0;padding:0}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-next,.ui-datepicker .ui-datepicker-prev{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-next-hover,.ui-datepicker .ui-datepicker-prev-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-next span,.ui-datepicker .ui-datepicker-prev span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:700;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td a,.ui-datepicker td span{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-dialog{overflow:hidden;position:absolute;top:0;left:0;padding:.2em;outline:0}.ui-dialog .ui-dialog-titlebar{padding:.4em 1em;position:relative}.ui-dialog .ui-dialog-title{float:left;margin:.1em 0;white-space:nowrap;width:90%;overflow:hidden;text-overflow:ellipsis}.ui-dialog .ui-dialog-titlebar-close{position:absolute;right:.3em;top:50%;width:20px;margin:-10px 0 0 0;padding:1px;height:20px}.ui-dialog .ui-dialog-content{position:relative;border:0;padding:.5em 1em;background:0 0;overflow:auto}.ui-dialog .ui-dialog-buttonpane{text-align:left;border-width:1px 0 0 0;background-image:none;margin-top:.5em;padding:.3em 1em .5em .4em}.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset{float:right}.ui-dialog .ui-dialog-buttonpane button{margin:.5em .4em .5em 0;cursor:pointer}.ui-dialog .ui-resizable-se{width:12px;height:12px;right:-5px;bottom:-5px;background-position:16px 16px}.ui-draggable .ui-dialog-titlebar{cursor:move}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{position:relative;margin:0;padding:3px 1em 3px .4em;cursor:pointer;min-height:0;list-style-image:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-active,.ui-menu .ui-state-focus{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0}.ui-progressbar{height:2em;text-align:left;overflow:hidden}.ui-progressbar .ui-progressbar-value{margin:-1px;height:100%}.ui-progressbar .ui-progressbar-overlay{background:url(data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==);height:100%;opacity:.25}.ui-progressbar-indeterminate .ui-progressbar-value{background-image:none}.ui-selectmenu-menu{padding:0;margin:0;position:absolute;top:0;left:0;display:none}.ui-selectmenu-menu .ui-menu{overflow:auto;overflow-x:hidden;padding-bottom:1px}.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup{font-size:1em;font-weight:700;line-height:1.5;padding:2px .4em;margin:.5em 0 0 0;height:auto;border:0}.ui-selectmenu-open{display:block}.ui-selectmenu-button{display:inline-block;overflow:hidden;position:relative;text-decoration:none;cursor:pointer}.ui-selectmenu-button span.ui-icon{right:.5em;left:auto;margin-top:-8px;position:absolute;top:50%}.ui-selectmenu-button span.ui-selectmenu-text{text-align:left;padding:.4em 2.1em .4em 1em;display:block;line-height:1.4;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-slider{position:relative;text-align:left}.ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1.2em;height:1.2em;cursor:default;-ms-touch-action:none;touch-action:none}.ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;background-position:0 0}.ui-slider.ui-state-disabled .ui-slider-handle,.ui-slider.ui-state-disabled .ui-slider-range{filter:inherit}.ui-slider-horizontal{height:.8em}.ui-slider-horizontal .ui-slider-handle{top:-.3em;margin-left:-.6em}.ui-slider-horizontal .ui-slider-range{top:0;height:100%}.ui-slider-horizontal .ui-slider-range-min{left:0}.ui-slider-horizontal .ui-slider-range-max{right:0}.ui-slider-vertical{width:.8em;height:100px}.ui-slider-vertical .ui-slider-handle{left:-.3em;margin-left:0;margin-bottom:-.6em}.ui-slider-vertical .ui-slider-range{left:0;width:100%}.ui-slider-vertical .ui-slider-range-min{bottom:0}.ui-slider-vertical .ui-slider-range-max{top:0}.ui-spinner{position:relative;display:inline-block;overflow:hidden;padding:0;vertical-align:middle}.ui-spinner-input{border:none;background:0 0;color:inherit;padding:0;margin:.2em 0;vertical-align:middle;margin-left:.4em;margin-right:22px}.ui-spinner-button{width:16px;height:50%;font-size:.5em;padding:0;margin:0;text-align:center;position:absolute;cursor:default;display:block;overflow:hidden;right:0}.ui-spinner a.ui-spinner-button{border-top:none;border-bottom:none;border-right:none}.ui-spinner .ui-icon{position:absolute;margin-top:-8px;top:50%;left:0}.ui-spinner-up{top:0}.ui-spinner-down{bottom:0}.ui-spinner .ui-icon-triangle-1-s{background-position:-65px -16px}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav .ui-tabs-anchor{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor{cursor:text}.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:0 0}.ui-tooltip{padding:8px;position:absolute;z-index:9999;max-width:300px;-webkit-box-shadow:0 0 5px #aaa;box-shadow:0 0 5px #aaa}body .ui-tooltip{border-width:2px}.ui-widget{font-family:Verdana,Arial,sans-serif;font-size:1.1em}.ui-widget .ui-widget{font-size:1em}.ui-widget button,.ui-widget input,.ui-widget select,.ui-widget textarea{font-family:Verdana,Arial,sans-serif;font-size:1em}.ui-widget-content{border:1px solid #aaa;background:#fff;color:#222}.ui-widget-content a{color:#222}.ui-widget-header{border:1px solid #aaa;background:#ccc url(images/ui-bg_highlight-soft_75_cccccc_1x100.png) 50% 50% repeat-x;color:#222;font-weight:700}.ui-widget-header a{color:#222}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #d3d3d3;background:#e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x;font-weight:400;color:#555}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#555;text-decoration:none}.ui-state-focus,.ui-state-hover,.ui-widget-content .ui-state-focus,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-focus,.ui-widget-header .ui-state-hover{border:1px solid #999;background:#dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x;font-weight:400;color:#212121}.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#212121;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #aaa;background:#fff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x;font-weight:400;color:#212121}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#212121;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcefa1;background:#fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x;color:#363636}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#363636}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x;color:#cd0a0a}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#cd0a0a}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#cd0a0a}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:700}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:400}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_222222_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_888888_256x240.png)}.ui-state-focus .ui-icon,.ui-state-hover .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_454545_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_2e83ff_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_cd0a0a_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-left,.ui-corner-tl,.ui-corner-top{border-top-left-radius:4px}.ui-corner-all,.ui-corner-right,.ui-corner-top,.ui-corner-tr{border-top-right-radius:4px}.ui-corner-all,.ui-corner-bl,.ui-corner-bottom,.ui-corner-left{border-bottom-left-radius:4px}.ui-corner-all,.ui-corner-bottom,.ui-corner-br,.ui-corner-right{border-bottom-right-radius:4px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:-8px 0 0 -8px;padding:8px;background:#aaa;opacity:.3;filter:Alpha(Opacity=30);border-radius:8px}.qtip{position:absolute;left:-28000px;top:-28000px;display:none;max-width:280px;min-width:50px;font-size:10.5px;line-height:12px;direction:ltr;box-shadow:none;padding:0}.qtip-content{position:relative;padding:5px 9px;overflow:hidden;text-align:left;word-wrap:break-word}.qtip-titlebar{position:relative;padding:5px 35px 5px 10px;overflow:hidden;border-width:0 0 1px;font-weight:700}.qtip-titlebar+.qtip-content{border-top-width:0!important}.qtip-close{position:absolute;right:-9px;top:-9px;z-index:11;cursor:pointer;outline:0;border:1px solid transparent}.qtip-titlebar .qtip-close{right:4px;top:50%;margin-top:-9px}* html .qtip-titlebar .qtip-close{top:16px}.qtip-icon .ui-icon,.qtip-titlebar .ui-icon{display:block;text-indent:-1000em;direction:ltr}.qtip-icon,.qtip-icon .ui-icon{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;text-decoration:none}.qtip-icon .ui-icon{width:18px;height:14px;line-height:14px;text-align:center;text-indent:0;font:400 bold 10px/13px Tahoma,sans-serif;color:inherit;background:-100em -100em no-repeat}.qtip-default{border:1px solid #f1d031;background-color:#ffffa3;color:#555}.qtip-default .qtip-titlebar{background-color:#ffef93}.qtip-default .qtip-icon{border-color:#ccc;background:#f1f1f1;color:#777}.qtip-default .qtip-titlebar .qtip-close{border-color:#aaa;color:#111}.qtip-light{background-color:#fff;border-color:#e2e2e2;color:#454545}.qtip-light .qtip-titlebar{background-color:#f1f1f1}.qtip-dark{background-color:#505050;border-color:#303030;color:#f3f3f3}.qtip-dark .qtip-titlebar{background-color:#404040}.qtip-dark .qtip-icon{border-color:#444}.qtip-dark .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-cream{background-color:#fbf7aa;border-color:#f9e98e;color:#a27d35}.qtip-cream .qtip-titlebar{background-color:#f0de7d}.qtip-cream .qtip-close .qtip-icon{background-position:-82px 0}.qtip-red{background-color:#f78b83;border-color:#d95252;color:#912323}.qtip-red .qtip-titlebar{background-color:#f06d65}.qtip-red .qtip-close .qtip-icon{background-position:-102px 0}.qtip-red .qtip-icon,.qtip-red .qtip-titlebar .ui-state-hover{border-color:#d95252}.qtip-green{background-color:#caed9e;border-color:#90d93f;color:#3f6219}.qtip-green .qtip-titlebar{background-color:#b0de78}.qtip-green .qtip-close .qtip-icon{background-position:-42px 0}.qtip-blue{background-color:#e5f6fe;border-color:#add9ed;color:#5e99bd}.qtip-blue .qtip-titlebar{background-color:#d0e9f5}.qtip-blue .qtip-close .qtip-icon{background-position:-2px 0}.qtip-shadow{-webkit-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);-moz-box-shadow:1px 1px 3px 1px rgba(0,0,0,.15);box-shadow:1px 1px 3px 1px rgba(0,0,0,.15)}.qtip-bootstrap,.qtip-rounded,.qtip-tipsy{-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.qtip-rounded .qtip-titlebar{-moz-border-radius:4px 4px 0 0;-webkit-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0}.qtip-youtube{-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 3px #333;-moz-box-shadow:0 0 3px #333;box-shadow:0 0 3px #333;color:#fff;border:0 solid transparent;background:#4a4a4a;background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#4a4a4a),color-stop(100%,#000));background-image:-webkit-linear-gradient(top,#4a4a4a 0,#000 100%);background-image:-moz-linear-gradient(top,#4a4a4a 0,#000 100%);background-image:-ms-linear-gradient(top,#4a4a4a 0,#000 100%);background-image:-o-linear-gradient(top,#4a4a4a 0,#000 100%)}.qtip-youtube .qtip-titlebar{background-color:transparent}.qtip-youtube .qtip-content{padding:.75em;font:12px arial,sans-serif}.qtip-youtube .qtip-icon{border-color:#222}.qtip-youtube .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-jtools{background:#232323;background:rgba(0,0,0,.7);background-image:-webkit-gradient(linear,left top,left bottom,from(#717171),to(#232323));background-image:-moz-linear-gradient(top,#717171,#232323);background-image:-webkit-linear-gradient(top,#717171,#232323);background-image:-ms-linear-gradient(top,#717171,#232323);background-image:-o-linear-gradient(top,#717171,#232323);border:2px solid #ddd;border:2px solid rgba(241,241,241,1);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-webkit-box-shadow:0 0 12px #333;-moz-box-shadow:0 0 12px #333;box-shadow:0 0 12px #333}.qtip-jtools .qtip-content,.qtip-jtools .qtip-titlebar{background:0 0;color:#fff;border:0 dashed transparent}.qtip-jtools .qtip-icon{border-color:#555}.qtip-jtools .qtip-titlebar .ui-state-hover{border-color:#333}.qtip-cluetip{-webkit-box-shadow:4px 4px 5px rgba(0,0,0,.4);-moz-box-shadow:4px 4px 5px rgba(0,0,0,.4);box-shadow:4px 4px 5px rgba(0,0,0,.4);background-color:#d9d9c2;color:#111;border:0 dashed transparent}.qtip-cluetip .qtip-titlebar{background-color:#87876a;color:#fff;border:0 dashed transparent}.qtip-cluetip .qtip-icon{border-color:#808064}.qtip-cluetip .qtip-titlebar .ui-state-hover{border-color:#696952;color:#696952}.qtip-tipsy{background:#000;background:rgba(0,0,0,.87);color:#fff;border:0 solid transparent;font-size:11px;font-family:'Lucida Grande',sans-serif;font-weight:700;line-height:16px;text-shadow:0 1px #000}.qtip-tipsy .qtip-titlebar{padding:6px 35px 0 10px;background-color:transparent}.qtip-tipsy .qtip-content{padding:6px 10px}.qtip-tipsy .qtip-icon{border-color:#222;text-shadow:none}.qtip-tipsy .qtip-titlebar .ui-state-hover{border-color:#303030}.qtip-tipped{border:3px solid #959fa9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-color:#f9f9f9;color:#454545;font-weight:400;font-family:serif}.qtip-tipped .qtip-titlebar{border-bottom-width:0;color:#fff;background:#3a79b8;background-image:-webkit-gradient(linear,left top,left bottom,from(#3a79b8),to(#2e629d));background-image:-webkit-linear-gradient(top,#3a79b8,#2e629d);background-image:-moz-linear-gradient(top,#3a79b8,#2e629d);background-image:-ms-linear-gradient(top,#3a79b8,#2e629d);background-image:-o-linear-gradient(top,#3a79b8,#2e629d)}.qtip-tipped .qtip-icon{border:2px solid #285589;background:#285589}.qtip-tipped .qtip-icon .ui-icon{background-color:#fbfbfb;color:#555}.qtip-bootstrap{font-size:14px;line-height:20px;color:#333;padding:1px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.qtip-bootstrap .qtip-titlebar{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.qtip-bootstrap .qtip-titlebar .qtip-close{right:11px;top:45%;border-style:none}.qtip-bootstrap .qtip-content{padding:9px 14px}.qtip-bootstrap .qtip-icon{background:0 0}.qtip-bootstrap .qtip-icon .ui-icon{width:auto;height:auto;float:right;font-size:20px;font-weight:700;line-height:18px;color:#000;text-shadow:0 1px 0 #fff;opacity:.2}.qtip-bootstrap .qtip-icon .ui-icon:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4}.qtip:not(.ie9haxors) div.qtip-content,.qtip:not(.ie9haxors) div.qtip-titlebar{filter:none;-ms-filter:none}.qtip .qtip-tip{margin:0 auto;overflow:hidden;z-index:10}.qtip .qtip-tip,x:-o-prefocus{visibility:hidden}.qtip .qtip-tip,.qtip .qtip-tip .qtip-vml,.qtip .qtip-tip canvas{position:absolute;color:#123456;background:0 0;border:0 dashed transparent}.qtip .qtip-tip canvas{top:0;left:0}.qtip .qtip-tip .qtip-vml{behavior:url(#default#VML);display:inline-block;visibility:visible}#qtip-overlay{position:fixed;left:0;top:0;width:100%;height:100%}#qtip-overlay.blurs{cursor:pointer}#qtip-overlay div{position:absolute;left:0;top:0;width:100%;height:100%;background-color:#000;opacity:.7;-ms-filter:"alpha(Opacity=70)"}.qtipmodal-ie6fix{position:absolute!important}.sp-container{position:absolute;top:0;left:0;display:inline-block;z-index:9999994;overflow:hidden}.sp-container.sp-flat{position:relative}.sp-container,.sp-container *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}.sp-top{position:relative;width:100%;display:inline-block}.sp-top-inner{position:absolute;top:0;left:0;bottom:0;right:0}.sp-color{position:absolute;top:0;left:0;bottom:0;right:20%}.sp-hue{position:absolute;top:0;right:0;bottom:0;left:84%;height:100%}.sp-clear-enabled .sp-hue{top:33px;height:77.5%}.sp-fill{padding-top:80%}.sp-sat,.sp-val{position:absolute;top:0;left:0;right:0;bottom:0}.sp-alpha-enabled .sp-top{margin-bottom:18px}.sp-alpha-enabled .sp-alpha{display:block}.sp-alpha-handle{position:absolute;top:-4px;bottom:-4px;width:6px;left:50%;cursor:pointer;border:1px solid #000;background:#fff;opacity:.8}.sp-alpha{display:none;position:absolute;bottom:-14px;right:0;left:0;height:8px}.sp-alpha-inner{border:solid 1px #333}.sp-clear{display:none}.sp-clear.sp-clear-display{background-position:center}.sp-clear-enabled .sp-clear{display:block;position:absolute;top:0;right:0;bottom:0;left:84%;height:28px}.sp-alpha,.sp-alpha-handle,.sp-clear,.sp-container,.sp-container button,.sp-container.sp-dragging .sp-input,.sp-dragger,.sp-preview,.sp-replacer,.sp-slider{-webkit-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}.sp-container.sp-input-disabled .sp-input-container{display:none}.sp-container.sp-buttons-disabled .sp-button-container{display:none}.sp-container.sp-palette-buttons-disabled .sp-palette-button-container{display:none}.sp-palette-only .sp-picker-container{display:none}.sp-palette-disabled .sp-palette-container{display:none}.sp-initial-disabled .sp-initial{display:none}.sp-sat{background-image:-webkit-gradient(linear,0 0,100% 0,from(#fff),to(rgba(204,154,129,0)));background-image:-webkit-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-moz-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-o-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:-ms-linear-gradient(left,#fff,rgba(204,154,129,0));background-image:linear-gradient(to right,#fff,rgba(204,154,129,0))}.sp-val{background-image:-webkit-gradient(linear,0 100%,0 0,from(#000),to(rgba(204,154,129,0)));background-image:-webkit-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-moz-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-o-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:-ms-linear-gradient(bottom,#000,rgba(204,154,129,0));background-image:linear-gradient(to top,#000,rgba(204,154,129,0))}.sp-hue{background:-moz-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-ms-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-o-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:-webkit-gradient(linear,left top,left bottom,from(red),color-stop(.17,#ff0),color-stop(.33,#0f0),color-stop(.5,#0ff),color-stop(.67,#00f),color-stop(.83,#f0f),to(red));background:-webkit-linear-gradient(top,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%);background:linear-gradient(to bottom,red 0,#ff0 17%,#0f0 33%,#0ff 50%,#00f 67%,#f0f 83%,red 100%)}.sp-1{height:17%}.sp-2{height:16%}.sp-3{height:17%}.sp-4{height:17%}.sp-5{height:16%}.sp-6{height:17%}.sp-hidden{display:none!important}.sp-cf:after,.sp-cf:before{content:"";display:table}.sp-cf:after{clear:both}@media (max-device-width:480px){.sp-color{right:40%}.sp-hue{left:63%}.sp-fill{padding-top:60%}}.sp-dragger{border-radius:5px;height:5px;width:5px;border:1px solid #fff;background:#000;cursor:pointer;position:absolute;top:0;left:0}.sp-slider{position:absolute;top:0;cursor:pointer;height:3px;left:-1px;right:-1px;border:1px solid #000;background:#fff;opacity:.8}.sp-container{border-radius:0;background-color:#ececec;border:solid 1px #f0c49b;padding:0}.sp-clear,.sp-color,.sp-container,.sp-container button,.sp-container input,.sp-hue{font:normal 12px "Lucida Grande","Lucida Sans Unicode","Lucida Sans",Geneva,Verdana,sans-serif;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;-ms-box-sizing:border-box;box-sizing:border-box}.sp-top{margin-bottom:3px}.sp-clear,.sp-color,.sp-hue{border:solid 1px #666}.sp-input-container{float:right;width:100px;margin-bottom:4px}.sp-initial-disabled .sp-input-container{width:100%}.sp-input{font-size:12px!important;border:1px inset;padding:4px 5px;margin:0;width:100%;background:0 0;border-radius:3px;color:#222}.sp-input:focus{border:1px solid orange}.sp-input.sp-validation-error{border:1px solid red;background:#fdd}.sp-palette-container,.sp-picker-container{float:left;position:relative;padding:10px;padding-bottom:300px;margin-bottom:-290px}.sp-picker-container{width:172px;border-left:solid 1px #fff}.sp-palette-container{border-right:solid 1px #ccc}.sp-palette-only .sp-palette-container{border:0}.sp-palette .sp-thumb-el{display:block;position:relative;float:left;width:24px;height:15px;margin:3px;cursor:pointer;border:solid 2px transparent}.sp-palette .sp-thumb-el.sp-thumb-active,.sp-palette .sp-thumb-el:hover{border-color:orange}.sp-thumb-el{position:relative}.sp-initial{float:left;border:solid 1px #333}.sp-initial span{width:30px;height:25px;border:none;display:block;float:left;margin:0}.sp-initial .sp-clear-display{background-position:center}.sp-button-container,.sp-palette-button-container{float:right}.sp-replacer{margin:0;overflow:hidden;cursor:pointer;padding:4px;display:inline-block;border:solid 1px #91765d;background:#eee;color:#333;vertical-align:middle}.sp-replacer.sp-active,.sp-replacer:hover{border-color:#f0c49b;color:#111}.sp-replacer.sp-disabled{cursor:default;border-color:silver;color:silver}.sp-dd{padding:2px 0;height:16px;line-height:16px;float:left;font-size:10px}.sp-preview{position:relative;width:25px;height:20px;border:solid 1px #222;margin-right:5px;float:left;z-index:0}.sp-palette{max-width:220px}.sp-palette .sp-thumb-el{width:16px;height:16px;margin:2px 1px;border:solid 1px #d0d0d0}.sp-container{padding-bottom:0}.sp-container button{background-color:#eee;background-image:-webkit-linear-gradient(top,#eee,#ccc);background-image:-moz-linear-gradient(top,#eee,#ccc);background-image:-ms-linear-gradient(top,#eee,#ccc);background-image:-o-linear-gradient(top,#eee,#ccc);background-image:linear-gradient(to bottom,#eee,#ccc);border:1px solid #ccc;border-bottom:1px solid #bbb;border-radius:3px;color:#333;font-size:14px;line-height:1;padding:5px 4px;text-align:center;text-shadow:0 1px 0 #eee;vertical-align:middle}.sp-container button:hover{background-color:#ddd;background-image:-webkit-linear-gradient(top,#ddd,#bbb);background-image:-moz-linear-gradient(top,#ddd,#bbb);background-image:-ms-linear-gradient(top,#ddd,#bbb);background-image:-o-linear-gradient(top,#ddd,#bbb);background-image:linear-gradient(to bottom,#ddd,#bbb);border:1px solid #bbb;border-bottom:1px solid #999;cursor:pointer;text-shadow:0 1px 0 #ddd}.sp-container button:active{border:1px solid #aaa;border-bottom:1px solid #888;-webkit-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-moz-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-ms-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;-o-box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee;box-shadow:inset 0 0 5px 2px #aaa,0 1px 0 0 #eee}.sp-cancel{font-size:11px;color:#d93f3f!important;margin:0;padding:2px;margin-right:5px;vertical-align:middle;text-decoration:none}.sp-cancel:hover{color:#d93f3f!important;text-decoration:underline}.sp-palette span.sp-thumb-active,.sp-palette span:hover{border-color:#000}.sp-alpha,.sp-preview,.sp-thumb-el{position:relative;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAIAAADZF8uwAAAAGUlEQVQYV2M4gwH+YwCGIasIUwhT25BVBADtzYNYrHvv4gAAAABJRU5ErkJggg==)}.sp-alpha-inner,.sp-preview-inner,.sp-thumb-inner{display:block;position:absolute;top:0;left:0;bottom:0;right:0}.sp-palette .sp-thumb-inner{background-position:50% 50%;background-repeat:no-repeat}.sp-palette .sp-thumb-light.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAIVJREFUeNpiYBhsgJFMffxAXABlN5JruT4Q3wfi/0DsT64h8UD8HmpIPCWG/KemIfOJCUB+Aoacx6EGBZyHBqI+WsDCwuQ9mhxeg2A210Ntfo8klk9sOMijaURm7yc1UP2RNCMbKE9ODK1HM6iegYLkfx8pligC9lCD7KmRof0ZhjQACDAAceovrtpVBRkAAAAASUVORK5CYII=)}.sp-palette .sp-thumb-dark.sp-thumb-active .sp-thumb-inner{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAadEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjEwMPRyoQAAAMdJREFUOE+tkgsNwzAMRMugEAahEAahEAZhEAqlEAZhEAohEAYh81X2dIm8fKpEspLGvudPOsUYpxE2BIJCroJmEW9qJ+MKaBFhEMNabSy9oIcIPwrB+afvAUFoK4H0tMaQ3XtlrggDhOVVMuT4E5MMG0FBbCEYzjYT7OxLEvIHQLY2zWwQ3D+9luyOQTfKDiFD3iUIfPk8VqrKjgAiSfGFPecrg6HN6m/iBcwiDAo7WiBeawa+Kwh7tZoSCGLMqwlSAzVDhoK+6vH4G0P5wdkAAAAASUVORK5CYII=)}.sp-clear-display{background-repeat:no-repeat;background-position:center;background-image:url(data:image/gif;base64,R0lGODlhFAAUAPcAAAAAAJmZmZ2dnZ6enqKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq/Hx8fLy8vT09PX19ff39/j4+Pn5+fr6+vv7+wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAP8ALAAAAAAUABQAAAihAP9FoPCvoMGDBy08+EdhQAIJCCMybCDAAYUEARBAlFiQQoMABQhKUJBxY0SPICEYHBnggEmDKAuoPMjS5cGYMxHW3IiT478JJA8M/CjTZ0GgLRekNGpwAsYABHIypcAgQMsITDtWJYBR6NSqMico9cqR6tKfY7GeBCuVwlipDNmefAtTrkSzB1RaIAoXodsABiZAEFB06gIBWC1mLVgBa0AAOw==)}.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir=rtl] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:#fff;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff}.select2-hidden-accessible{border:0!important;clip:rect(0 0 0 0)!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:700}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:#fff;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:700;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:700;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-search--inline,.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__placeholder{float:right}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid #000 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple,.select2-container--default.select2-container--open.select2-container--above .select2-selection--single{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple,.select2-container--default.select2-container--open.select2-container--below .select2-selection--single{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:0 0;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:#fff}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top,#fff 50%,#eee 100%);background-image:-o-linear-gradient(top,#fff 50%,#eee 100%);background-image:linear-gradient(to bottom,#fff 50%,#eee 100%);background-repeat:repeat-x}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:700;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top,#eee 50%,#ccc 100%);background-image:-o-linear-gradient(top,#eee 50%,#ccc 100%);background-image:linear-gradient(to bottom,#eee 50%,#ccc 100%);background-repeat:repeat-x}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir=rtl] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:0 0;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top,#fff 0,#eee 50%);background-image:-o-linear-gradient(top,#fff 0,#eee 50%);background-image:linear-gradient(to bottom,#fff 0,#eee 50%);background-repeat:repeat-x}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top,#eee 50%,#fff 100%);background-image:-o-linear-gradient(top,#eee 50%,#fff 100%);background-image:linear-gradient(to bottom,#eee 50%,#fff 100%);background-repeat:repeat-x}.select2-container--classic .select2-selection--multiple{background-color:#fff;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:700;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice{float:right}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir=rtl] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb}.mirador-container .mirador-main-menu-bar,.mirador-container .mirador-status-bar,.mirador-container .mirador-viewer{font-family:'Open Sans','Lucida Grande',Verdana,Arial,sans-serif}.mirador-container .ui-dialog-titlebar{display:none}.mirador-container .ui-dialog{overflow:hidden;padding:0}.mirador-container .slot.ui-dialog-content{margin:0}.mirador-container .qtip-bootstrap{border-radius:2px;padding:0;background-color:#fafafa}.mirador-container .qtip-bootstrap .qtip-content{padding:0;clear:both}.mirador-container .qtip-viewer .qtip-content{min-width:275px;max-height:200px;overflow:auto}.mirador-container .qtip-content{text-align:inherit}.mirador-container .annotation-tooltip{padding:10px}.mirador-container .annotation-editor{cursor:move}.mirador-container .annotation-display{position:relative;border-left:0;border-right:0;padding:12px;padding-bottom:0;border-bottom:1px solid gray}.mirador-container .annotation-display:last-child{border:none}.mirador-container .annotation-tooltip .button-container{text-align:right}.mirador-container .annotation-tooltip .cancel,.mirador-container .annotation-tooltip .save{margin-left:12px;font-size:12px;text-decoration:underline}.mirador-container .annotation-tooltip .cancel:hover,.mirador-container .annotation-tooltip .save:hover{font-weight:700}.mirador-container .select2-container,.mirador-container .tags-editor,.mirador-container .text-editor{padding:5px;display:block;margin:6px 0 6px 0;border:0;background:#efefef;box-shadow:inset 0 0 7px gray;resize:vertical;border:1px solid gray;width:200px}.mirador-container .select2-container .select2-selection--multiple,.mirador-container .tags-editor .select2-selection--multiple,.mirador-container .text-editor .select2-selection--multiple{border:none;background-color:inherit;font-size:16px}.mirador-container .annotation-display.annotation-tooltip .button-container{text-align:right}.mirador-container .annotation-display .delete,.mirador-container .annotation-display .edit{font-size:12px;margin-left:5px;text-decoration:underline}.mirador-container .annotation-display .text-viewer a{border-bottom:1px dotted #005ebd}.mirador-container .annotation-display .text-viewer a:hover{border-bottom:1px dotted #ddd}.mirador-container .text-viewer p{margin-top:0}.mirador-container .text-viewer p.user{color:gray;font-style:italic;font-size:11px}.mirador-container .tags-viewer{margin-bottom:12px}.mirador-container .qtip-bootstrap .tags-viewer span.tag{background:#d3d3d3;color:#222;border-radius:6px;padding:0 5px;margin-right:5px;margin-bottom:5px;text-align:center;font-size:12;font-weight:700;border:1px solid #aaa;display:inline-block}.mirador-container .mce-edit-area iframe{height:75px!important}.mirador-container a{color:inherit;text-decoration:inherit}.mirador-container .mirador-loading{background-color:#fff;border:1px solid #999;padding:20px}.mirador-container .mirador-btn{cursor:pointer;display:inline-block;height:20px;width:20px;margin-top:9px}.mirador-container .mirador-btn.disabled{opacity:.5}.mirador-container .disabled{opacity:.5;pointer-events:none}.mirador-container a.mirador-icon-annotations [class^=icon-]{display:block;position:absolute}.mirador-container a.mirador-icon-view-type [class^=icon-]{display:block;position:absolute}.mirador-container a.mirador-icon-empty-slot [class^=icon-]{display:block;position:absolute}.mirador-container .mirador-viewer{position:absolute;top:33px;bottom:0;left:0;right:0;overflow:hidden;box-sizing:border-box;-moz-border-sizing:border-box;margin:0;padding:0;border:0}.mirador-container .mirador-viewer a.mirador-icon-annotations{background:0 0;color:#929191;box-sizing:border-box}.mirador-container .mirador-viewer a.mirador-icon-annotations:hover{color:#000}.mirador-container .mirador-viewer ul.dropdown{display:none;width:160px;z-index:3;opacity:.98;background-color:#efefef;text-align:center;list-style:none;position:absolute;padding:0;margin-top:10px;height:auto;box-shadow:0 2px 4px #b1b1b1;border:1px solid #b1b1b1}.mirador-container .mirador-viewer .dropdown li{margin:0;cursor:pointer;box-sizing:border-box;background-color:#ddd;padding:10px;width:100%;text-align:left}.mirador-container .mirador-viewer .dropdown li:hover{border-left:3px solid #00bfff;background-color:#ddd;padding-left:7px;font-weight:700}.mirador-container .mirador-viewer a.mirador-icon-metadata-view,.mirador-container .mirador-viewer a.mirador-icon-view-type,.mirador-container .mirador-viewer a.mirador-osd-fullscreen{background:0 0;color:#929191;box-sizing:border-box;margin-right:5px;padding-bottom:30px}.mirador-container .mirador-viewer a.mirador-close-window,.mirador-container .mirador-viewer a.mirador-icon-toc,.mirador-container .mirador-viewer a.mirador-icon-window-menu{float:left;background:0 0;color:#929191;box-sizing:border-box;margin-left:5px;padding-bottom:30px}.mirador-container a.mirador-icon-view-type,.mirador-container a.mirador-icon-window-menu{width:30px}.mirador-container .mirador-viewer a.mirador-icon-empty-slot:hover,.mirador-container .mirador-viewer a.mirador-icon-metadata-view:hover,.mirador-container .mirador-viewer a.mirador-icon-toc:hover,.mirador-container .mirador-viewer a.mirador-icon-view-type:hover,.mirador-container .mirador-viewer a.mirador-icon-window-menu:hover,.mirador-container .mirador-viewer a.mirador-osd-fullscreen:hover{color:#000}.mirador-container .mirador-viewer a.mirador-icon-metadata-view.selected,.mirador-container .mirador-viewer a.mirador-icon-toc.selected,.mirador-container .mirador-viewer a.mirador-icon-view-type.selected{color:#000}.mirador-container .mirador-viewer a.mirador-icon-copy{background:0 0;box-sizing:border-box}.mirador-container input[type=submit],.mirador-container input[type=text]{height:25px;border:1px solid #d3d3d3;transition:border-color .3s ease-out}.mirador-container input:focus{outline:0;border-color:#00bfff}.mirador-container input[type=submit]{color:gray;background:#fff}.mirador-container input[type=submit]:hover{outline:0;border-color:#00bfff;color:#333}.mirador-container :-moz-full-screen :-ms-fullscreen,.mirador-container :-webkit-full-screen,.mirador-container :fullscreen,.mirador-container:-moz-full-screen .mirador-container:-ms-fullscreen,.mirador-container:-webkit-full-screen,.mirador-container:fullscreen{height:100%;left:0;margin:0;top:0;width:100%}.mirador-container .workspace-container{position:absolute;left:0;right:0;top:0;bottom:0;overflow:hidden;box-sizing:border-box;margin:3px}.mirador-container .layout-slot{position:absolute;margin:0;padding:0;box-sizing:border-box}.mirador-container .slot{width:100%;height:100%;box-shadow:inset 0 0 35px #000;overflow:hidden;box-sizing:border-box}.mirador-container .slot .remove-slot-option{position:absolute;margin:10px;color:gray;cursor:pointer}.mirador-container .slot .remove-slot-option:hover{float:left;margin:10px;color:#d3d3d3}.mirador-container .slot h1{color:gray;text-align:center;font-weight:400;margin:0}.mirador-container .slot:hover h1{color:#d3d3d3}.mirador-container .plus{font-size:170px;font-weight:700;margin-bottom:2%}.mirador-container .slotIconContainer{position:relative;top:50%;transform:translateY(-50%);width:100%;overflow:hidden;pointer-events:none}.mirador-container .slot.draggedOver,.mirador-container .slot.focused,.mirador-container .slot:hover{box-shadow:inset 0 0 35px #5edbff}.mirador-container .slot.draggedOver .dropIcon,.mirador-container .slot.draggedOver .dropMeMessage{display:block}.mirador-container .dropIcon,.mirador-container .dropMeMessage{display:none}.mirador-container .slot.draggedOver .addItemText,.mirador-container .slot.draggedOver .plus span{display:none}.mirador-container .addItemLink{display:block;position:absolute;top:0;bottom:0;right:0;left:0;cursor:pointer}.mirador-container .dropMask{position:absolute;top:0;bottom:0;right:0;left:0;display:none}.mirador-container .mirador-main-menu-bar{background-color:#000;border-bottom:1px solid #555;color:#fff;height:33px;width:100%;font-size:14px;top:0}.mirador-container .mirador-main-menu-bar .window-options-menu{position:relative;border-radius:0;display:none}.mirador-container .mirador-main-menu{float:right;list-style:none;margin:0;padding:8px 12px 0 0;text-align:right}.mirador-container .mirador-main-menu li{cursor:pointer;float:left;padding:0 15px}.mirador-container .mirador-main-menu a{color:#fff;font-weight:400;text-decoration:none;opacity:.6}.mirador-container .mirador-main-menu a:hover{opacity:1}.mirador-container .mirador-main-menu a:active{opacity:1;border-bottom:2px solid #00bfff}.mirador-container .mirador-main-menu.user-buttons{padding-right:0}.mirador-container .mirador-main-menu.user-logo{padding-right:0;padding-left:0;float:left}.mirador-container .mirador-window-options-menu{list-style:none;margin:0;padding:10px 5px}.mirador-container .mirador-window-options-menu li{cursor:pointer;padding:3px 5px}.mirador-container .window-manifest-title{text-overflow:ellipsis;max-width:80%;overflow:hidden;white-space:nowrap;padding-left:10px;margin:8px 0 8px 0;font-weight:700;font-size:16px}.mirador-container .window-manifest-navigation{float:right;width:24%;text-align:right;padding-right:10px;font-size:16px}.mirador-container .mirador-status-bar{background-color:#ccc;border-top:1px solid #000;bottom:0;color:#000;position:fixed}.mirador-container .mirador-status-bar-msg-left,.mirador-container .mirador-status-bar-msg-right{color:#666;float:left;overflow:hidden;padding:4px 10px;text-align:left;text-overflow:ellipsis;white-space:nowrap;width:40%}.mirador-container .mirador-status-bar-msg-right{float:right;text-align:right}.mirador-container .window{position:absolute;width:100%;height:100%;overflow:hidden;background-color:#333;top:0}.mirador-container .manifest-info{overflow:auto;background:#fafafa}.mirador-container .manifest-info .mirador-btn{font-size:.8em}.mirador-container .content-container{position:absolute;bottom:0;left:0;right:0;top:0;margin-top:34px;box-sizing:border-box}.mirador-container .view-container{margin-left:280px;height:100%;position:relative;transition:all 0s ease}.mirador-container .view-container.focus-max-width{margin-left:0}.mirador-container .view-container.focus-side-panel-minimized{margin-left:0}.mirador-container .overlay{display:none;position:absolute;right:0;top:0;box-sizing:border-box;background-color:rgba(255,255,255,.9);z-index:5;width:45%;overflow-y:scroll;height:80%;word-wrap:break-word;font-size:90%}.mirador-container .book-view,.mirador-container .image-view,.mirador-container .scroll-view,.mirador-container .thumbnail-view{height:100%;width:100%;background-color:#000;display:none;overflow-y:scroll}.mirador-container .book-view,.mirador-container .image-view{overflow:hidden}.mirador-container .scroll-view{overflow-y:hidden;overflow-x:scroll}.mirador-container .focus-max-height{height:100%}.mirador-container .focus-bottom-panel-minimized{height:95%}.mirador-container .image-list{right:0}.mirador-container .slot-controls{left:0}.mirador-container .menu-divider{color:#b1b1b1;margin:0;height:0}.mirador-container .v-direction-rtl{direction:rtl}.mirador-container canvas{outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0)}.mirador-container .mirador-osd{background-color:#000;width:100%;height:100%}.mirador-container .hud-control{color:#fff;text-shadow:0 0 5px #000;opacity:.6;font-size:18px;z-index:2}.mirador-container .hud-container{color:#fff;text-shadow:0 0 5px #000;transition:all .3s ease;font-size:18px;z-index:2}.mirador-container .hud-control.hud-disabled{opacity:.3}.mirador-container .hud-control:not(.hud-disabled):hover{cursor:pointer;opacity:1}.mirador-container .hud-control.selected{opacity:1}.mirador-container .hud-control.hidden{opacity:0}.mirador-container .mirador-osd-previous{position:absolute;left:1%;top:50%;margin-top:-35px;width:40px;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0);transition:all .2s ease-out}.mirador-container .mirador-osd-previous.bottom-panel-open{-webkit-transform:translateY(-65px);-moz-transform:translateY(-65px);-ms-transform:translateY(-65px);-o-transform:translateY(-65px);transform:translateY(-65px);transition:all .2s ease-out}.mirador-container .mirador-osd-next{position:absolute;right:1%;top:50%;margin-top:-35px;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0);transition:all .2s ease-out}.mirador-container .mirador-osd-next.bottom-panel-open{-webkit-transform:translateY(-65px);-moz-transform:translateY(-65px);-ms-transform:translateY(-65px);-o-transform:translateY(-65px);transform:translateY(-65px);transition:all .2s ease-out}.mirador-container .mirador-osd-toggle-bottom-panel{position:absolute;bottom:0;right:50%;margin-right:-25px;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0);transition:all .2s ease-out}.mirador-container .mirador-osd-toggle-bottom-panel.bottom-panel-open{-webkit-transform:translateY(-130px);-moz-transform:translateY(-130px);-ms-transform:translateY(-130px);-o-transform:translateY(-130px);transform:translateY(-130px);transition:all .2s ease-out}.mirador-container .mirador-pan-zoom-controls{position:absolute;width:100px;height:65px;bottom:0;right:0;margin:1%}.mirador-container .mirador-pan-zoom-controls.bottom-panel-open{-webkit-transform:translateY(-130px);-moz-transform:translateY(-130px);-ms-transform:translateY(-130px);-o-transform:translateY(-130px);transform:translateY(-130px);transition:all .2s ease-out}.mirador-container .mirador-osd-up{position:absolute;right:20px;top:0}.mirador-container .mirador-osd-right{position:absolute;right:0;top:20px}.mirador-container .mirador-osd-down{position:absolute;right:20px;top:40px}.mirador-container .mirador-osd-left{position:absolute;right:40px;top:20px}.mirador-container .mirador-osd-zoom-in{font-size:130%;position:absolute;right:70px;top:5px}.mirador-container .mirador-osd-zoom-out{font-size:130%;position:absolute;right:70px;top:30px}.mirador-container .mirador-osd-go-home{position:absolute;right:20px;top:20px}.mirador-container .mirador-osd-context-controls{position:absolute;top:10px;left:10px;transition:none}.mirador-container .mirador-osd-context-controls>div{clear:both}.mirador-container .mirador-osd-context-controls>div>a:first-child{margin-bottom:10px}.mirador-container .mirador-osd-context-controls a{float:left;margin:0 10px 0 0;font-weight:400}.mirador-container .mirador-annotation-controls{position:absolute;top:0;left:0}.mirador-container .mirador-manipulation-controls{min-width:364px}.mirador-container .mirador-mirror{-moz-transform:scale(-1,1);-webkit-transform:scale(-1,1);-o-transform:scale(-1,1);transform:scale(-1,1);filter:FlipH}.mirador-container .mirador-osd-color-picker *{text-shadow:none}.mirador-container .sp-dd{display:none}.mirador-container .mirador-osd-color-picker .dropdown-icon{font-size:.8em;height:30px;vertical-align:middle}.mirador-container .mirador-osd-color-picker .sp-container{width:300px;border-color:#ccc;opacity:.9;border-radius:3px}.mirador-container .mirador-osd-color-picker .sp-preview{height:10px}.mirador-container .mirador-osd-color-picker .sp-replacer{border-color:#ccc;height:11px;border-radius:3px;cursor:default}.mirador-container .mirador-osd-color-picker .material-icons{float:left;font-size:12px;margin:0 5px 0 0}.mirador-container .hud-control.mirador-line-type{height:11px;border-radius:3px;margin:2px 11px 0 0;padding:4px;width:57px;border:1px solid #ccc;background:#eee none repeat scroll 0 0;text-shadow:none;color:#333}.mirador-container .mirador-line-type ul.dropdown.type-list{margin-top:-14px;border-radius:3px;margin-left:-5px;font-size:10px;box-shadow:none;width:140px}.mirador-container .mirador-line-type ul i{display:inline-block;width:25px;height:1em;background:no-repeat;margin-right:10px}.mirador-container .mirador-line-type .mirador-border-icon{font-size:12px;margin:0 5px 0 0;float:left}.mirador-container .mirador-line-type .border-type-image{display:inline-block;width:25px;height:1em;background:no-repeat;margin:0 5px 2px 0}.mirador-container .mirador-line-type .dropdown-icon{font-size:.8em;height:30px;vertical-align:middle}.mirador-container .mirador-image-view-nav-toolbar{position:relative;float:right;margin-right:5px}.mirador-container .mirador-image-view-bg{background-color:#000}.mirador-container .mirador-image-scale{bottom:25px;display:block;position:absolute;z-index:2}.mirador-container .axis line,.mirador-container .axis path{fill:none;shape-rendering:crispEdges;stroke:#fff;stroke-width:2px}.mirador-container text{fill:#fff;text-shadow:0 0 3px #000}.mirador-container .mirador-image-dimensions{margin-right:10px;margin-top:7px;position:absolute;right:0;top:0}.mirador-container .mirador-image-view-physical-dimensions{border:none;font-weight:700;height:16px;margin:0;outline:0;overflow-wrap:normal;overflow:hidden;padding:0;resize:none;vertical-align:top;width:40px;text-align:center}.mirador-container .mirador-image-dimensions.noDimensionsSet .mirador-image-view-physical-dimensions,.mirador-container .mirador-image-view-physical-dimensions:focus,.mirador-container .mirador-image-view-physical-dimensions:hover{border-bottom:2px solid #ff4500;height:16px;margin-bottom:-2px;transition:all .2s ease-out}.mirador-container .noDimensionsWarning{display:none;margin-right:10px}.mirador-container .mirador-image-dimensions.noDimensionsSet .noDimensionsWarning{color:rgba(0,0,0,.5);display:inline-block}.mirador-container .mirador-image-view-physical-dimensions:focus{background-color:rgba(200,200,200,.7);box-shadow:0 0 4px rgba(200,200,200,.7);-webkit-transform:scale(1.2);-moz-transform:scale(1.2);transform:scale(1.2)}.mirador-container .mirador-image-dimensions .units{cursor:context-menu}.mirador-container .mirador-image-dimensions .units:hover{height:16px;border-bottom:2px solid #ff4500;margin-bottom:-2px;transition:all .2s ease-out}.mirador-container .mirador-image-dimensions .unit-selector{position:absolute;display:none}.mirador-container .mirador-image-dimensions .unit-selector.active{display:block}.mirador-container .mirador-image-scale.hidden{display:none}.mirador-container .mirador-image-view-choices{list-style:none;max-height:350px;overflow:auto;padding:0}.mirador-container .mirador-image-view-choices li{margin:0;padding:0}.mirador-container .mirador-image-view-choices li a{padding-left:12px}.mirador-container .mirador-image-view-choice{background-repeat:no-repeat;height:6px;background-position:0 6px;width:6px}.mirador-container .mirador-image-view-choice{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RUQ5OEI2ODFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RUQ5OEI2OTFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRFRDk4QjY2MUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRFRDk4QjY3MUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+fRx/ZQAAAHRJREFUeNpi/P//P0NnZ2cNAwNDOgMEzCwvL29h5uTkrFFSUkqOiorSMjMzm/L27ds5W7Zs4WUCqfT09NTh4eH5BsIgNkiMiQENMDIy/gdRIImZO3bsuPL161fOz58/c23fvv0qSIwRankt1PK/UMvbAAIMALeqLWb/azLQAAAAAElFTkSuQmCC)}.mirador-container .mirador-image-view-choice-selected{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo0RUQ5OEI2QzFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo0RUQ5OEI2RDFFMkIxMUUzOUExN0IyREY1RTI1MUQ0QiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjRFRDk4QjZBMUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjRFRDk4QjZCMUUyQjExRTM5QTE3QjJERjVFMjUxRDRCIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+9DJqAgAAAF1JREFUeNpitLS0ZHj69GktAwNDJgMETJeWlm5mZmJiAgk2ATEvFDt+/vz5H6OcnNwzIEeSARU8Z2LADhiZ+fn5uUDa0SS6mbW0tA4BzfwP5GgC8Ucg7gJa3gIQYAChCRXFhBXUngAAAABJRU5ErkJggg==)}.mirador-container ul.scroll-listing-thumbs{clear:both;list-style:none;padding:0;white-space:nowrap}.mirador-container ul.scroll-listing-thumbs li{box-sizing:border-box;margin:0 0 15px 0;padding:10px 10px 10px 10px;display:inline-block}.mirador-container ul.scroll-listing-thumbs li img{background-color:#eee;min-height:25px;min-width:25px;margin:0 auto;display:block}.mirador-container ul.scroll-listing-thumbs li .thumb-label{clear:both;color:#999;font-size:12px;margin:0 auto;max-width:200px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center}.mirador-container .mirador-viewer ul.listing-thumbs{clear:both;list-style:none;overflow:auto;padding:0}.mirador-container .mirador-viewer ul.listing-thumbs li{box-sizing:border-box;float:left;margin:0 0 15px 0;padding:10px 10px 10px 10px}.mirador-container .mirador-viewer ul.listing-thumbs li img{background-color:#eee;min-height:25px;min-width:25px;margin:0 auto;display:block;box-sizing:border-box}.mirador-container .mirador-viewer ul.listing-thumbs li img:hover{border:3px solid rgba(0,191,255,.7);transform:scale(1.1);cursor:pointer;transition:all .2 ease-out}.mirador-container .mirador-viewer ul.listing-thumbs li .thumb-label{clear:both;color:#999;font-size:12px;margin:0 auto;max-width:125px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center}.mirador-container .mirador-viewer .thumbnails-view-slider{float:left;margin:10px 15px;width:60px}.mirador-container .mirador-thumbnails-view-nav-toolbar{float:right;margin-right:5px}.mirador-container .mirador-widget-toolbar .ui-slider-horizontal{height:.4em}.mirador-container .mirador-widget-toolbar .ui-slider-handle{top:-.5em}.mirador-container .hud-control .ui-slider-handle .percent{position:absolute;left:17px;top:-.3em;display:block;color:#fff;text-shadow:0 0 3px #000}.mirador-container .hud-control .ui-slider,.mirador-container .ui-slider-vertical{width:3px;margin-left:27px;margin-bottom:20px;height:100px}.mirador-container .hud-control .ui-slider-vertical .ui-slider-handle{width:.7em;height:.7em;border-radius:40px;margin-bottom:-.35em}.mirador-container .hud-control .ui-slider-vertical .ui-slider-handle:focus{outline:0}.mirador-container .hud-control .ui-slider-range{background:#00bfff}.mirador-container .thumbnail-rtl{float:right!important}@media screen and (max-width:768px){.mirador-container #load-controls form{float:none}.mirador-container #url-load-form{margin-bottom:5px}}.mirador-container #manifest-select-menu{position:absolute;margin:6px;display:block;left:0;right:0;bottom:0;top:0;display:none;overflow:hidden;z-index:18000;background-color:#fff;box-shadow:0 0 6px #333}.mirador-container #manifest-select-menu .container{position:relative;width:100%;height:100%;padding:10px 4px 10px 10px;box-sizing:border-box;overflow:hidden;margin:0 auto}.mirador-container #manifest-select-menu .remove-object-option{cursor:pointer;display:inline-block;font-size:.9em;font-weight:700;transition:color .2s ease-out}.mirador-container #manifest-select-menu .remove-object-option:hover{color:#929191}.mirador-container .items-listing{margin:0;padding-left:0;box-sizing:border-box}.mirador-container .items-listing li{list-style-type:none;overflow:hidden;border-bottom:1px solid #d3d3d3;padding-top:10px;padding-bottom:10px;position:relative;padding-left:5px;transition:background-color .3s ease-out}.mirador-container .items-listing li:hover{background-color:#ddd;cursor:pointer}.mirador-container .manifest-load-status-indicator{width:100%;padding:10px;box-sizing:border-box;overflow:hidden;background:rgba(255,255,255,.94);position:absolute}.mirador-container .request-status-bar{background:#00bfff;width:10px;height:50px;display:inline-block;margin-left:5px;vertical-align:bottom;transition:all .1s ease-out}.mirador-container .request-status-bar.pending{background:gray;transition:all .1s ease-out}.mirador-container .loading-status{display:block}.mirador-container .request-status-bar:nth-child(2){margin-left:0}.mirador-container .repository-label{border-top:1px solid rgba(0,0,0,.7);padding-top:3px;position:absolute;bottom:0;width:100%}.mirador-container .select-metadata{width:45%;max-width:450px;min-width:300px;position:relative}.mirador-container .repo-image{position:relative;width:80px;height:80px;overflow:hidden;opacity:.5}.mirador-container .repo-image img{position:absolute;width:100%;top:0}.mirador-container .repo-image span.default-logo{position:absolute;width:100%;height:100%;top:0;background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAACMCAYAAACuwEE+AAAACXBIWXMAAAsTAAALEwEAmpwYAAAKT2lDQ1BQaG90b3Nob3AgSUNDIHByb2ZpbGUAAHjanVNnVFPpFj333vRCS4iAlEtvUhUIIFJCi4AUkSYqIQkQSoghodkVUcERRUUEG8igiAOOjoCMFVEsDIoK2AfkIaKOg6OIisr74Xuja9a89+bN/rXXPues852zzwfACAyWSDNRNYAMqUIeEeCDx8TG4eQuQIEKJHAAEAizZCFz/SMBAPh+PDwrIsAHvgABeNMLCADATZvAMByH/w/qQplcAYCEAcB0kThLCIAUAEB6jkKmAEBGAYCdmCZTAKAEAGDLY2LjAFAtAGAnf+bTAICd+Jl7AQBblCEVAaCRACATZYhEAGg7AKzPVopFAFgwABRmS8Q5ANgtADBJV2ZIALC3AMDOEAuyAAgMADBRiIUpAAR7AGDIIyN4AISZABRG8lc88SuuEOcqAAB4mbI8uSQ5RYFbCC1xB1dXLh4ozkkXKxQ2YQJhmkAuwnmZGTKBNA/g88wAAKCRFRHgg/P9eM4Ors7ONo62Dl8t6r8G/yJiYuP+5c+rcEAAAOF0ftH+LC+zGoA7BoBt/qIl7gRoXgugdfeLZrIPQLUAoOnaV/Nw+H48PEWhkLnZ2eXk5NhKxEJbYcpXff5nwl/AV/1s+X48/Pf14L7iJIEyXYFHBPjgwsz0TKUcz5IJhGLc5o9H/LcL//wd0yLESWK5WCoU41EScY5EmozzMqUiiUKSKcUl0v9k4t8s+wM+3zUAsGo+AXuRLahdYwP2SycQWHTA4vcAAPK7b8HUKAgDgGiD4c93/+8//UegJQCAZkmScQAAXkQkLlTKsz/HCAAARKCBKrBBG/TBGCzABhzBBdzBC/xgNoRCJMTCQhBCCmSAHHJgKayCQiiGzbAdKmAv1EAdNMBRaIaTcA4uwlW4Dj1wD/phCJ7BKLyBCQRByAgTYSHaiAFiilgjjggXmYX4IcFIBBKLJCDJiBRRIkuRNUgxUopUIFVIHfI9cgI5h1xGupE7yAAygvyGvEcxlIGyUT3UDLVDuag3GoRGogvQZHQxmo8WoJvQcrQaPYw2oefQq2gP2o8+Q8cwwOgYBzPEbDAuxsNCsTgsCZNjy7EirAyrxhqwVqwDu4n1Y8+xdwQSgUXACTYEd0IgYR5BSFhMWE7YSKggHCQ0EdoJNwkDhFHCJyKTqEu0JroR+cQYYjIxh1hILCPWEo8TLxB7iEPENyQSiUMyJ7mQAkmxpFTSEtJG0m5SI+ksqZs0SBojk8naZGuyBzmULCAryIXkneTD5DPkG+Qh8lsKnWJAcaT4U+IoUspqShnlEOU05QZlmDJBVaOaUt2ooVQRNY9aQq2htlKvUYeoEzR1mjnNgxZJS6WtopXTGmgXaPdpr+h0uhHdlR5Ol9BX0svpR+iX6AP0dwwNhhWDx4hnKBmbGAcYZxl3GK+YTKYZ04sZx1QwNzHrmOeZD5lvVVgqtip8FZHKCpVKlSaVGyovVKmqpqreqgtV81XLVI+pXlN9rkZVM1PjqQnUlqtVqp1Q61MbU2epO6iHqmeob1Q/pH5Z/YkGWcNMw09DpFGgsV/jvMYgC2MZs3gsIWsNq4Z1gTXEJrHN2Xx2KruY/R27iz2qqaE5QzNKM1ezUvOUZj8H45hx+Jx0TgnnKKeX836K3hTvKeIpG6Y0TLkxZVxrqpaXllirSKtRq0frvTau7aedpr1Fu1n7gQ5Bx0onXCdHZ4/OBZ3nU9lT3acKpxZNPTr1ri6qa6UbobtEd79up+6Ynr5egJ5Mb6feeb3n+hx9L/1U/W36p/VHDFgGswwkBtsMzhg8xTVxbzwdL8fb8VFDXcNAQ6VhlWGX4YSRudE8o9VGjUYPjGnGXOMk423GbcajJgYmISZLTepN7ppSTbmmKaY7TDtMx83MzaLN1pk1mz0x1zLnm+eb15vft2BaeFostqi2uGVJsuRaplnutrxuhVo5WaVYVVpds0atna0l1rutu6cRp7lOk06rntZnw7Dxtsm2qbcZsOXYBtuutm22fWFnYhdnt8Wuw+6TvZN9un2N/T0HDYfZDqsdWh1+c7RyFDpWOt6azpzuP33F9JbpL2dYzxDP2DPjthPLKcRpnVOb00dnF2e5c4PziIuJS4LLLpc+Lpsbxt3IveRKdPVxXeF60vWdm7Obwu2o26/uNu5p7ofcn8w0nymeWTNz0MPIQ+BR5dE/C5+VMGvfrH5PQ0+BZ7XnIy9jL5FXrdewt6V3qvdh7xc+9j5yn+M+4zw33jLeWV/MN8C3yLfLT8Nvnl+F30N/I/9k/3r/0QCngCUBZwOJgUGBWwL7+Hp8Ib+OPzrbZfay2e1BjKC5QRVBj4KtguXBrSFoyOyQrSH355jOkc5pDoVQfujW0Adh5mGLw34MJ4WHhVeGP45wiFga0TGXNXfR3ENz30T6RJZE3ptnMU85ry1KNSo+qi5qPNo3ujS6P8YuZlnM1VidWElsSxw5LiquNm5svt/87fOH4p3iC+N7F5gvyF1weaHOwvSFpxapLhIsOpZATIhOOJTwQRAqqBaMJfITdyWOCnnCHcJnIi/RNtGI2ENcKh5O8kgqTXqS7JG8NXkkxTOlLOW5hCepkLxMDUzdmzqeFpp2IG0yPTq9MYOSkZBxQqohTZO2Z+pn5mZ2y6xlhbL+xW6Lty8elQfJa7OQrAVZLQq2QqboVFoo1yoHsmdlV2a/zYnKOZarnivN7cyzytuQN5zvn//tEsIS4ZK2pYZLVy0dWOa9rGo5sjxxedsK4xUFK4ZWBqw8uIq2Km3VT6vtV5eufr0mek1rgV7ByoLBtQFr6wtVCuWFfevc1+1dT1gvWd+1YfqGnRs+FYmKrhTbF5cVf9go3HjlG4dvyr+Z3JS0qavEuWTPZtJm6ebeLZ5bDpaql+aXDm4N2dq0Dd9WtO319kXbL5fNKNu7g7ZDuaO/PLi8ZafJzs07P1SkVPRU+lQ27tLdtWHX+G7R7ht7vPY07NXbW7z3/T7JvttVAVVN1WbVZftJ+7P3P66Jqun4lvttXa1ObXHtxwPSA/0HIw6217nU1R3SPVRSj9Yr60cOxx++/p3vdy0NNg1VjZzG4iNwRHnk6fcJ3/ceDTradox7rOEH0x92HWcdL2pCmvKaRptTmvtbYlu6T8w+0dbq3nr8R9sfD5w0PFl5SvNUyWna6YLTk2fyz4ydlZ19fi753GDborZ752PO32oPb++6EHTh0kX/i+c7vDvOXPK4dPKy2+UTV7hXmq86X23qdOo8/pPTT8e7nLuarrlca7nuer21e2b36RueN87d9L158Rb/1tWeOT3dvfN6b/fF9/XfFt1+cif9zsu72Xcn7q28T7xf9EDtQdlD3YfVP1v+3Njv3H9qwHeg89HcR/cGhYPP/pH1jw9DBY+Zj8uGDYbrnjg+OTniP3L96fynQ89kzyaeF/6i/suuFxYvfvjV69fO0ZjRoZfyl5O/bXyl/erA6xmv28bCxh6+yXgzMV70VvvtwXfcdx3vo98PT+R8IH8o/2j5sfVT0Kf7kxmTk/8EA5jz/GMzLdsAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAE/JJREFUeNrsnX+olFd6xz9nGC4XERGxIiJBUgmpmDQk2WCzaWqsiPmBbLNpPLPW/UHChiRtNt25IVlkG1wJacp9DQntbgPbbOhuMrNJ1lprVWzIusHaRSSVIGGRrAQRERERkdvL5TJP/3jPtG/efX+c875n5o56HrjM3Hl/nvN+n9/PeV4lIgQKZEuNMAWBAmACBcAECoAJFAATKAAmUKAAmEABMIECYAIFwAQKgAkUABMoUABMoACYQAEwgQJgAgXABLpeqVnlIKVUmLmrkCYmJhCRhhEUY8D05ORkb+CACXRVAWQcuAG4XURuAVYDy4FlwIPAxwEw1zG1222AJcBaEbkfuEcptUJEmmnNYKQNATDXJ1DGgHuBrcBDwMIsG7Vu0X8AzNUPlHnAV4DvALcnn6lSCt+rQgJgrl6gNIENwIvAnUXSJP0ZAHP9gWU58DLwKDBWJkn6231IHK+A0Vr3z9lH+6xSqtfpdObSAOzfzzgwDcwCvSiKnM/XarUaItKfsx7Q63a7vWGNx3g9G4A3gBW2dolPCaOqnCRtbWut5xs9+iBwK7AYuAJ8DhwH9iulDnU6ndkh6vX1wP3AXcaNHAemgJPAvwNvRVF03pIJbgS+BtwHrFBKzRORC+Zc/wXsBj7rdruDBEsDeEZEXgbG+88gKTmSEiT5W3K/1DFfmpycPDY0wGitG8Am4NUk4jOoB5wGfgS82e12LwwIKEuBbwNPmDhDEZ0Htiml3swLXhlG2A48ZQCXR7PAR8BrwL5utzvreVxNo4K+S4XofIFKGh5gWq0WIvIM8IpSajwP7Rk3+zmwQyn1s06nM+PRpfy6MQCXp7krLZ4T9zID/C2wPYqiXgosC4EOsDFr0nM+Z4FDwPPdbvdjj2B5BXhWKdXIGkfeeLOkTUrSOAOmci5JRNYBLwHjRaBL60+l1ArgDRF5W2u91MOELgN+CvxIKbU879r9vxTwx4AXgIfTtooZ28a8h5Dz2VRKrQd+qbV+Smtdy0bsqyHz1yizQ5LjtHkmVagSYMxEbAfmK6UKc0v9bal9mkqpR4D9WutVrVarkkHbbrdXAvuNt9CsODljwI52uz2eOOZ24JvpcSXHmvWZ2H+BUU+vaq3n1WDKDcCO/th8uslVj60qYW4F1mRxr+PnbcC/ishNLqCZmJjA2Ez7zb04TWTGfjcBaxO7bAXmpcdVNs4UZzeBvwRe01qPV2CIFcbmm1f34fv0kqoCZq1SqpnkrCLOK/lcCfyLiCx14I4lwL8BKy2kmY231wD+uN1uo7UeA+7JO2eZhMn4/XFgh4t6arfbfZW4wsVbdZTyQwXMH7hwnsXnKuCfbDjRqI6fEGdda3FSar/VZj4WGDfceRwF8/As8BcOUnQ98IgvtTIKEmaBBWc5fQIPAM8aV70oEPdds+/vcI0tJ+XstyhhCI95lDB99RSJyGpLj+8lcx+FEqVgLgufyVwABs8Spk/PZ0mOlO30XB6XudowOXPRcPCKrOfBAPLVVqs1VjK1m4hrV0rvu2guS+5l6IC5ksVZHv4WAttbrVYzJx7xIrAw69gyrs/aL8Wpl82kzgAznsfVv8ZaEXk4TzUZN/pppVQjy/uykWYF1878bViA+W0dEVeC9AdEZE3G73dmxUXqpjUS9JmJSF82UWDvZByF50RkLGdeVicNbhfDdVhls1UBc1xEerYiMk8k5mwfA54wOZyk7fJY0tXNClIVqQmL/f87iiK63e408GnWflXUVE4oYW2OfbYZaOa580XjsNjvnIgcEJF9IvKJiEwPEzC/Jk4uWnGBq+FIXOexJHGKhcBDlmLfVU1AnMU+nLjef1Th5jIj01yzAWxJMkQigLip6riKVDDwY+APoyi6P4qiB4E7gFuMVHWiqqHri8AB4NGyfIVDjilJi01gcI/5/y5gSZnRlr6mg3o6JiInE5sOAhdFZFEyw5seZ5aqLcjbJK+5nv8vt+jTjcCqOiH9nO17gCejKPq/hKj5/hnA5OTk4CWMSeP/hLjepbZLncEZDeDLiUveBTTyOMpGqhWE8XvAGzt37kwefhrY6zN0kLrmUhNd/kIwtD/GstSDreQhzqJ/PwmWOXOrgQ+Bo7Yupu3/id+TE/r7ee6irZ1R8P0EcT1LmiFeE5Ep17RA3n6ptEHDSJSk/fJll3EU7ZfYfsL8zbnRS7fbnQG2i8h0UZKuLOhUwP1LEu7nEhc9brufKUfYEUVRlj12HHinyG7JCpTZuMH9MSW+jwOrbNxgl1ACcMxIUEZBwgB8AHTz0O5qU6RofvL+8ri2pueyO2EnfYE6nU4P2CEiZ11tirz5SNHCZOQcuKFMgrkG74DfVilFHRhgTD3rNuJSxcKJs40TJMB2KcEdU1nGpc05UxIluekU0I6iaKbg2NPEyzcqcWkJk1xMSZsFeQZ1WpLZFHwbujQqcZjkDZ4FHhORyx5iFEmOOpsoHj+V9TBsCoWy9jP3+g1j3OZSp9NBKbUL2Fk1NVBwv2cSm5cBYzb2Sln1v880wEAAYyb1MPAtYMqXRwH8Z+IyvwJ6WarOZXLMcdPmXg/biOtOp9NTSm0Dfgb0XJOPWTaOuYfjic2L0tKkbi5p1CK9vwMaYBewte9Z2IAjT12JyCUTC+nTYeBUuuq9LC+S3kdErhjJsttFt5va4yf6oKkbwDO2XzL9sCRrbHnutM11BpUq8NYfxriiu4CvisiZKnmdhKh9J2kXRVF0GYj6D6u/XxlnpdTFaeCrwLvpgm/L8U0BT4rITuLi8UoPx4TkX06tZxrPs1HyjHuXeR1JwPRBo5Q6APypyVnMWk5i8vMI8GLGGp+3ROSfk6opL7aS+m3WeEL3RVF0sI7X0O12p5RS3wO2iMgpVy/J3MvLZoxJ+j0b9eJaajEI8r5U1qink1rrPwMeEZHnTYyhWbI0omdE9bey1i1FUTTdbrf/yuj/x/slogXh+VkTh3gF2Osr2mkW472vtT4MtEXkm8DiopSI+T5FXHb5d2lmSC4fsWEum7RLHuhM+ecik544Umb4DxwwqcDeO1rr3cR1IFuB9SKyKCHZeiLSI85+/0N8WDc3ixpF0ZV2u/00cQ3wX5tw+pg5X8/8nRORg8Rrij4qcptrju9cq9V6TkReNYyxmbh7wlhqfFeAfcSL/Y5mrY50lQauxq9ZYjsG3E1c4P6ASU98yRUwlReymVLKhu0qP5OdHTMh/xuMxJkCfgOcdV2DbcLpC4Gb+eLS3DNKqVnbpJopiZxJqyqtddPcU6m9Yxb1Nfr3o5RabOb1vAnNXylaRjsxMRERl556JRF50jgMLUArpW5MbXdeyFZHwiwAfqG1/hWwSyn1adHkmgmbwVN+wzzgS8SlFk5kqvduJa4/uRf4k7QhS1zI9aTW+m3gQNHyXgP0ngnGHfEc4LNi4JxzfN94YE1frnezxk02RGSVUmqdiDwvIsfM5O5VSp2z4cxhktHdNxA3DWgBtyqlxkXkQk6eaExENiqlNojIBa31AeBt4IhS6orPjhR123AUHLvMd5ym6WnA84B7ReRe4IKIfKC17gCHlVIX56rdh9HdS4yts8V8LnB8QA3DpV8Xka8Bp0Rkl9b6PeDTIpurzgPPusei2pyR7w+TN0hjT2gReRT4XET2GvAc9zG5liCZB6wRkRbxYvplmFoTmwhqQWCsaWywF4hbbxzXWv+cOIl5pmqvmKzWHUVznrePZXFaLeA0fYrR1M02RORGpdQzIvIUcMJM7rtKqdM+e8UkGgetFJEtxIvrb8ZyyUiZC5vzOQ+4Wyl1t4jsAA4ZlXwQuOwCnipLZVzjMr5U08Dc6tRNNYmLn29TSr0oIocMePYCF6o24jHSZJmxSzYbt7HpyoE2kdGSkoUFSqlNwCYROQfsMVL1CDBTNr6sRkA2TGrZgsRa8swpYPIGZ8LgG83fReCA1vptpdSHnU5n2lKazAc2GmmyznhspSrGheOy7Iec8aSP6Tc1epy4brartX6vzIu08Zh8SZSRkTAVlscuMoakFpHTWuv3gZ8DH6dFuvFy7jYezsPENSSNvDZdeQXYLpzmUiWYsb0B3CQifwO8ICJHjcrabbzI5APs2QDSRYIU2T91gNP0rHqqUoO4U8EEca+XO4B03GORAdMyV46sY8NYqqQySdvvCHEPcIuIPJ3abb7N+atKlLog8QoYl+UWNstQ+jZIFqjy8kdZHFRml5RJmLycUNH48vZPbWtmXKtZdB1bxnVt7DRUCZPRisxpgK4TYmOoVc3J2Ijwon2LJEJRPMWnJPMo7UtVQW17ZRjrel3qQFzbfdhIGZtz2hRzlakMX1K+yryMkls9lPLCGi3LCl1w3/ZQ1RLTqsw0Cu0+nFHvut7ah5dWlzNd77+qhPHtnY6shKmz6L4KWGzcRheDfABhAqftZcDN6+RdFi+yiSdVDd41fIrCuoEll9JC25pem+UorqK8YhsTq+tk1fBm/W9THppjiE8DR0WkTVyLNLdxmEHmN2zXS/tYs1MXFC7jK4ga15rrBM0SZ9n3mFjWiSiKpsG9e4M3ozdP1JXlP+rYFenzF72kwdVFLxuPbUbYBgyuKsImR2S+XwL2isjbxOuwrsy5l2TTxdKmFUcdUFYBVx1j0tb2yguWlQXYiuI3jstMtkVR9MORiMPYqATfNkwVlWRzf1VtGF8hg0GoJPPde9XjUCWMzadLMrBu9NjGtij6Pe9aVSRoWZCwKN2Qdy+DiPw2fEgW1wDSIAbkem6XzhJ14xs+4h9lKYlR76JZ2mCnavyh6sCrxHSq2DWDoDrXHxZQvHpJRV6D6/9lk+Cj2Nl2v2F5SUUBtqLffFbSDRUweZKjCnDqinefEqaskU+Z3eHiJVX9rUiyDgI83sobfAbyXEoIBi1hXAN1c6GahqlWa68aGLYOrTNBLscNamw5oYPLNmuNylTQVaGS6q6Vyfq/Kie6pgZclpm4gq/swbtKbhcpPZJeUnLwdd5ZVMXar+rm+rhmWbtYm/IG1xjMXHtGA4vD1C0HsJ2oGi3LKl3PFXCuLn5WGcM117LMpjbD1TCskCsZSsyijmQa1P1VkWQjZcP4+r+qfq/idbiWHLicyzU2YtHi3nsR/JwApu5yzfSnS5zChQNLln54H58LAH1JBJuWZSMZuBvEuVxVVZVcV5lbXdWmKQONrwc7DG9pTpfKuhiHNgvmisDjCsQiA7LmElpnaVg1JjSSEsam64BNnMbVoC7iKlcuriPVfAQLXWpf5pq8x2FcjMKqEzHMOEzV6kEfHs8oxV+8AaaqWqoivl1BlldQVGXibUszqqxLcqltrhIkHdnAXV2d72LcVglS1bFjXMBdZV2S6+uBqkjYObVh0v3+fcVhfMR+fF3LJgZStF56WDUqw4zHDKTdxyAGW8Y9Ng+06muFfdpULm/GLXIKbNuUjLRbPch+az4Xutmcs6xr1aDGV3SP10S22lccxsXDcUnG2STrXG2YKuMtslNsgoRV53Nk4zCDVkk2S2IHsebZxbPxOW6fLctGLg5TJ/YxTO4YRKxnGC02Rom8rHwsW2BlY6wOUw/bgGNUIqvXHGDqRl19cmJoWTZ4uqraffi2F1xyX1WbJ2dtH8aS1msiDlPWvtT2Ibq0Wrdx+W0MXpfssWt23GYdV5GLn7V95OIwPpKGdWpRXd4WX0Vsu5Q3+FIRRa60bR/iQaungdT0hpZl1dSt75Zl170Nc622LLOt36nRsmx0vKQyD8W1+5QP1WG75rnOeOrEYbJskzprpIa5zCS0LBsyaIbcsmw0A3fDsmGu1ZZlNud0VUmDUkuhZdkItCwri5bb7BNalnkyvm32n+uWZXXWU4eWZddhy7JhBU7nOnDXw7xN/mptWWZoioz2pCIyC/TM23Fzr3G9tSyrI2EuAX8kIt8BjhK3J891E315TumODOmkX1bRUkYXhxngI+Ax4I4oimYzrrPXjO914GyZNLS9lyLJmrVf0W85krUHnAR+QPzW3tGQMOYll2eB17XWPxSRVUBLRL5C/DLwRlVPaUAty3rACeA94F3gsyiKegXjmwWOaq2PAt8TkfVmfOuBxT7tsbrSwRx7xgCkA/wamImiaPS8JIButzsLfKK1/gR4CVgDbAE2KKWWDUJvO0zu6cREHlNKTbu8kMG8c3oK2NNqtfaKyFLgAeK3264xLzx3AkeRSnJpWQZcAg6ZdwkcAi4MAiTeAZOa3CvAB61W60MRWWw4civxK4QXDKll2QWjcvoTedHHRJr3Tp8Ffqy1fgtYKSKPAn9upOqYbQDONfaT+G1KRI4Tv5VkN3CmSFKONGAyJvc88I7WugusJH5z/GZgtVJqvGpDv5x9p4CPzUTuAU4PktuMVP0N8AOt9SRwlwHOQ8DytH1YVHJg8faVWRE5BewyKvVEFEUzc+GVNYdxEfPS8pPApNb6deA2A5xHRGS5UqrhApQE584Cp4Au8Aul1KeTk5Ozw57Ebrc7BRxqtVqHRGQbsE5EvgGsA+a7vBI58b0HXAT2ichPgSPA1KBVzkgAJjW5Mwljsj+5W4CNwCLLSO15EdlrVM7hQRl4FR2BS8AurfUuYJmIPGzsnTuTKquAIaZE5JCxufb5UqdXLWBS9s40sK/Vau0znscm4D7DXVlieR+wHzgIXBqlicwZ31ng77XW/wjcDGwG/idj956IHDMgeX/YdslVAZgMzrwAvNlqtd4i+z0/F4HHRnUiLeydE1rrEzmxr5eMtJ0ZZSYAUGE5RSAXaoQpCBQAEygAJlAATKAAmEABMIECBcAECoAJFAATKAAmUABMoACYQIECYAIFwAQKgAkUABMoACbQ9Ur/OwDPb/OYDgsfJAAAAABJRU5ErkJggg==);background-size:80px 80px;background-repeat:no-repeat}.mirador-container .items-listing h3,.mirador-container .items-listing h4{margin:0;font-weight:400;color:rgba(0,0,0,.7)}.mirador-container .items-listing h3{color:rgba(0,0,0,.8);margin-top:2px;font-size:1em}.mirador-container .manifest-title h3{line-height:1.2em;height:3.6em;position:relative;overflow:hidden}.mirador-container .manifest-title h3:after{content:"";text-align:right;position:absolute;bottom:0;right:0;width:20%;height:1.2em}.mirador-container .item-info{position:absolute;bottom:0;display:table;width:100%}.mirador-container .item-info-row{display:table-row}.mirador-container .canvas-count,.mirador-container .repo-label{display:table-cell;white-space:nowrap;font-size:.85em;vertical-align:bottom;color:gray}.mirador-container .canvas-count{text-align:right}.mirador-container .preview-images,.mirador-container .repo-image,.mirador-container .select-metadata{float:left;margin-right:15px;height:80px}.mirador-container .preview-thumb{display:inline-flex;position:absolute}.mirador-container .preview-images{margin-right:0}.mirador-container .preview-image{background-color:gray;box-shadow:0 0 5px rgba(0,0,0,.7);float:left;margin-right:15px;min-height:25px;min-width:25px}.mirador-container .preview-image:hover{box-shadow:0 0 5px #00bfff;transform:scale(1.1);transition:all .6 ease-out}.mirador-container .remaining{line-height:80px;opacity:.5;text-align:center;box-sizing:border-box;vertical-align:middle;width:20px}.mirador-container #load-controls{margin-top:20px}.mirador-container #load-controls:after{content:"";display:table;clear:both}.mirador-container #manifest-search-form{float:left}.mirador-container #manifest-search-form label{margin-right:6px}.mirador-container #url-load-form{float:right}.mirador-container #url-load-form input[type=text]{width:250px;margin:0 5px}.mirador-container #load-controls input[type=submit]{height:29px}.mirador-container #manifest-search i{position:absolute;left:0;color:#000}.mirador-container #manifest-search-form input:focus,.mirador-container #url-load-form input:focus,.mirador-container #url-load-form input[type=submit]:hover{outline:0;border-color:#00bfff}.mirador-container #manifest-search i{width:25px;height:25px;color:red;border:1px solid red}.mirador-container .select-results{height:100%;overflow-y:scroll;margin-top:10px;border-top:1px solid gray}.mirador-container #workspace-select-menu{position:absolute;height:100%;width:100%;background-color:rgba(255,255,255,.94);display:none;overflow:hidden;z-index:6}.mirador-container #workspace-select-menu{background-color:#333;text-align:center;padding:20%;padding-top:0;box-sizing:border-box}.mirador-container #workspace-select-menu h1{color:#d3d3d3;padding-bottom:3%;font-weight:400}.mirador-container #workspace-select-menu h2,.mirador-container #workspace-select-menu h3{color:#d3d3d3}.mirador-container .select-grid{width:60%;min-width:300px;position:relative;margin:auto}.mirador-container .grid-row{content:"";display:table;clear:both;margin:0 auto}.mirador-container .grid-item{height:50px;width:50px;float:left;padding:4px;display:block}.mirador-container .grid-item .grid-icon{background:gray;height:50px;width:50px;border-radius:7px;display:block;transition:all .2s ease-out;margin:auto}.mirador-container .grid-item.hovered .grid-icon{background:#00bfff;box-shadow:0 0 10px #000;transform:scale(1.1) translateY(-10px) translateX(-5px);transition:all .2s ease-out}.mirador-container .grid-text{display:none}.mirador-container .sidePanel{position:absolute;width:280px;left:0;bottom:0;top:0;background-color:#efefef;border-right:1px solid #d3d3d3;box-sizing:border-box;overflow:hidden;transition:all .3s ease;padding:10px;opacity:1;transition:all .2s ease-out;transform:translateX(0)}.mirador-container .sidePanel .tabGroup{list-style-type:none;margin:0;padding:0}.mirador-container .sidePanel .tab{padding:8px;margin-right:2px;display:inline-block;cursor:pointer;background:#ddd;border-width:1px 1px 0 1px;border-color:#b1b1b1;border-style:solid;color:#666;font-size:.9em}.mirador-container .sidePanel .tab:not(.selected):hover{background:#d3d3d3;color:#333}.mirador-container .sidePanel .tab.selected{font-weight:700;color:#333;background:#efefef;border-top-width:1px;border-top-style:solid;border-top-color:#00bfff}.mirador-container .sidePanel .annotationListItem{list-style-type:none;border-left:0;border-right:0;padding:10px 10px 0 10px}.mirador-container .sidePanel .annotationListItem:after{content:"";height:1px;background:linear-gradient(to right,rgba(0,0,0,0) 0,#939393 50%,rgba(0,0,0,0) 100%);display:block;margin-top:10px}.mirador-container .sidePanel .annotationListItem.focused{background-color:#ddd;border-left:3px solid #add8e6}.mirador-container .sidePanel .annotationListItem:hover{background-color:#ddd;border-left:3px solid #add8e6}.mirador-container .sidePanel .annotationListItem.selected{background-color:#ccc;border-left:3px solid #00bfff}.mirador-container .sidePanel a:hover{text-decoration:none}.mirador-container .sidePanel h2{font-size:1em}.mirador-container .sidePanel h3{font-size:.9em}.mirador-container .sidePanel h4{font-size:.8em}.mirador-container .sidePanel h1,.mirador-container .sidePanel h2,.mirador-container .sidePanel h3,.mirador-container .sidePanel h4{margin:0;padding:0;font-weight:400}.mirador-container .sidePanel.minimized{transition:all .2s ease-out;transform:translateX(-280px);opacity:0;border:none}.mirador-container .tabContentArea{position:relative;width:270px;height:100%;float:left;background-color:#efefef;border-right:1px solid #d3d3d3;box-sizing:border-box;overflow:hidden;transition:all .3s ease;margin-top:8px}.mirador-container .annotationsPanel ul{padding:0;margin:0}.mirador-container .toc{margin:0;overflow-y:scroll;width:270px;padding:0;position:absolute;box-sizing:border-box;left:0;top:0;bottom:0;list-style-type:none;margin-bottom:30px}.mirador-container .toc a.toc-link{color:#000;padding:8px;padding-left:8px;display:block}.mirador-container .toc a.toc-link:hover{cursor:pointer;background-color:#ddd;display:block;overflow:hidden}.mirador-container .toc ul{margin:0;padding:0;box-sizing:border-box;list-style-type:none;width:100%}.mirador-container .toc li{cursor:pointer;box-sizing:border-box;display:block;position:relative;margin-left:8px;margin-bottom:5px;border-left:4px solid #efefef}.mirador-container .toc li.selected{cursor:pointer;overflow:hidden;border-left:4px solid #00bfff;transition:all .2s ease-out}.mirador-container .toc>li{margin-left:0}.mirador-container .toc-link i{color:rgba(0,0,0,.4);margin-right:.4em;transition:all .2s linear}.mirador-container .toc-link i:hover{color:#000}.mirador-container .toc-caret{padding:.4em;margin:-.4em}.mirador-container .toc li.has-child i.star{display:none}.mirador-container .toc li.leaf-item i.toc-caret{display:none}.mirador-container .toc li.leaf-item i.star{display:inline-block}.mirador-container .toc li.selected>h2 .toc-link,.mirador-container .toc li.selected>h3 .toc-link,.mirador-container .toc li.selected>h4 .toc-link,.mirador-container .toc li.selected>h5 .toc-link{font-weight:700}.mirador-container .toc li.hovered>h2 .toc-link .star,.mirador-container .toc li.hovered>h3 .toc-link .star,.mirador-container .toc li.hovered>h4 .toc-link .star,.mirador-container .toc li.hovered>h5 .toc-link .star,.mirador-container .toc li.selected>h2 .toc-link .star,.mirador-container .toc li.selected>h3 .toc-link .star,.mirador-container .toc li.selected>h4 .toc-link .star,.mirador-container .toc li.selected>h5 .toc-link .star{color:#000}.mirador-container .toc li.open>h2 .toc-link .toc-caret,.mirador-container .toc li.open>h3 .toc-link .toc-caret,.mirador-container .toc li.open>h4 .toc-link .toc-caret,.mirador-container .toc li.open>h5 .toc-link .toc-caret{transition:all .2s linear;transform:rotate(90deg);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg)}.mirador-container .toc li.hovered{border-left:4px solid #00bfff}.mirador-container .toc li:hover{border-left:4px solid #99e5ff}.mirador-container .toc-link:hover .star{color:#000}.mirador-container .annotationListPanel{background-color:#f0f0f0;width:200px;height:100%;position:absolute;right:0;top:0;margin:0;padding:0;z-index:2;box-shadow:0 0 5px rgba(0,0,0,.3);border-left:1px solid gray}.mirador-container .annotationPanelHeader{padding:0 10px}.mirador-container .annotationListPanel ul{position:absolute;bottom:0;top:80px;border-top:1px solid #fff;list-style:none;overflow:scroll;overflow-x:hidden;margin-bottom:0;padding:0;width:100%}.mirador-container .annotationListPanel ul li{font-size:80%;margin:0;padding:10px;border-bottom:1px solid #fff;box-sizing:border-box}.mirador-container .annotationListPanel ul li:hover{background-color:#d3d3d3;cursor:pointer;border-left:2px solid #ff4500;padding-left:8px}.mirador-container .annotationListPanel ul li.selected{color:#fff;background-color:gray;cursor:pointer;border-left:3px solid #ff4500;padding-left:7px}.mirador-container .annotationListPanel ul li.hovered{background-color:#d3d3d3;cursor:pointer;border-left:2px solid #ff4500;padding-left:8px}.mirador-container .annotationListPanel ul li p{margin:0}.mirador-container .annotationListPanel ul li p:hover{margin:0;cursor:pointer}.mirador-container .annotationListPanel ul li a{display:block;position:absolute;top:0;bottom:0;left:0;right:0}.mirador-container .annotationListPanel .resizeGrip{position:absolute;left:-7px;bottom:0;top:0;width:12px;z-index:3;background:0 0;display:block;cursor:ew-resize}.mirador-container .annotation,.mirador-container .osd-select-rectangle{border:2px solid #00bfff;box-shadow:0 0 5px #fff;box-sizing:border-box}.mirador-container .annotation.selected{border:3px solid #ff4500;box-shadow:0 0 8px rgba(0,0,0,.7)}.mirador-container .annotation.hovered{border:3px solid #ff4500;opacity:.5;box-shadow:0 0 15px #000}.mirador-container .annotationDetails{box-sizing:border-box;position:absolute;bottom:0;left:0;width:100%;padding:inherit;padding-top:25px;color:#fff;overflow:hidden;height:20%;z-index:2;background:-moz-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.77) 13%,rgba(0,0,0,.77) 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0,rgba(0,0,0,0)),color-stop(13%,rgba(0,0,0,.77)),color-stop(100%,rgba(0,0,0,.77)));background:-webkit-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.77) 13%,rgba(0,0,0,.77) 100%);background:-o-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.77) 13%,rgba(0,0,0,.77) 100%);background:-ms-linear-gradient(top,rgba(0,0,0,0) 0,rgba(0,0,0,.77) 13%,rgba(0,0,0,.77) 100%);background:linear-gradient(to bottom,rgba(0,0,0,0) 0,rgba(0,0,0,.77) 13%,rgba(0,0,0,.77) 100%)}.mirador-container .annotationDetailToggle{float:right;margin:32px;margin-top:0;cursor:pointer}.mirador-container .osd-annotation-overlay{display:none}.mirador-container .displayBottomPanelButton{box-sizing:border-box;position:absolute;bottom:0;left:0;width:100%;padding:inherit;color:#fff;height:75px;z-index:2}.mirador-container .annotationDetails p{width:80%;font-size:1.3em;font-weight:700;display:block;margin:0 auto}.mirador-container #bookmark-panel{position:absolute;height:20%;width:30%;background-color:rgba(255,255,255,.94);display:none;overflow:hidden;z-index:6;right:0;top:0;padding:10px}.mirador-container #bookmark-panel span{width:100%;padding-left:2%}.mirador-container #bookmark-panel input{width:80%;margin-right:3px}.mirador-container #bookmark-panel h3{text-align:center}.mirador-container .mirador-viewer .sub-title{border-bottom:1px solid #b1b1b1;color:#333;font-weight:700;margin:10px 20px 5px 20px;padding:0 5px 5px 0;font-size:120%;text-transform:uppercase}.mirador-container .mirador-viewer .metadata-listing{width:100%;margin:0;padding:0 20px 10px 20px;box-sizing:border-box}.mirador-container .mirador-viewer .metadata-item{padding:10px 0 5px 0}.mirador-container .mirador-viewer .metadata-label,.mirador-container .mirador-viewer .metadata-value{line-height:1.5}.mirador-container .mirador-viewer .metadata-label{color:#666;font-style:italic;text-transform:uppercase}.mirador-container .mirador-viewer .metadata-value{vertical-align:bottom}.mirador-container .mirador-viewer .metadata-listing a{border-bottom:1px dotted #005ebd}.mirador-container .mirador-viewer .metadata-listing a:hover{border-bottom:1px dotted #ddd}.mirador-container .mirador-metadata-view-nav-toolbar{float:right;margin-right:5px}.mirador-container .metadata-logo{max-height:120px;max-width:100%}.mirador-container .bottomPanel{background-color:rgba(0,0,0,.7);position:absolute;bottom:0;left:0;right:0;height:130px;z-index:4;overflow:hidden;display:none;transition:transform .3s ease}.mirador-container .bottomPanel.minimized{transform:translateY(130px)}.mirador-container .panel-thumbnail-view{position:absolute;height:100%;width:100%;overflow-x:scroll;overflow-y:hidden}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs{clear:both;list-style:none;padding:0;white-space:nowrap;margin-top:10px;margin-bottom:4px}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li{box-sizing:border-box;padding:0 10px 0 10px;display:inline-block;margin-bottom:11px}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li.highlight{padding-left:8px;padding-right:8px}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img{background-color:gray;min-height:25px;min-width:25px;margin:0 auto;display:block;box-sizing:border-box}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img.thumbnail-image{background-color:gray;box-shadow:0 0 5px rgba(0,0,0,.6);float:left;margin-right:15px}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img.thumbnail-image.highlight{border:2px solid #00bfff}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li img:hover{border:2px solid rgba(0,191,255,.7);transform:scale(1.1);cursor:pointer}.mirador-container .panel-thumbnail-view ul.panel-listing-thumbs li .thumb-label{clear:both;color:#999;font-size:12px;margin:0 auto;max-width:75px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-align:center}.mirador-container .layersPanel h3{margin:10px 0}.layersPanel{position:absolute;width:285px;left:0;right:0;top:0;bottom:0;overflow-y:scroll}.layersPanel .layers-listing{padding:0;list-style-type:none;margin-top:0}.layersPanel .layers-list-item{zoom:1;border-top:1px solid #b1b1b1;padding:10px 10px 10px 0;margin-right:20px}.layersPanel .layers-list-item:after,.layersPanel .layers-list-item:before{content:"";display:table}.layersPanel .layers-list-item:after{clear:both}.layersPanel .layers-list-item>h4{margin-bottom:5px}.layersPanel .layers-list-item .thumb-container{position:relative;float:left;width:60px;height:60px;margin-right:10px}.layersPanel .layers-list-item .thumb-container img{position:relative;margin:0 auto;max-height:60px;max-width:60px;display:block;opacity:0;border:1px solid gray;box-shadow:inset 0 0 12px gray;top:50%;transform:translateY(-50%)}.layersPanel .layers-list-item .thumb-container img.loaded{transition:all .2s ease-out;opacity:1}.layersPanel .layers-list-item .thumb-container .failed,.layersPanel .layers-list-item .thumb-container .spinner,.layersPanel .layers-list-item .thumb-container .thumb-failed{position:absolute;display:inline-block;width:100%;margin:0 auto;top:50%;transform:translateY(-50%);opacity:0;transition:all .2s ease-out;color:#666}.layersPanel .layers-list-item .thumb-container.awaiting-thumbnail .spinner{opacity:1}.layersPanel .layers-list-item.requested .spinner{opacity:1;transition:all .2s ease-out}.layersPanel .layers-list-item.requested .thumb-container img{transition:all .2s ease-out;opacity:.5}.layersPanel .layers-list-item.failed .failed{opacity:1;transition:all .2s ease-out}.layersPanel .layers-list-item.failed .thumb-container img{transition:all .2s ease-out;opacity:.5}.layersPanel .layers-list-item.failed .thumb-failed{opacity:0}.layersPanel .layers-list-item.failed .thumb-container.awaiting-thumbnail .spinner{opacity:0;transition:all .2s ease-out}.layersPanel .layers-list-item .visibility-toggle{margin-bottom:10px}.layersPanel .disabled-overlay{display:none}.layersPanel.inactive>:not(.disabled-overlay){display:none}.layersPanel.inactive .disabled-overlay{padding:10px;display:block;box-sizing:border-box;color:#696969}.mirador-container .search-results{padding:0 5px 0 0;margin:0;position:absolute;height:100%}.mirador-container .search-results select{margin:5px 0 10px 0}.mirador-container .search-results-list{position:relative;height:100%}.mirador-container .search-results-list .search-results-messages{border-top:1px solid #b1b1b1;padding-top:10px;margin-top:10px}.mirador-container .search-results-list .search-results-count{font-size:.85em}.mirador-container .search-results-list .search-results-container{overflow-y:scroll;position:absolute;height:70%}.mirador-container .search-results-list .result-wrapper{margin-bottom:5px}.mirador-container .search-results-list .result-wrapper .result-paragraph .highlight{background-color:#ff0}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(../fonts/MaterialIcons-Regular.eot);src:local('Material Icons'),local('MaterialIcons-Regular'),url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),url(../fonts/MaterialIcons-Regular.woff) format('woff'),url(../fonts/MaterialIcons-Regular.ttf) format('truetype')}.material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;display:inline-block;width:1em;height:1em;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale;font-feature-settings:'liga'} \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/FontAwesome.otf b/iiif-5-day-workshop/day-three/mirador/fonts/FontAwesome.otf deleted file mode 100755 index 401ec0f3..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/FontAwesome.otf and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.eot b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.eot deleted file mode 100755 index 70508eba..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.eot and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ijmap b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ijmap deleted file mode 100755 index d9f1d259..00000000 --- a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ijmap +++ /dev/null @@ -1 +0,0 @@ -{"icons":{"e84d":{"name":"3d Rotation"},"eb3b":{"name":"Ac Unit"},"e190":{"name":"Access Alarm"},"e191":{"name":"Access Alarms"},"e192":{"name":"Access Time"},"e84e":{"name":"Accessibility"},"e914":{"name":"Accessible"},"e84f":{"name":"Account Balance"},"e850":{"name":"Account Balance Wallet"},"e851":{"name":"Account Box"},"e853":{"name":"Account Circle"},"e60e":{"name":"Adb"},"e145":{"name":"Add"},"e439":{"name":"Add A Photo"},"e193":{"name":"Add Alarm"},"e003":{"name":"Add Alert"},"e146":{"name":"Add Box"},"e147":{"name":"Add Circle"},"e148":{"name":"Add Circle Outline"},"e567":{"name":"Add Location"},"e854":{"name":"Add Shopping Cart"},"e39d":{"name":"Add To Photos"},"e05c":{"name":"Add To Queue"},"e39e":{"name":"Adjust"},"e630":{"name":"Airline Seat Flat"},"e631":{"name":"Airline Seat Flat Angled"},"e632":{"name":"Airline Seat Individual Suite"},"e633":{"name":"Airline Seat Legroom Extra"},"e634":{"name":"Airline Seat Legroom Normal"},"e635":{"name":"Airline Seat Legroom Reduced"},"e636":{"name":"Airline Seat Recline Extra"},"e637":{"name":"Airline Seat Recline Normal"},"e195":{"name":"Airplanemode Active"},"e194":{"name":"Airplanemode Inactive"},"e055":{"name":"Airplay"},"eb3c":{"name":"Airport Shuttle"},"e855":{"name":"Alarm"},"e856":{"name":"Alarm Add"},"e857":{"name":"Alarm Off"},"e858":{"name":"Alarm On"},"e019":{"name":"Album"},"eb3d":{"name":"All Inclusive"},"e90b":{"name":"All Out"},"e859":{"name":"Android"},"e85a":{"name":"Announcement"},"e5c3":{"name":"Apps"},"e149":{"name":"Archive"},"e5c4":{"name":"Arrow Back"},"e5db":{"name":"Arrow Downward"},"e5c5":{"name":"Arrow Drop Down"},"e5c6":{"name":"Arrow Drop Down Circle"},"e5c7":{"name":"Arrow Drop Up"},"e5c8":{"name":"Arrow Forward"},"e5d8":{"name":"Arrow Upward"},"e060":{"name":"Art Track"},"e85b":{"name":"Aspect Ratio"},"e85c":{"name":"Assessment"},"e85d":{"name":"Assignment"},"e85e":{"name":"Assignment Ind"},"e85f":{"name":"Assignment Late"},"e860":{"name":"Assignment Return"},"e861":{"name":"Assignment Returned"},"e862":{"name":"Assignment Turned In"},"e39f":{"name":"Assistant"},"e3a0":{"name":"Assistant Photo"},"e226":{"name":"Attach File"},"e227":{"name":"Attach Money"},"e2bc":{"name":"Attachment"},"e3a1":{"name":"Audiotrack"},"e863":{"name":"Autorenew"},"e01b":{"name":"Av Timer"},"e14a":{"name":"Backspace"},"e864":{"name":"Backup"},"e19c":{"name":"Battery Alert"},"e1a3":{"name":"Battery Charging Full"},"e1a4":{"name":"Battery Full"},"e1a5":{"name":"Battery Std"},"e1a6":{"name":"Battery Unknown"},"eb3e":{"name":"Beach Access"},"e52d":{"name":"Beenhere"},"e14b":{"name":"Block"},"e1a7":{"name":"Bluetooth"},"e60f":{"name":"Bluetooth Audio"},"e1a8":{"name":"Bluetooth Connected"},"e1a9":{"name":"Bluetooth Disabled"},"e1aa":{"name":"Bluetooth Searching"},"e3a2":{"name":"Blur Circular"},"e3a3":{"name":"Blur Linear"},"e3a4":{"name":"Blur Off"},"e3a5":{"name":"Blur On"},"e865":{"name":"Book"},"e866":{"name":"Bookmark"},"e867":{"name":"Bookmark Border"},"e228":{"name":"Border All"},"e229":{"name":"Border Bottom"},"e22a":{"name":"Border Clear"},"e22b":{"name":"Border Color"},"e22c":{"name":"Border Horizontal"},"e22d":{"name":"Border Inner"},"e22e":{"name":"Border Left"},"e22f":{"name":"Border Outer"},"e230":{"name":"Border Right"},"e231":{"name":"Border Style"},"e232":{"name":"Border Top"},"e233":{"name":"Border Vertical"},"e06b":{"name":"Branding Watermark"},"e3a6":{"name":"Brightness 1"},"e3a7":{"name":"Brightness 2"},"e3a8":{"name":"Brightness 3"},"e3a9":{"name":"Brightness 4"},"e3aa":{"name":"Brightness 5"},"e3ab":{"name":"Brightness 6"},"e3ac":{"name":"Brightness 7"},"e1ab":{"name":"Brightness Auto"},"e1ac":{"name":"Brightness High"},"e1ad":{"name":"Brightness Low"},"e1ae":{"name":"Brightness Medium"},"e3ad":{"name":"Broken Image"},"e3ae":{"name":"Brush"},"e6dd":{"name":"Bubble Chart"},"e868":{"name":"Bug Report"},"e869":{"name":"Build"},"e43c":{"name":"Burst Mode"},"e0af":{"name":"Business"},"eb3f":{"name":"Business Center"},"e86a":{"name":"Cached"},"e7e9":{"name":"Cake"},"e0b0":{"name":"Call"},"e0b1":{"name":"Call End"},"e0b2":{"name":"Call Made"},"e0b3":{"name":"Call Merge"},"e0b4":{"name":"Call Missed"},"e0e4":{"name":"Call Missed Outgoing"},"e0b5":{"name":"Call Received"},"e0b6":{"name":"Call Split"},"e06c":{"name":"Call To Action"},"e3af":{"name":"Camera"},"e3b0":{"name":"Camera Alt"},"e8fc":{"name":"Camera Enhance"},"e3b1":{"name":"Camera Front"},"e3b2":{"name":"Camera Rear"},"e3b3":{"name":"Camera Roll"},"e5c9":{"name":"Cancel"},"e8f6":{"name":"Card Giftcard"},"e8f7":{"name":"Card Membership"},"e8f8":{"name":"Card Travel"},"eb40":{"name":"Casino"},"e307":{"name":"Cast"},"e308":{"name":"Cast Connected"},"e3b4":{"name":"Center Focus Strong"},"e3b5":{"name":"Center Focus Weak"},"e86b":{"name":"Change History"},"e0b7":{"name":"Chat"},"e0ca":{"name":"Chat Bubble"},"e0cb":{"name":"Chat Bubble Outline"},"e5ca":{"name":"Check"},"e834":{"name":"Check Box"},"e835":{"name":"Check Box Outline Blank"},"e86c":{"name":"Check Circle"},"e5cb":{"name":"Chevron Left"},"e5cc":{"name":"Chevron Right"},"eb41":{"name":"Child Care"},"eb42":{"name":"Child Friendly"},"e86d":{"name":"Chrome Reader Mode"},"e86e":{"name":"Class"},"e14c":{"name":"Clear"},"e0b8":{"name":"Clear All"},"e5cd":{"name":"Close"},"e01c":{"name":"Closed Caption"},"e2bd":{"name":"Cloud"},"e2be":{"name":"Cloud Circle"},"e2bf":{"name":"Cloud Done"},"e2c0":{"name":"Cloud Download"},"e2c1":{"name":"Cloud Off"},"e2c2":{"name":"Cloud Queue"},"e2c3":{"name":"Cloud Upload"},"e86f":{"name":"Code"},"e3b6":{"name":"Collections"},"e431":{"name":"Collections Bookmark"},"e3b7":{"name":"Color Lens"},"e3b8":{"name":"Colorize"},"e0b9":{"name":"Comment"},"e3b9":{"name":"Compare"},"e915":{"name":"Compare Arrows"},"e30a":{"name":"Computer"},"e638":{"name":"Confirmation Number"},"e0d0":{"name":"Contact Mail"},"e0cf":{"name":"Contact Phone"},"e0ba":{"name":"Contacts"},"e14d":{"name":"Content Copy"},"e14e":{"name":"Content Cut"},"e14f":{"name":"Content Paste"},"e3ba":{"name":"Control Point"},"e3bb":{"name":"Control Point Duplicate"},"e90c":{"name":"Copyright"},"e150":{"name":"Create"},"e2cc":{"name":"Create New Folder"},"e870":{"name":"Credit Card"},"e3be":{"name":"Crop"},"e3bc":{"name":"Crop 16 9"},"e3bd":{"name":"Crop 3 2"},"e3bf":{"name":"Crop 5 4"},"e3c0":{"name":"Crop 7 5"},"e3c1":{"name":"Crop Din"},"e3c2":{"name":"Crop Free"},"e3c3":{"name":"Crop Landscape"},"e3c4":{"name":"Crop Original"},"e3c5":{"name":"Crop Portrait"},"e437":{"name":"Crop Rotate"},"e3c6":{"name":"Crop Square"},"e871":{"name":"Dashboard"},"e1af":{"name":"Data Usage"},"e916":{"name":"Date Range"},"e3c7":{"name":"Dehaze"},"e872":{"name":"Delete"},"e92b":{"name":"Delete Forever"},"e16c":{"name":"Delete Sweep"},"e873":{"name":"Description"},"e30b":{"name":"Desktop Mac"},"e30c":{"name":"Desktop Windows"},"e3c8":{"name":"Details"},"e30d":{"name":"Developer Board"},"e1b0":{"name":"Developer Mode"},"e335":{"name":"Device Hub"},"e1b1":{"name":"Devices"},"e337":{"name":"Devices Other"},"e0bb":{"name":"Dialer Sip"},"e0bc":{"name":"Dialpad"},"e52e":{"name":"Directions"},"e52f":{"name":"Directions Bike"},"e532":{"name":"Directions Boat"},"e530":{"name":"Directions Bus"},"e531":{"name":"Directions Car"},"e534":{"name":"Directions Railway"},"e566":{"name":"Directions Run"},"e533":{"name":"Directions Subway"},"e535":{"name":"Directions Transit"},"e536":{"name":"Directions Walk"},"e610":{"name":"Disc Full"},"e875":{"name":"Dns"},"e612":{"name":"Do Not Disturb"},"e611":{"name":"Do Not Disturb Alt"},"e643":{"name":"Do Not Disturb Off"},"e644":{"name":"Do Not Disturb On"},"e30e":{"name":"Dock"},"e7ee":{"name":"Domain"},"e876":{"name":"Done"},"e877":{"name":"Done All"},"e917":{"name":"Donut Large"},"e918":{"name":"Donut Small"},"e151":{"name":"Drafts"},"e25d":{"name":"Drag Handle"},"e613":{"name":"Drive Eta"},"e1b2":{"name":"Dvr"},"e3c9":{"name":"Edit"},"e568":{"name":"Edit Location"},"e8fb":{"name":"Eject"},"e0be":{"name":"Email"},"e63f":{"name":"Enhanced Encryption"},"e01d":{"name":"Equalizer"},"e000":{"name":"Error"},"e001":{"name":"Error Outline"},"e926":{"name":"Euro Symbol"},"e56d":{"name":"Ev Station"},"e878":{"name":"Event"},"e614":{"name":"Event Available"},"e615":{"name":"Event Busy"},"e616":{"name":"Event Note"},"e903":{"name":"Event Seat"},"e879":{"name":"Exit To App"},"e5ce":{"name":"Expand Less"},"e5cf":{"name":"Expand More"},"e01e":{"name":"Explicit"},"e87a":{"name":"Explore"},"e3ca":{"name":"Exposure"},"e3cb":{"name":"Exposure Neg 1"},"e3cc":{"name":"Exposure Neg 2"},"e3cd":{"name":"Exposure Plus 1"},"e3ce":{"name":"Exposure Plus 2"},"e3cf":{"name":"Exposure Zero"},"e87b":{"name":"Extension"},"e87c":{"name":"Face"},"e01f":{"name":"Fast Forward"},"e020":{"name":"Fast Rewind"},"e87d":{"name":"Favorite"},"e87e":{"name":"Favorite Border"},"e06d":{"name":"Featured Play List"},"e06e":{"name":"Featured Video"},"e87f":{"name":"Feedback"},"e05d":{"name":"Fiber Dvr"},"e061":{"name":"Fiber Manual Record"},"e05e":{"name":"Fiber New"},"e06a":{"name":"Fiber Pin"},"e062":{"name":"Fiber Smart Record"},"e2c4":{"name":"File Download"},"e2c6":{"name":"File Upload"},"e3d3":{"name":"Filter"},"e3d0":{"name":"Filter 1"},"e3d1":{"name":"Filter 2"},"e3d2":{"name":"Filter 3"},"e3d4":{"name":"Filter 4"},"e3d5":{"name":"Filter 5"},"e3d6":{"name":"Filter 6"},"e3d7":{"name":"Filter 7"},"e3d8":{"name":"Filter 8"},"e3d9":{"name":"Filter 9"},"e3da":{"name":"Filter 9 Plus"},"e3db":{"name":"Filter B And W"},"e3dc":{"name":"Filter Center Focus"},"e3dd":{"name":"Filter Drama"},"e3de":{"name":"Filter Frames"},"e3df":{"name":"Filter Hdr"},"e152":{"name":"Filter List"},"e3e0":{"name":"Filter None"},"e3e2":{"name":"Filter Tilt Shift"},"e3e3":{"name":"Filter Vintage"},"e880":{"name":"Find In Page"},"e881":{"name":"Find Replace"},"e90d":{"name":"Fingerprint"},"e5dc":{"name":"First Page"},"eb43":{"name":"Fitness Center"},"e153":{"name":"Flag"},"e3e4":{"name":"Flare"},"e3e5":{"name":"Flash Auto"},"e3e6":{"name":"Flash Off"},"e3e7":{"name":"Flash On"},"e539":{"name":"Flight"},"e904":{"name":"Flight Land"},"e905":{"name":"Flight Takeoff"},"e3e8":{"name":"Flip"},"e882":{"name":"Flip To Back"},"e883":{"name":"Flip To Front"},"e2c7":{"name":"Folder"},"e2c8":{"name":"Folder Open"},"e2c9":{"name":"Folder Shared"},"e617":{"name":"Folder Special"},"e167":{"name":"Font Download"},"e234":{"name":"Format Align Center"},"e235":{"name":"Format Align Justify"},"e236":{"name":"Format Align Left"},"e237":{"name":"Format Align Right"},"e238":{"name":"Format Bold"},"e239":{"name":"Format Clear"},"e23a":{"name":"Format Color Fill"},"e23b":{"name":"Format Color Reset"},"e23c":{"name":"Format Color Text"},"e23d":{"name":"Format Indent Decrease"},"e23e":{"name":"Format Indent Increase"},"e23f":{"name":"Format Italic"},"e240":{"name":"Format Line Spacing"},"e241":{"name":"Format List Bulleted"},"e242":{"name":"Format List Numbered"},"e243":{"name":"Format Paint"},"e244":{"name":"Format Quote"},"e25e":{"name":"Format Shapes"},"e245":{"name":"Format Size"},"e246":{"name":"Format Strikethrough"},"e247":{"name":"Format Textdirection L To R"},"e248":{"name":"Format Textdirection R To L"},"e249":{"name":"Format Underlined"},"e0bf":{"name":"Forum"},"e154":{"name":"Forward"},"e056":{"name":"Forward 10"},"e057":{"name":"Forward 30"},"e058":{"name":"Forward 5"},"eb44":{"name":"Free Breakfast"},"e5d0":{"name":"Fullscreen"},"e5d1":{"name":"Fullscreen Exit"},"e24a":{"name":"Functions"},"e927":{"name":"G Translate"},"e30f":{"name":"Gamepad"},"e021":{"name":"Games"},"e90e":{"name":"Gavel"},"e155":{"name":"Gesture"},"e884":{"name":"Get App"},"e908":{"name":"Gif"},"eb45":{"name":"Golf Course"},"e1b3":{"name":"Gps Fixed"},"e1b4":{"name":"Gps Not Fixed"},"e1b5":{"name":"Gps Off"},"e885":{"name":"Grade"},"e3e9":{"name":"Gradient"},"e3ea":{"name":"Grain"},"e1b8":{"name":"Graphic Eq"},"e3eb":{"name":"Grid Off"},"e3ec":{"name":"Grid On"},"e7ef":{"name":"Group"},"e7f0":{"name":"Group Add"},"e886":{"name":"Group Work"},"e052":{"name":"Hd"},"e3ed":{"name":"Hdr Off"},"e3ee":{"name":"Hdr On"},"e3f1":{"name":"Hdr Strong"},"e3f2":{"name":"Hdr Weak"},"e310":{"name":"Headset"},"e311":{"name":"Headset Mic"},"e3f3":{"name":"Healing"},"e023":{"name":"Hearing"},"e887":{"name":"Help"},"e8fd":{"name":"Help Outline"},"e024":{"name":"High Quality"},"e25f":{"name":"Highlight"},"e888":{"name":"Highlight Off"},"e889":{"name":"History"},"e88a":{"name":"Home"},"eb46":{"name":"Hot Tub"},"e53a":{"name":"Hotel"},"e88b":{"name":"Hourglass Empty"},"e88c":{"name":"Hourglass Full"},"e902":{"name":"Http"},"e88d":{"name":"Https"},"e3f4":{"name":"Image"},"e3f5":{"name":"Image Aspect Ratio"},"e0e0":{"name":"Import Contacts"},"e0c3":{"name":"Import Export"},"e912":{"name":"Important Devices"},"e156":{"name":"Inbox"},"e909":{"name":"Indeterminate Check Box"},"e88e":{"name":"Info"},"e88f":{"name":"Info Outline"},"e890":{"name":"Input"},"e24b":{"name":"Insert Chart"},"e24c":{"name":"Insert Comment"},"e24d":{"name":"Insert Drive File"},"e24e":{"name":"Insert Emoticon"},"e24f":{"name":"Insert Invitation"},"e250":{"name":"Insert Link"},"e251":{"name":"Insert Photo"},"e891":{"name":"Invert Colors"},"e0c4":{"name":"Invert Colors Off"},"e3f6":{"name":"Iso"},"e312":{"name":"Keyboard"},"e313":{"name":"Keyboard Arrow Down"},"e314":{"name":"Keyboard Arrow Left"},"e315":{"name":"Keyboard Arrow Right"},"e316":{"name":"Keyboard Arrow Up"},"e317":{"name":"Keyboard Backspace"},"e318":{"name":"Keyboard Capslock"},"e31a":{"name":"Keyboard Hide"},"e31b":{"name":"Keyboard Return"},"e31c":{"name":"Keyboard Tab"},"e31d":{"name":"Keyboard Voice"},"eb47":{"name":"Kitchen"},"e892":{"name":"Label"},"e893":{"name":"Label Outline"},"e3f7":{"name":"Landscape"},"e894":{"name":"Language"},"e31e":{"name":"Laptop"},"e31f":{"name":"Laptop Chromebook"},"e320":{"name":"Laptop Mac"},"e321":{"name":"Laptop Windows"},"e5dd":{"name":"Last Page"},"e895":{"name":"Launch"},"e53b":{"name":"Layers"},"e53c":{"name":"Layers Clear"},"e3f8":{"name":"Leak Add"},"e3f9":{"name":"Leak Remove"},"e3fa":{"name":"Lens"},"e02e":{"name":"Library Add"},"e02f":{"name":"Library Books"},"e030":{"name":"Library Music"},"e90f":{"name":"Lightbulb Outline"},"e919":{"name":"Line Style"},"e91a":{"name":"Line Weight"},"e260":{"name":"Linear Scale"},"e157":{"name":"Link"},"e438":{"name":"Linked Camera"},"e896":{"name":"List"},"e0c6":{"name":"Live Help"},"e639":{"name":"Live Tv"},"e53f":{"name":"Local Activity"},"e53d":{"name":"Local Airport"},"e53e":{"name":"Local Atm"},"e540":{"name":"Local Bar"},"e541":{"name":"Local Cafe"},"e542":{"name":"Local Car Wash"},"e543":{"name":"Local Convenience Store"},"e556":{"name":"Local Dining"},"e544":{"name":"Local Drink"},"e545":{"name":"Local Florist"},"e546":{"name":"Local Gas Station"},"e547":{"name":"Local Grocery Store"},"e548":{"name":"Local Hospital"},"e549":{"name":"Local Hotel"},"e54a":{"name":"Local Laundry Service"},"e54b":{"name":"Local Library"},"e54c":{"name":"Local Mall"},"e54d":{"name":"Local Movies"},"e54e":{"name":"Local Offer"},"e54f":{"name":"Local Parking"},"e550":{"name":"Local Pharmacy"},"e551":{"name":"Local Phone"},"e552":{"name":"Local Pizza"},"e553":{"name":"Local Play"},"e554":{"name":"Local Post Office"},"e555":{"name":"Local Printshop"},"e557":{"name":"Local See"},"e558":{"name":"Local Shipping"},"e559":{"name":"Local Taxi"},"e7f1":{"name":"Location City"},"e1b6":{"name":"Location Disabled"},"e0c7":{"name":"Location Off"},"e0c8":{"name":"Location On"},"e1b7":{"name":"Location Searching"},"e897":{"name":"Lock"},"e898":{"name":"Lock Open"},"e899":{"name":"Lock Outline"},"e3fc":{"name":"Looks"},"e3fb":{"name":"Looks 3"},"e3fd":{"name":"Looks 4"},"e3fe":{"name":"Looks 5"},"e3ff":{"name":"Looks 6"},"e400":{"name":"Looks One"},"e401":{"name":"Looks Two"},"e028":{"name":"Loop"},"e402":{"name":"Loupe"},"e16d":{"name":"Low Priority"},"e89a":{"name":"Loyalty"},"e158":{"name":"Mail"},"e0e1":{"name":"Mail Outline"},"e55b":{"name":"Map"},"e159":{"name":"Markunread"},"e89b":{"name":"Markunread Mailbox"},"e322":{"name":"Memory"},"e5d2":{"name":"Menu"},"e252":{"name":"Merge Type"},"e0c9":{"name":"Message"},"e029":{"name":"Mic"},"e02a":{"name":"Mic None"},"e02b":{"name":"Mic Off"},"e618":{"name":"Mms"},"e253":{"name":"Mode Comment"},"e254":{"name":"Mode Edit"},"e263":{"name":"Monetization On"},"e25c":{"name":"Money Off"},"e403":{"name":"Monochrome Photos"},"e7f2":{"name":"Mood"},"e7f3":{"name":"Mood Bad"},"e619":{"name":"More"},"e5d3":{"name":"More Horiz"},"e5d4":{"name":"More Vert"},"e91b":{"name":"Motorcycle"},"e323":{"name":"Mouse"},"e168":{"name":"Move To Inbox"},"e02c":{"name":"Movie"},"e404":{"name":"Movie Creation"},"e43a":{"name":"Movie Filter"},"e6df":{"name":"Multiline Chart"},"e405":{"name":"Music Note"},"e063":{"name":"Music Video"},"e55c":{"name":"My Location"},"e406":{"name":"Nature"},"e407":{"name":"Nature People"},"e408":{"name":"Navigate Before"},"e409":{"name":"Navigate Next"},"e55d":{"name":"Navigation"},"e569":{"name":"Near Me"},"e1b9":{"name":"Network Cell"},"e640":{"name":"Network Check"},"e61a":{"name":"Network Locked"},"e1ba":{"name":"Network Wifi"},"e031":{"name":"New Releases"},"e16a":{"name":"Next Week"},"e1bb":{"name":"Nfc"},"e641":{"name":"No Encryption"},"e0cc":{"name":"No Sim"},"e033":{"name":"Not Interested"},"e06f":{"name":"Note"},"e89c":{"name":"Note Add"},"e7f4":{"name":"Notifications"},"e7f7":{"name":"Notifications Active"},"e7f5":{"name":"Notifications None"},"e7f6":{"name":"Notifications Off"},"e7f8":{"name":"Notifications Paused"},"e90a":{"name":"Offline Pin"},"e63a":{"name":"Ondemand Video"},"e91c":{"name":"Opacity"},"e89d":{"name":"Open In Browser"},"e89e":{"name":"Open In New"},"e89f":{"name":"Open With"},"e7f9":{"name":"Pages"},"e8a0":{"name":"Pageview"},"e40a":{"name":"Palette"},"e925":{"name":"Pan Tool"},"e40b":{"name":"Panorama"},"e40c":{"name":"Panorama Fish Eye"},"e40d":{"name":"Panorama Horizontal"},"e40e":{"name":"Panorama Vertical"},"e40f":{"name":"Panorama Wide Angle"},"e7fa":{"name":"Party Mode"},"e034":{"name":"Pause"},"e035":{"name":"Pause Circle Filled"},"e036":{"name":"Pause Circle Outline"},"e8a1":{"name":"Payment"},"e7fb":{"name":"People"},"e7fc":{"name":"People Outline"},"e8a2":{"name":"Perm Camera Mic"},"e8a3":{"name":"Perm Contact Calendar"},"e8a4":{"name":"Perm Data Setting"},"e8a5":{"name":"Perm Device Information"},"e8a6":{"name":"Perm Identity"},"e8a7":{"name":"Perm Media"},"e8a8":{"name":"Perm Phone Msg"},"e8a9":{"name":"Perm Scan Wifi"},"e7fd":{"name":"Person"},"e7fe":{"name":"Person Add"},"e7ff":{"name":"Person Outline"},"e55a":{"name":"Person Pin"},"e56a":{"name":"Person Pin Circle"},"e63b":{"name":"Personal Video"},"e91d":{"name":"Pets"},"e0cd":{"name":"Phone"},"e324":{"name":"Phone Android"},"e61b":{"name":"Phone Bluetooth Speaker"},"e61c":{"name":"Phone Forwarded"},"e61d":{"name":"Phone In Talk"},"e325":{"name":"Phone Iphone"},"e61e":{"name":"Phone Locked"},"e61f":{"name":"Phone Missed"},"e620":{"name":"Phone Paused"},"e326":{"name":"Phonelink"},"e0db":{"name":"Phonelink Erase"},"e0dc":{"name":"Phonelink Lock"},"e327":{"name":"Phonelink Off"},"e0dd":{"name":"Phonelink Ring"},"e0de":{"name":"Phonelink Setup"},"e410":{"name":"Photo"},"e411":{"name":"Photo Album"},"e412":{"name":"Photo Camera"},"e43b":{"name":"Photo Filter"},"e413":{"name":"Photo Library"},"e432":{"name":"Photo Size Select Actual"},"e433":{"name":"Photo Size Select Large"},"e434":{"name":"Photo Size Select Small"},"e415":{"name":"Picture As Pdf"},"e8aa":{"name":"Picture In Picture"},"e911":{"name":"Picture In Picture Alt"},"e6c4":{"name":"Pie Chart"},"e6c5":{"name":"Pie Chart Outlined"},"e55e":{"name":"Pin Drop"},"e55f":{"name":"Place"},"e037":{"name":"Play Arrow"},"e038":{"name":"Play Circle Filled"},"e039":{"name":"Play Circle Outline"},"e906":{"name":"Play For Work"},"e03b":{"name":"Playlist Add"},"e065":{"name":"Playlist Add Check"},"e05f":{"name":"Playlist Play"},"e800":{"name":"Plus One"},"e801":{"name":"Poll"},"e8ab":{"name":"Polymer"},"eb48":{"name":"Pool"},"e0ce":{"name":"Portable Wifi Off"},"e416":{"name":"Portrait"},"e63c":{"name":"Power"},"e336":{"name":"Power Input"},"e8ac":{"name":"Power Settings New"},"e91e":{"name":"Pregnant Woman"},"e0df":{"name":"Present To All"},"e8ad":{"name":"Print"},"e645":{"name":"Priority High"},"e80b":{"name":"Public"},"e255":{"name":"Publish"},"e8ae":{"name":"Query Builder"},"e8af":{"name":"Question Answer"},"e03c":{"name":"Queue"},"e03d":{"name":"Queue Music"},"e066":{"name":"Queue Play Next"},"e03e":{"name":"Radio"},"e837":{"name":"Radio Button Checked"},"e836":{"name":"Radio Button Unchecked"},"e560":{"name":"Rate Review"},"e8b0":{"name":"Receipt"},"e03f":{"name":"Recent Actors"},"e91f":{"name":"Record Voice Over"},"e8b1":{"name":"Redeem"},"e15a":{"name":"Redo"},"e5d5":{"name":"Refresh"},"e15b":{"name":"Remove"},"e15c":{"name":"Remove Circle"},"e15d":{"name":"Remove Circle Outline"},"e067":{"name":"Remove From Queue"},"e417":{"name":"Remove Red Eye"},"e928":{"name":"Remove Shopping Cart"},"e8fe":{"name":"Reorder"},"e040":{"name":"Repeat"},"e041":{"name":"Repeat One"},"e042":{"name":"Replay"},"e059":{"name":"Replay 10"},"e05a":{"name":"Replay 30"},"e05b":{"name":"Replay 5"},"e15e":{"name":"Reply"},"e15f":{"name":"Reply All"},"e160":{"name":"Report"},"e8b2":{"name":"Report Problem"},"e56c":{"name":"Restaurant"},"e561":{"name":"Restaurant Menu"},"e8b3":{"name":"Restore"},"e929":{"name":"Restore Page"},"e0d1":{"name":"Ring Volume"},"e8b4":{"name":"Room"},"eb49":{"name":"Room Service"},"e418":{"name":"Rotate 90 Degrees Ccw"},"e419":{"name":"Rotate Left"},"e41a":{"name":"Rotate Right"},"e920":{"name":"Rounded Corner"},"e328":{"name":"Router"},"e921":{"name":"Rowing"},"e0e5":{"name":"Rss Feed"},"e642":{"name":"Rv Hookup"},"e562":{"name":"Satellite"},"e161":{"name":"Save"},"e329":{"name":"Scanner"},"e8b5":{"name":"Schedule"},"e80c":{"name":"School"},"e1be":{"name":"Screen Lock Landscape"},"e1bf":{"name":"Screen Lock Portrait"},"e1c0":{"name":"Screen Lock Rotation"},"e1c1":{"name":"Screen Rotation"},"e0e2":{"name":"Screen Share"},"e623":{"name":"Sd Card"},"e1c2":{"name":"Sd Storage"},"e8b6":{"name":"Search"},"e32a":{"name":"Security"},"e162":{"name":"Select All"},"e163":{"name":"Send"},"e811":{"name":"Sentiment Dissatisfied"},"e812":{"name":"Sentiment Neutral"},"e813":{"name":"Sentiment Satisfied"},"e814":{"name":"Sentiment Very Dissatisfied"},"e815":{"name":"Sentiment Very Satisfied"},"e8b8":{"name":"Settings"},"e8b9":{"name":"Settings Applications"},"e8ba":{"name":"Settings Backup Restore"},"e8bb":{"name":"Settings Bluetooth"},"e8bd":{"name":"Settings Brightness"},"e8bc":{"name":"Settings Cell"},"e8be":{"name":"Settings Ethernet"},"e8bf":{"name":"Settings Input Antenna"},"e8c0":{"name":"Settings Input Component"},"e8c1":{"name":"Settings Input Composite"},"e8c2":{"name":"Settings Input Hdmi"},"e8c3":{"name":"Settings Input Svideo"},"e8c4":{"name":"Settings Overscan"},"e8c5":{"name":"Settings Phone"},"e8c6":{"name":"Settings Power"},"e8c7":{"name":"Settings Remote"},"e1c3":{"name":"Settings System Daydream"},"e8c8":{"name":"Settings Voice"},"e80d":{"name":"Share"},"e8c9":{"name":"Shop"},"e8ca":{"name":"Shop Two"},"e8cb":{"name":"Shopping Basket"},"e8cc":{"name":"Shopping Cart"},"e261":{"name":"Short Text"},"e6e1":{"name":"Show Chart"},"e043":{"name":"Shuffle"},"e1c8":{"name":"Signal Cellular 4 Bar"},"e1cd":{"name":"Signal Cellular Connected No Internet 4 Bar"},"e1ce":{"name":"Signal Cellular No Sim"},"e1cf":{"name":"Signal Cellular Null"},"e1d0":{"name":"Signal Cellular Off"},"e1d8":{"name":"Signal Wifi 4 Bar"},"e1d9":{"name":"Signal Wifi 4 Bar Lock"},"e1da":{"name":"Signal Wifi Off"},"e32b":{"name":"Sim Card"},"e624":{"name":"Sim Card Alert"},"e044":{"name":"Skip Next"},"e045":{"name":"Skip Previous"},"e41b":{"name":"Slideshow"},"e068":{"name":"Slow Motion Video"},"e32c":{"name":"Smartphone"},"eb4a":{"name":"Smoke Free"},"eb4b":{"name":"Smoking Rooms"},"e625":{"name":"Sms"},"e626":{"name":"Sms Failed"},"e046":{"name":"Snooze"},"e164":{"name":"Sort"},"e053":{"name":"Sort By Alpha"},"eb4c":{"name":"Spa"},"e256":{"name":"Space Bar"},"e32d":{"name":"Speaker"},"e32e":{"name":"Speaker Group"},"e8cd":{"name":"Speaker Notes"},"e92a":{"name":"Speaker Notes Off"},"e0d2":{"name":"Speaker Phone"},"e8ce":{"name":"Spellcheck"},"e838":{"name":"Star"},"e83a":{"name":"Star Border"},"e839":{"name":"Star Half"},"e8d0":{"name":"Stars"},"e0d3":{"name":"Stay Current Landscape"},"e0d4":{"name":"Stay Current Portrait"},"e0d5":{"name":"Stay Primary Landscape"},"e0d6":{"name":"Stay Primary Portrait"},"e047":{"name":"Stop"},"e0e3":{"name":"Stop Screen Share"},"e1db":{"name":"Storage"},"e8d1":{"name":"Store"},"e563":{"name":"Store Mall Directory"},"e41c":{"name":"Straighten"},"e56e":{"name":"Streetview"},"e257":{"name":"Strikethrough S"},"e41d":{"name":"Style"},"e5d9":{"name":"Subdirectory Arrow Left"},"e5da":{"name":"Subdirectory Arrow Right"},"e8d2":{"name":"Subject"},"e064":{"name":"Subscriptions"},"e048":{"name":"Subtitles"},"e56f":{"name":"Subway"},"e8d3":{"name":"Supervisor Account"},"e049":{"name":"Surround Sound"},"e0d7":{"name":"Swap Calls"},"e8d4":{"name":"Swap Horiz"},"e8d5":{"name":"Swap Vert"},"e8d6":{"name":"Swap Vertical Circle"},"e41e":{"name":"Switch Camera"},"e41f":{"name":"Switch Video"},"e627":{"name":"Sync"},"e628":{"name":"Sync Disabled"},"e629":{"name":"Sync Problem"},"e62a":{"name":"System Update"},"e8d7":{"name":"System Update Alt"},"e8d8":{"name":"Tab"},"e8d9":{"name":"Tab Unselected"},"e32f":{"name":"Tablet"},"e330":{"name":"Tablet Android"},"e331":{"name":"Tablet Mac"},"e420":{"name":"Tag Faces"},"e62b":{"name":"Tap And Play"},"e564":{"name":"Terrain"},"e262":{"name":"Text Fields"},"e165":{"name":"Text Format"},"e0d8":{"name":"Textsms"},"e421":{"name":"Texture"},"e8da":{"name":"Theaters"},"e8db":{"name":"Thumb Down"},"e8dc":{"name":"Thumb Up"},"e8dd":{"name":"Thumbs Up Down"},"e62c":{"name":"Time To Leave"},"e422":{"name":"Timelapse"},"e922":{"name":"Timeline"},"e425":{"name":"Timer"},"e423":{"name":"Timer 10"},"e424":{"name":"Timer 3"},"e426":{"name":"Timer Off"},"e264":{"name":"Title"},"e8de":{"name":"Toc"},"e8df":{"name":"Today"},"e8e0":{"name":"Toll"},"e427":{"name":"Tonality"},"e913":{"name":"Touch App"},"e332":{"name":"Toys"},"e8e1":{"name":"Track Changes"},"e565":{"name":"Traffic"},"e570":{"name":"Train"},"e571":{"name":"Tram"},"e572":{"name":"Transfer Within A Station"},"e428":{"name":"Transform"},"e8e2":{"name":"Translate"},"e8e3":{"name":"Trending Down"},"e8e4":{"name":"Trending Flat"},"e8e5":{"name":"Trending Up"},"e429":{"name":"Tune"},"e8e6":{"name":"Turned In"},"e8e7":{"name":"Turned In Not"},"e333":{"name":"Tv"},"e169":{"name":"Unarchive"},"e166":{"name":"Undo"},"e5d6":{"name":"Unfold Less"},"e5d7":{"name":"Unfold More"},"e923":{"name":"Update"},"e1e0":{"name":"Usb"},"e8e8":{"name":"Verified User"},"e258":{"name":"Vertical Align Bottom"},"e259":{"name":"Vertical Align Center"},"e25a":{"name":"Vertical Align Top"},"e62d":{"name":"Vibration"},"e070":{"name":"Video Call"},"e071":{"name":"Video Label"},"e04a":{"name":"Video Library"},"e04b":{"name":"Videocam"},"e04c":{"name":"Videocam Off"},"e338":{"name":"Videogame Asset"},"e8e9":{"name":"View Agenda"},"e8ea":{"name":"View Array"},"e8eb":{"name":"View Carousel"},"e8ec":{"name":"View Column"},"e42a":{"name":"View Comfy"},"e42b":{"name":"View Compact"},"e8ed":{"name":"View Day"},"e8ee":{"name":"View Headline"},"e8ef":{"name":"View List"},"e8f0":{"name":"View Module"},"e8f1":{"name":"View Quilt"},"e8f2":{"name":"View Stream"},"e8f3":{"name":"View Week"},"e435":{"name":"Vignette"},"e8f4":{"name":"Visibility"},"e8f5":{"name":"Visibility Off"},"e62e":{"name":"Voice Chat"},"e0d9":{"name":"Voicemail"},"e04d":{"name":"Volume Down"},"e04e":{"name":"Volume Mute"},"e04f":{"name":"Volume Off"},"e050":{"name":"Volume Up"},"e0da":{"name":"Vpn Key"},"e62f":{"name":"Vpn Lock"},"e1bc":{"name":"Wallpaper"},"e002":{"name":"Warning"},"e334":{"name":"Watch"},"e924":{"name":"Watch Later"},"e42c":{"name":"Wb Auto"},"e42d":{"name":"Wb Cloudy"},"e42e":{"name":"Wb Incandescent"},"e436":{"name":"Wb Iridescent"},"e430":{"name":"Wb Sunny"},"e63d":{"name":"Wc"},"e051":{"name":"Web"},"e069":{"name":"Web Asset"},"e16b":{"name":"Weekend"},"e80e":{"name":"Whatshot"},"e1bd":{"name":"Widgets"},"e63e":{"name":"Wifi"},"e1e1":{"name":"Wifi Lock"},"e1e2":{"name":"Wifi Tethering"},"e8f9":{"name":"Work"},"e25b":{"name":"Wrap Text"},"e8fa":{"name":"Youtube Searched For"},"e8ff":{"name":"Zoom In"},"e900":{"name":"Zoom Out"},"e56b":{"name":"Zoom Out Map"}}} \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.svg b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.svg deleted file mode 100755 index a449327e..00000000 --- a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.svg +++ /dev/null @@ -1,2373 +0,0 @@ - - - - - -Created by FontForge 20151118 at Mon Feb 8 11:58:02 2016 - By shyndman -Copyright 2015 Google, Inc. All Rights Reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ttf b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ttf deleted file mode 100755 index 7015564a..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.ttf and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff deleted file mode 100755 index b648a3ee..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff2 b/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff2 deleted file mode 100755 index 9fa21125..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/MaterialIcons-Regular.woff2 and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.eot b/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.eot deleted file mode 100755 index e9f60ca9..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.svg b/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.svg deleted file mode 100755 index 855c845e..00000000 --- a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - - -Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 - By ,,, -Copyright Dave Gandy 2016. All rights reserved. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.ttf b/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.ttf deleted file mode 100755 index 35acda2f..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff b/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff deleted file mode 100755 index 400014a4..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff2 b/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff2 deleted file mode 100755 index 4d13fc60..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/fonts/fontawesome-webfont.woff2 and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/border_type_1.png b/iiif-5-day-workshop/day-three/mirador/images/border_type_1.png deleted file mode 100755 index f1818325..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/border_type_1.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/border_type_2.png b/iiif-5-day-workshop/day-three/mirador/images/border_type_2.png deleted file mode 100755 index 60992c94..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/border_type_2.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/border_type_3.png b/iiif-5-day-workshop/day-three/mirador/images/border_type_3.png deleted file mode 100755 index 7e0f8e23..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/border_type_3.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/border_type_4.png b/iiif-5-day-workshop/day-three/mirador/images/border_type_4.png deleted file mode 100755 index 4a581bb4..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/border_type_4.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/border_type_5.png b/iiif-5-day-workshop/day-three/mirador/images/border_type_5.png deleted file mode 100755 index 544e018c..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/border_type_5.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/images/debut_dark.png b/iiif-5-day-workshop/day-three/mirador/images/debut_dark.png deleted file mode 100755 index 17a4d6b4..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/images/debut_dark.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/locales/ar/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/ar/translation.json deleted file mode 100755 index 79c01bf2..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/ar/translation.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "addItem": "أضف عنصراً", - "changeLayout": "غيّر الإطار", - "selectGrid": "اختر تقسيم الشاشة في الأسفل", - "bookmark": "أضف للمفضلة", - "close": "أغلق", - "bookmarkTitle": "أضف للمفضلة أو شارك مساحة العمل", - "filterObjects": "فلتر المواضيع", - "addNewObject": "أضف موضوعاً جديداً من الرابط", - "more": "أكثر", - "item": "عنصر", - "items": "عناصر", - "details": "تفاصيل", - "rights": "الحقوق", - "rightsStatus": "حالة الحقوق", - "unspecified": "غير محدد", - "links": "روابط", - "addSlotRight": "أضف شريحة إلى اليمين", - "addSlotLeft": "أضف شريحة إلى اليسار", - "addSlotAbove": "أضف شريحة في الأعلى", - "addSlotBelow": "أصف شريحة في الأسفل", - "imageView": "مشاهدة الصورة", - "bookView": "مشاهدة الكتاب", - "scrollView": "مشاهدة الانتقال", - "thumbnailsView": "مشاهدة ظفر الإبهام", - "comments": "التعليقات", - "addTagsHere": "أضف الإشارة هنا", - "save": "حفظ", - "cancel": "إلغاء", - "edit": "تحرير", - "delete": "مسح", - "url": "الرابط", - "newObject": "موضوع جديد", - "objectMetadata": "البيانات الوصفية للموضوع", - "fullScreen": "ملء الشاشة", - "logo": "الشعار", - "load": "عبأ", - "dropToLoad": "إسقاط لتحميل واضح" -} - - - diff --git a/iiif-5-day-workshop/day-three/mirador/locales/de/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/de/translation.json deleted file mode 100755 index 033d39b7..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/de/translation.json +++ /dev/null @@ -1,103 +0,0 @@ -{ - "addItem": "Objekt hinzufügen", - "addNewObject": "Objekt über URL hinzufügen", - "addSlotAbove": "Bereich oben hinzufügen", - "addSlotBelow": "Bereich unten hinzufügen", - "addSlotLeft": "Bereich links hinzufügen", - "addSlotRight": "Bereich rechts hinzufügen", - "addTagsHere": "Tags hier hinzufügen", - "annotationTooltip": "Annotationen", - "attribution": "Bereitgestellt von", - "bookmark": "Lesezeichen", - "bookmarkTitle": "Ansicht speichern oder teilen", - "bookmarkTooltip": "Lesezeichen für diese Mirador Instanz erstellen", - "bookView": "Doppelseite", - "borderColorTooltip": "Randfarbe wählen", - "borderTypeTooltip": "Randstil wählen", - "brightnessTooltip": "Helligkeit anpassen", - "cancel": "Abbrechen", - "cancelAnnotation": "Wollen Sie diese Annotation verwerfen?", - "changeLayout": "Layout ändern", - "changeLayoutTooltip": "Anzahl der sichtbaren Slots anpassen", - "close": "Schließen", - "closeTooltip": "Schließt das Fenster", - "comments": "Kommentare", - "contrastTooltip": "Kontrast anpassen", - "dashed":"Striche", - "delete": "Löschen", - "deleteAnnotation": "Wollen Sie diese Annotation und alle dazugehörigen Marker entfernen?", - "deleteShape":"Wollen Sie diesen Marker löschen?", - "description": "Beschreibung", - "details": "Details", - "disabledLayersTabMessage": "Bildebenen sind nur in der Einzelbildanzeige verfügbar", - "disabledOpacityMessage": "deaktiviert", - "dotDashed":"Punkte & Striche", - "dropToLoad": "Hier ablegen um das Manifest zu laden", - "edit": "Bearbeiten", - "editModalBtnDeleteAnnotation":"Annotation löschen", - "editModalBtnSaveWithoutShapes":"Annotation ohne Marker speichern", - "editModalSaveAnnotationWithNoShapesMsg":"Mit dieser Annotation sind keine Marker verknüpft", - "ellipseTooltip": "Oval", - "emptyTemplateMessage": "Auf diesem Canvas gibt es keine Bildebenen", - "fillColorTooltip": "Füllfarbe wählen", - "filterObjects": "Objekte filtern", - "freehandTooltip": "Freihand", - "fullScreen": "Vollbild", - "fullScreenTooltip": "Vollbild", - "fullScreenWindowTooltip": "Dieses Fenster als Vollbild anzeigen", - "grayscaleTooltip": "Graustufen umstellen", - "imageManipulationTooltip": "Bild-Manipulation", - "imagesFor": "Bilder für", - "imageView": "Einzelbild", - "invertTooltip": "Farben umkehren", - "item": "Objekt", - "items": "Objekte", - "less": "weniger", - "license": "Lizenz", - "links": "Links", - "load": "Laden", - "logo": "Logo", - "manifest": "IIIF-Manifest", - "metadataTooltip": "Informationen/Metadaten über dieses Objekt anzeigen", - "mirrorTooltip": "Bild spiegeln", - "more": "mehr", - "newObject": "Neues Objekt", - "no": "Nein", - "noIndex": "Kein Inhaltsverzeichnis verfügbar", - "noLabel": "Kein Label", - "objectMetadata": "Metadaten des Objekts", - "opacityLabel": "Deckkraft", - "pinTooltip": "Stecknadel", - "pointerTooltip": "Auswählen", - "polygonTooltip": "Polygon", - "rectangleTooltip": "Rechteck", - "related": "Verwandte Resourcen", - "resetTooltip": "Bild zurücksetzen", - "rights": "Rechte", - "rightsStatus": "Rechtsstatus", - "rotateLeftTooltip": "Um 90° nach links drehen", - "rotateRightTooltip": "Um 90° nach rechts drehen", - "saturationTooltip": "Sättigung anpassen", - "save": "Speichern", - "scrollView": "Horizontales Scrollen", - "searchLabelSelect": "Suchdienst auswählen", - "searchNotAvailable": "Kein Suchdienst verfügbar", - "searchText": "Suchtext", - "seeAlso": "Siehe auch", - "selectGrid": "Anordnung auswählen", - "sidePanelTooltip": "Seitenleiste", - "solid": "Durchgängig", - "submit": "Senden", - "tabTitleIndex": "Index", - "tabTitleLayers": "Ebenen", - "tabTitleSearch": "Suche", - "thick": "Dick", - "thickest": "Dicker", - "thumbnailsView": "Galerie", - "unspecified": "nicht spezifiziert", - "url": "URL", - "viewTypeTooltip": "Ansichtstyp wechseln", - "visibleLabel": "sichtbar", - "within": "Teil von", - "yes": "Ja" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/en/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/en/translation.json deleted file mode 100755 index f9a3c88f..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/en/translation.json +++ /dev/null @@ -1,104 +0,0 @@ -{ - "addItem": "Add Item", - "addNewObject": "Add new object from URL", - "addSlotAbove": "Add Slot Above", - "addSlotBelow": "Add Slot Below", - "addSlotLeft": "Add Slot Left", - "addSlotRight": "Add Slot Right", - "addTagsHere": "Add tags here", - "annotationTooltip": "Toggle annotations", - "attribution": "Attribution", - "bookmark": "Bookmark", - "bookmarkTitle": "Bookmark or Share Your Workspace", - "bookmarkTooltip": "Bookmark this Mirador instance", - "bookView": "Book View", - "borderColorTooltip": "Choose border color", - "borderTypeTooltip": "Choose border style", - "brightnessTooltip": "Adjust brightness", - "cancel": "Cancel", - "cancelAnnotation": "Do you want to cancel this annotation?", - "changeLayout": "Change Layout", - "changeLayoutTooltip": "Change the number of visible slots", - "close": "Close", - "closeTooltip": "Close this window", - "comments": "Comments", - "contrastTooltip": "Adjust contrast", - "dashed": "Dashes", - "delete": "Delete", - "deleteAnnotation": "Do you want to delete this annotation and all associated shapes?", - "deleteShape": "Do you want to delete this shape?", - "description": "Description", - "details": "Details", - "disabledLayersTabMessage": "Image layers are only available in single-page view", - "disabledOpacityMessage": "disabled", - "dotDashed": "Dots & Dashes", - "dropToLoad": "Drop to Load Manifest", - "edit": "Edit", - "editModalBtnDeleteAnnotation": "Delete this annotation", - "editModalBtnSaveWithoutShapes": "Save annotation without shapes", - "editModalSaveAnnotationWithNoShapesMsg": "There are no shapes associated with this annotation.", - "ellipseTooltip": "Oval annotation", - "emptyTemplateMessage": "There are no image layers on this canvas", - "fillColorTooltip": "Choose fill color", - "filterObjects": "Filter objects", - "freehandTooltip": "Freeform annotation", - "fullScreen": "Full Screen", - "fullScreenTooltip": "Toggle full screen", - "fullScreenWindowTooltip": "Toggle this window to full screen", - "grayscaleTooltip": "Toggle grayscale", - "imageManipulationTooltip": "Toggle image manipulation", - "imagesFor": "Images for", - "imageView": "Image View", - "invertTooltip": "Invert colors", - "item": "item", - "items": "items", - "label": "Label", - "less": "less", - "license": "License", - "links": "Links", - "load": "Load", - "logo": "Logo", - "manifest": "IIIF Manifest", - "metadataTooltip": "View information/metadata about this object", - "mirrorTooltip": "Mirror image", - "more": "more", - "newObject": "Replace Object", - "no": "No", - "noIndex": "No index available", - "noLabel": "No Label", - "objectMetadata": "Object Metadata", - "opacityLabel": "opacity", - "pinTooltip": "Pin annotation", - "pointerTooltip": "Pointer", - "polygonTooltip": "Polygon annotation", - "rectangleTooltip": "Rectangle annotation", - "related": "Related", - "resetTooltip": "Reset image", - "rights": "Rights", - "rightsStatus": "Rights Status", - "rotateLeftTooltip": "Rotate 90° left", - "rotateRightTooltip": "Rotate 90° right", - "saturationTooltip": "Adjust saturation", - "save": "Save", - "scrollView": "Scroll View", - "searchLabelSelect": "Select Search Service", - "searchNotAvailable": "No search service available", - "searchText": "Search text", - "seeAlso": "See Also", - "selectGrid": "Select a grid below", - "sidePanelTooltip": "Toggle the side panel", - "solid": "Solid", - "submit": "Submit", - "tabTitleIndex": "Index", - "tabTitleLayers": "Layers", - "tabTitleSearch": "Search", - "thick": "Thick", - "thickest": "Thickest", - "thumbnailsView": "Gallery View", - "unspecified": "Unspecified", - "url": "URL", - "viewTypeTooltip": "Change view type", - "visibleLabel": "visible", - "within": "Within", - "yes": "Yes" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/es/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/es/translation.json deleted file mode 100755 index 6450b44d..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/es/translation.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "addItem": "Añadir artículo", - "addNewObject": "Añadir nuevo objeto de URL", - "addSlotAbove": "Añadir sobre ranura", - "addSlotBelow": "Añadir debajo ranura", - "addSlotLeft": "Añadir izquierda ranura", - "addSlotRight": "Añadir derecho ranura", - "addTagsHere": "Añada etiquetas aquí", - "annotationTooltip": "Alternar anotaciones", - "attribution": "Atribución", - "bookView": "Vista del Libro", - "bookmark": "Añadir a la lista de marcadores", - "bookmarkTitle": "Añadir a la lista de marcadores o compartir su espacio de trabajo", - "bookmarkTooltip": "Añada esta instancia al Mirador", - "borderColorTooltip": "Elija el color del borde", - "borderTypeTooltip": "Elija estilo del borde", - "brightnessTooltip": "Ajustar el brillo", - "cancel": "Cancelar", - "cancelAnnotation": "¿Desea cancelar esta anotación?", - "changeLayout": "Cambiar diseño", - "changeLayoutTooltip": "Cambiar el número de ranuras visibles", - "close": "Cerrar", - "closeTooltip": "Cerrar esta ventana", - "comments": "Comentarios", - "contrastTooltip": "Ajuste el contraste", - "dashed": "Guiones", - "delete": "Eliminar", - "deleteAnnotation": "¿Desea eliminar esta anotación y todas las formas asociadas?", - "deleteShape": "¿Quieres eliminar esta forma?", - "description": "Descripción", - "details": "Detalles", - "dotDashed": "Puntos & Guiones", - "dropToLoad": "Soltar aquí para añadir el objeto", - "edit": "Editar", - "editModalBtnDeleteAnnotation": "Eliminar esta anotación", - "editModalBtnSaveWithoutShapes": "Guardar anotación sin formas", - "editModalSaveAnnotationWithNoShapesMsg": "No hay formas asociadas con esta anotación.", - "ellipseTooltip": "Anotación oval", - "fillColorTooltip": "Elija el color de relleno", - "filterObjects": "Filtrar objetos", - "freehandTooltip": "Anotación de forma libre", - "fullScreen": "Pantalla completa", - "fullScreenTooltip": "Alternar pantalla completa", - "fullScreenWindowTooltip": "Cambiar esta ventana a pantalla completa", - "grayscaleTooltip": "Cambiar a escala de grises", - "imageManipulationTooltip": "Alternar la manipulación de imágenes", - "imageView": "Vista de la Imagen", - "invertTooltip": "Invertir Colores", - "item": "artículo", - "items": "artículos", - "label": "Etiqueta", - "license": "Licencia", - "links": "Enlaces", - "load": "Cargar", - "logo": "Logo", - "metadataTooltip": "Ver información/metadatos sobre este objeto", - "mirrorTooltip": "Espejo de la Imagen", - "more": "más", - "newObject": "Nuevo Objeto", - "noIndex": "No hay ningún índice disponible", - "objectMetadata": "Metadatos", - "pinTooltip": "Anotación de pin", - "pointerTooltip": "Puntero", - "polygonTooltip": "Anotación de polígono", - "rectangleTooltip": "Anotación rectangular", - "related": "Relacionado", - "resetTooltip": "Restablecer imagen", - "rights": "Derechos", - "rightsStatus": "Estado de los Derechos", - "rotateLeftTooltip": "Girar 90° izquierda", - "rotateRightTooltip": "Girar 90° derecha", - "saturationTooltip": "Ajustar la saturación", - "save": "Salvar", - "scrollView": "Vista del rollo de papel", - "seeAlso": "Ver también", - "selectGrid": "Elija una cuadrícula de abajo", - "sidePanelTooltip": "Alternar el panel lateral", - "solid": "Sólido", - "thick": "Grueso", - "thickest": "Más grueso", - "thumbnailsView": "Miniaturas", - "unspecified": "Sin Especificar", - "viewTypeTooltip": "Cambiar tipo de vista", - "within": "Dentro de", - "yes": "Sí" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/fr/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/fr/translation.json deleted file mode 100755 index c2aa9966..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/fr/translation.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "addItem": "Ajouter un objet", - "addNewObject": "Ajouter un objet à partir de son URL", - "addSlotAbove": "Ajouter une fenêtre au-dessus", - "addSlotBelow": "Ajouter une fenêtre en dessous", - "addSlotLeft": "Ajouter une fenêtre à gauche", - "addSlotRight": "Ajouter une fenêtre à droite", - "addTagsHere": "Ajouter des mots-clés", - "annotationTooltip": "Annoter / Voir les annotations", - "attribution": "Attribution", - "bookmark": "Sauvegarder / Partager", - "bookmarkTitle": "Sauvegarder ou partager cet espace de travail Mirador", - "bookmarkTooltip": "Obtenir le lien vers cet espace de travail Mirador", - "bookView": "Vue livre", - "borderColorTooltip": "Choisir la couleur de bordure", - "borderTypeTooltip": "Choisir le style de bordure", - "brightnessTooltip": "Luminosité", - "cancel": "Annuler", - "cancelAnnotation": "Voulez-vous supprimer cette annotation", - "changeLayout": "Changer la disposition", - "changeLayoutTooltip": "Choisir le nombre de fenêtres visibles", - "close": "Fermer", - "closeTooltip": "Fermer cette fenêtre", - "comments": "Commentaires", - "contrastTooltip": "Contraste", - "dashed":"Tirets", - "delete": "Supprimer", - "deleteAnnotation": "Voulez-vous supprimer cette annotation et toutes les formes associées", - "deleteShape":"Voulez-vous supprimer cette forme", - "description": "Description", - "details": "Détails", - "disabledLayersTabMessage": "Les calques d'image ne sont accessibles que depuis la vue image", - "disabledOpacityMessage": "désactivé", - "dotDashed":"Pointillés et traits", - "dropToLoad": "Déposer ici pour ajouter l'objet", - "edit": "Editer", - "editModalBtnDeleteAnnotation":"Supprimer cette annotation", - "editModalBtnSaveWithoutShapes":"Enregistrer l'annotation sans aucune forme associée ?", - "editModalSaveAnnotationWithNoShapesMsg":"Aucune forme n'est associée à cette annotation.", - "ellipseTooltip": "Ovale", - "emptyTemplateMessage": "Il n'y a pas de calques d'image sur ce canevas", - "fillColorTooltip": "Choisir une couleur de remplissage", - "filterObjects": "Filtrer la liste", - "freehandTooltip": "Tracé libre", - "fullScreen": "Plein écran", - "fullScreenTooltip": "Ouvrir en plein écran", - "fullScreenWindowTooltip": "Ouvrir cette fenêtre en plein écran", - "grayscaleTooltip": "Niveaux de gris", - "imageManipulationTooltip": "Modifier les réglages de l'image", - "imagesFor": "Images pour", - "imageView": "Vue image", - "invertTooltip": "Couleurs inversées", - "item": "objet", - "items": "objets", - "label": "Libellé", - "license": "Licence", - "links": "Liens", - "load": "Ajouter", - "logo": "Logo", - "manifest": "Manifest IIIF", - "metadataTooltip": "Afficher les informations/métadonnées", - "mirrorTooltip": "Retourner l'image (axe horizontal)", - "more": "restants", - "newObject": "Nouvel objet", - "no": "Non", - "noIndex": "Aucun index disponible", - "objectMetadata": "Métadonnées", - "opacityLabel": "opacité", - "pinTooltip": "Marqueur", - "pointerTooltip": "Pointeur", - "polygonTooltip": "Polygone", - "rectangleTooltip": "Rectangle", - "related": "Ressources liées", - "resetTooltip": "Réinitialiser", - "rights": "Droits", - "rightsStatus": "Statut des droits", - "rotateLeftTooltip": "Rotation antihoraire 90°", - "rotateRightTooltip": "Rotation horaire 90°", - "saturationTooltip": "Saturation", - "save": "Enregistrer", - "scrollView": "Défilement horizontal", - "searchLabelSelect": "Choisir le service", - "searchNotAvailable": "Aucun service de recherche disponible", - "searchText": "Rechercher", - "seeAlso": "Voir aussi", - "selectGrid": "Sélectionner la grille de votre choix", - "sidePanelTooltip": "Ouvrir le panneau latéral", - "solid":"Ligne continue", - "tabTitleIndex": "Index", - "tabTitleLayers": "Calques", - "tabTitleSearch": "Rechercher", - "thick": "Epais", - "thickest": "Plus épais", - "thumbnailsView": "Mosaïque", - "unspecified": "Non spécifié", - "url": "URL", - "viewTypeTooltip": "Changer le type de vue", - "visibleLabel": "visible", - "within": "Fait partie de", - "yes": "Oui" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/ga/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/ga/translation.json deleted file mode 100755 index dce0d8bb..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/ga/translation.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "addItem": "Cuir mír leis", - "addNewObject": "Cuir ábhar ó URL", - "addSlotAbove": "Cuir Sliotán Thuas", - "addSlotBelow": "Cuir Sliotán Thíos", - "addSlotLeft": "Cuir Sliotán ar chlé", - "addSlotRight": "Cuir sliotán ar dheis", - "addTagsHere": "Cuir clibeanna anseo", - "annotationTooltip": "Malartaigh nótaí", - "attribution": "Admháil", - "bookmark": "Leabharmharc", - "bookmarkTitle": "Leabharmharcáil nó Roinn do Spás Oibre", - "bookmarkTooltip": "Leabharmharcáil an cás Mirador seo", - "bookView": "Amharc ar an leabhar", - "borderColorTooltip": "Roghnaigh dath imlíne don nodaireacht", - "borderTypeTooltip": "Roghnaigh stíl imlíne", - "brightnessTooltip": "Oiriúnaigh gile", - "cancel": "Cealaigh", - "cancelAnnotation": "An mian leat an nóta seo a chealú?", - "changeLayout": "Athraigh an Leagan Amach", - "changeLayoutTooltip": "Athraigh líon na sliotán atá le feiceáil", - "cite": "Luaigh", - "close": "Dún", - "closeTooltip": "Dún an fhuinneog seo", - "comments": "Nótaí tráchta", - "contrastTooltip": "Oiriúnaigh codarsnacht", - "crop": "Gearr amach", - "croptool": "Cuir eagar ar an íomhá", - "croptoolTooltip": "Gabh an íomhá de réir de shonraíocht féin", - "editImage": "Athraigh méid an íomhá", - "dashed": "Daiseanna", - "delete": "Scrios", - "deleteAnnotation": "An mian leat an nodaireacht seo agus pé cruth a bhaineann leis a scrios?", - "deleteShape": "An mian leat an cruth seo a scrios?", - "description": "Cur síos", - "details": "Sonraí", - "dotDashed": "Poncanna; daiseanna", - "dropToLoad": "Buail isteach lastliosta", - "edit": "Cuir in eagar", - "editModalBtnDeleteAnnotation": "Scrios an nodaireacht seo", - "editModalBtnSaveWithoutShapes": "Sábháil nodaireacht gan cruthanna", - "editModalSaveAnnotationWithNoShapesMsg": "N bhaineann cruth ar bith leis an nodaireacht seo", - "ellipseTooltip": "Nodaireacht ubhchruthach", - "fillColorTooltip": "Roghnaigh dath líonta don nodaireacht", - "filterObjects": "Scag ábhair", - "freehandTooltip": "Nodaireacht shaorfhoirme", - "fullScreen": "Lánscáileán", - "fullScreenTooltip": "Malartaigh lánscáileán", - "fullScreenWindowTooltip": "Malartaigh an fhuinneog seo go lánscáileán", - "grayscaleTooltip": "Scoránaigh an liathscála", - "help": "Cabhair", - "imageCapture": "Gabháil íomhá", - "imageManipulationTooltip": "Malartaigh láimhsiú íomhá ", - "imageView": "Amharc Íomhánna", - "invertTooltip": "Aisiompaigh na dathanna", - "item": "mír ", - "items": "míreanna", - "label": "Lipéad", - "language": "Teanga", - "license": "Ceadúnas", - "links": "Naisc", - "load": "Lódáil", - "logo": "Lógó", - "map": "Amharc ar chomhthéacs geografach", - "metadataTooltip": "Amharc ar eolas/meiteashonraí i leith an ábhar seo", - "more": "Tuilleadh", - "newObject": "Ábhar Nua", - "no": "Ní hea", - "noIndex": "Níl fáil ar innéacs", - "objectMetadata": "Meiteashonraí an ábhair", - "pinTooltip": "Nodaireacht bhioráin", - "pointerTooltip": "Pointeoir", - "polygonTooltip": "Nodaireacht pholagáin", - "rectangleTooltip": "Nodaireacht dronuilleoige", - "related": "Gaolmhar", - "resetTooltip": "Athshocraigh gach rialtán", - "rights": "Cearta", - "rightsStatus": "Stádas cirt", - "rotateLeftTooltip": "Cas 90céim; ar chlé", - "rotateRightTooltip": "Cas 90céim; ar dheis", - "saturationTooltip": "Coigeartaigh an sáithiú", - "save": "Sábháil", - "scrollView": "Amharc Scrollaithe", - "seeAlso": "Féach freisin", - "selectGrid": "Roghnaigh greille thíos", - "sidePanelTooltip": "malartaigh an painéal taoibh", - "solid": "dlúthlíne", - "thick": "tiúlíne", - "thickest": "líne is tiubha", - "thumbnailsView": "Amharc ar an gailearaí", - "transcribe": "Scríobh amach an mhír seo", - "unspecified": "Neamhshonraithe", - "url": "URL", - "viewTypeTooltip": "Athraigh amhairc", - "within": "Laistigh de", - "yes": "Tá" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/ja/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/ja/translation.json deleted file mode 100755 index 88125308..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/ja/translation.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "addItem": "アイテム追加", - "addNewObject": "URLで新規オブジェクト追加", - "addSlotAbove": "上にスロット追加", - "addSlotBelow": "下にスロット追加", - "addSlotLeft": "左にスロット追加", - "addSlotRight": "右にスロット追加", - "addTagsHere": "ここでタグを追加", - "annotationTooltip": "アノテーション", - "attribution": "帰属", - "bookmark": "ブックマーク", - "bookmarkTitle": "現在の表示内容をブックマーク", - "bookmarkTooltip": "このインスタンスをブックマーク", - "bookView": "Book表示モード", - "borderColorTooltip": "線の色を選択", - "borderTypeTooltip": "線のスタイルを選択", - "brightnessTooltip": "明度調整", - "cancel": "キャンセル", - "cancelAnnotation": "この注釈を取消したいですか?", - "changeLayout": "レイアウト変更", - "changeLayoutTooltip": "スロット数の変更", - "close": "閉じる", - "closeTooltip": "このウインドウを閉じる", - "comments": "コメント", - "contrastTooltip": "コントラスト調整", - "dashed":"破線", - "delete": "削除", - "deleteAnnotation": "この注釈と関連するすべての図形を削除したいですか?", - "deleteShape":"この図形を削除したいですか?", - "details": "詳細", - "dotDashed":"一点鎖線", - "dropToLoad": "ドロップしてマニフェストを読み込み", - "edit": "編集", - "editModalBtnDeleteAnnotation":"この注釈を削除", - "editModalBtnSaveWithoutShapes":"図形なしで注釈を保存", - "editModalSaveAnnotationWithNoShapesMsg":"この注釈に関連する図形はありません。", - "ellipseTooltip": "楕円形で注釈", - "fillColorTooltip": "塗り潰し色を選択", - "filterObjects": "フィルタをかける対象", - "freehandTooltip": "フリーハンドで注釈", - "fullScreen": "全画面表示", - "fullScreenTooltip": "フルスクリーン表示", - "fullScreenWindowTooltip": "このウインドウをフルスクリーン表示", - "grayscaleTooltip": "グレースケール", - "imageManipulationTooltip": "画像操作", - "imageView": "画像表示モード", - "invertTooltip": "色反転", - "item": "アイテム", - "items": "アイテム", - "license": "利用許諾条件(ライセンス)", - "links": "リンク", - "load": "読み込み", - "logo": "ロゴ", - "metadataTooltip": "この資料の情報を表示", - "more": "さらに", - "newObject": "新しいオブジェクト", - "no": "いいえ", - "objectMetadata": "オブジェクトのメタデータ", - "pinTooltip": "ピンポイントで注釈", - "pointerTooltip": "ポインター", - "polygonTooltip": "多角形で注釈", - "rectangleTooltip": "矩形で注釈", - "related": "関連リソース", - "resetTooltip": "設定をリセット", - "rights": "権利関係", - "rightsStatus": "権利状態", - "rotateLeftTooltip": "90度左回転", - "rotateRightTooltip": "90度右回転", - "saturationTooltip": "彩度調整", - "save": "保存", - "scrollView": "スクロール表示モード", - "seeAlso": "機械可読形式の解説", - "selectGrid": "以下のグリッドから選択", - "sidePanelTooltip": "サイドパネルを表示", - "solid":"実線", - "thumbnailsView": "ギャラリー表示モード", - "unspecified": "未特定の", - "url": "URL", - "viewTypeTooltip": "表示モード切替え", - "within": "このリソースを含むリソース", - "yes": "はい" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/ko/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/ko/translation.json deleted file mode 100755 index 7a0b5d7d..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/ko/translation.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "addItem": "아이템 추가", - "addNewObject": "URL 사용 오브젝트 추가", - "addSlotAbove": "슬롯 추가 - 위", - "addSlotBelow": "슬롯 추가 - 아래", - "addSlotLeft": "슬롯 추가 - 왼쪽", - "addSlotRight": "슬롯 추가 - 오른쪽", - "addTagsHere": "태그 추가", - "annotationTooltip": "주석 모드 전환", - "attribution": "저작자 정보", - "bookmark": "북마크", - "bookmarkTitle": "작업공간 공유/북마크", - "bookmarkTooltip": "북마크 하기", - "bookView": "책으로 보기", - "borderColorTooltip": "경계 색 선택", - "borderTypeTooltip": "경계 스타일", - "brightnessTooltip": "명도 변환", - "cancel": "취소", - "cancelAnnotation": "이 주석을 취소하시겠습니까?", - "changeLayout": "레이아웃 변경", - "changeLayoutTooltip": "슬롯 개수 변경", - "close": "닫기", - "closeTooltip": "창 닫기", - "comments": "코멘트", - "contrastTooltip": "대비 조절", - "dashed": "파선", - "delete": "지우기", - "deleteAnnotation": "이 주석과 그에 관련된 도형들을 삭제하시겠습니까?", - "deleteShape":"이 도형을 삭제하시겠습니까?", - "details": "세부 정보", - "dotDashed":"쇄선", - "dropToLoad": "매니페스트를 여기 놓으세요.", - "edit": "편집", - "editModalBtnDeleteAnnotation":"주석 삭제", - "editModalBtnSaveWithoutShapes":"도형 없이 주석 저장하기", - "editModalSaveAnnotationWithNoShapesMsg":"이 주석과 관련된 도형이 없습니다.", - "ellipseTooltip": "타원형", - "fillColorTooltip": "면색", - "filterObjects": "오브젝트 필터", - "freehandTooltip": "프리핸드", - "fullScreen": "전체화면", - "fullScreenTooltip": "전체화면 전환", - "fullScreenWindowTooltip": "이 창을 전체화면으로", - "grayscaleTooltip": "그레이스케일 전환", - "imageManipulationTooltip": "이미지 변환", - "imageView": "이미지로 보기", - "invertTooltip": "색상 반전", - "item": "아이템", - "items": "아이템", - "license": "라이선스", - "links": "고리", - "load": "불러오기", - "logo": "로고", - "metadataTooltip": "메타데이터", - "more": "더 보기", - "newObject": "새 오브젝트", - "no": "아니요", - "noIndex": "인덱스가 없습니다", - "objectMetadata": "오브젝트 메타데이터", - "pinTooltip": "핀", - "pointerTooltip": "포인터", - "polygonTooltip": "다각형", - "rectangleTooltip": "직사각형", - "related": "관련고리", - "resetTooltip": "이미지 리셋", - "rights": "저작권 정보", - "rightsStatus": "저작권 상황", - "rotateLeftTooltip": "90도 좌회전", - "rotateRightTooltip": "90도 우회전", - "saturationTooltip": "채도 변환", - "save": "저장", - "scrollView": "스크롤로 보기", - "seeAlso": "같이 보기", - "selectGrid": "격자 선택하기", - "sidePanelTooltip": "사이드 패널 전환", - "solid":"실선", - "thumbnailsView": "썸네일로 보기", - "unspecified": "불특정", - "url": "URL", - "viewTypeTooltip": "뷰 타입 전환", - "within": "상위 컬렉션", - "yes": "네" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/nl/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/nl/translation.json deleted file mode 100755 index 228504b9..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/nl/translation.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "addItem": "Voeg item toe", - "changeLayout": "Pas layout aan", - "selectGrid": "Kies een grid hieronder", - "bookmark": "Favoriet", - "close": "Sluiten", - "bookmarkTitle": "Favoriet of deel uw werkset", - "filterObjects": "Filter objecten", - "addNewObject": "Voeg nieuw object toe via URL", - "more": "meer", - "item": "item", - "items": "items", - "details": "Details", - "rights": "Copyright", - "rightsStatus": "Copyright Status", - "unspecified": "Niet gespecifieerd", - "links": "Links", - "addSlotRight": "Voeg Slot toe rechts", - "addSlotLeft": "Voeg Slot toe links", - "addSlotAbove": "Voeg Slot toe bovenaan", - "addSlotBelow": "Voeg Slot toe onderaan", - "imageView": "Beeld presentatie", - "bookView": "Boek presentatie", - "scrollView": "Navigeer door presentatie", - "thumbnailsView": "Galerie presentatie", - "comments": "Commentaar", - "addTagsHere": "Voeg hier tags toe", - "save": "Bewaren", - "cancel": "Annuleren", - "edit": "Bewerken", - "delete": "Verwijderen", - "url": "URL", - "newObject": "Nieuw Object", - "objectMetadata": "Object Metadata", - "fullScreen": "Volledig scherm", - "logo": "Logo", - "load": "Opladen", - "dropToLoad": "Vallen hier om object te laden" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/zh-CN/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/zh-CN/translation.json deleted file mode 100755 index 58896cbb..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/zh-CN/translation.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "addItem": "添加项", - "addNewObject": "从 URL 建立新的物件", - "addSlotAbove": "添加插槽(上)", - "addSlotBelow": "添加插槽(下)", - "addSlotLeft": "添加插槽(左)", - "addSlotRight": "添加插槽(右)", - "addTagsHere": "添加标签", - "bookmark": "添加书签", - "bookmarkTitle": "为当前工作区创建书签", - "bookmarkTooltip": "为当前进程创建书签", - "bookView": "书本视图", - "borderColorTooltip": "选择边框颜色", - "borderTypeTooltip": "选择边框样式", - "brightnessTooltip": "调整亮度", - "cancel": "取消", - "cancelAnnotation": "你想取消这个注释吗?", - "changeLayout": "更改布局", - "changeLayoutTooltip": "更改可见插槽的数量", - "close": "关闭", - "closeTooltip": "关闭这个窗口", - "comments": "评论", - "contrastTooltip": "调整对比度", - "dashed": "虚线", - "delete": "删除", - "deleteAnnotation": "你想删除这个注释和所有相关的形状吗?", - "deleteShape": "你想删除这个形状吗?", - "details": "详细资料", - "dotDashed": "点和虚线", - "dropToLoad": "拖放以装载清单", - "edit": "编辑", - "editModalBtnDeleteAnnotation": "删除这个注释", - "editModalBtnSaveWithoutShapes": "存储注释但忽略形状", - "editModalSaveAnnotationWithNoShapesMsg": "这个注释没有相关的形状。", - "ellipseTooltip": "椭圆形注释", - "fillColorTooltip": "选择填充颜色", - "filterObjects": "过滤物件", - "freehandTooltip": "自由注释", - "fullScreen": "全屏", - "fullScreenTooltip": "进入/退出全屏", - "fullScreenWindowTooltip": "进入/退出全屏", - "grayscaleTooltip": "灰度", - "imageView": "图像视图", - "invertTooltip": "反色", - "item": "项目", - "items": "项目", - "links": "链接", - "load": "载入", - "logo": "徽标", - "metadataTooltip": "查看这个物件的信息/元数据", - "more": "更多", - "newObject": "建立新的物件", - "no": "否", - "objectMetadata": "物件元数据", - "pinTooltip": "点注释", - "polygonTooltip": "多边形注释", - "rectangleTooltip": "长方形注释", - "resetTooltip": "重置图像", - "rights": "版权", - "rightsStatus": "版权状态", - "rotateLeftTooltip": "顺时针旋转 90 度", - "rotateRightTooltip": "逆时针旋转 90 度", - "saturationTooltip": "调整色彩饱和度", - "save": "保存", - "scrollView": "滚动视图", - "selectGrid": "选中下方单元格", - "sidePanelTooltip": "打开/关闭侧边栏", - "solid": "实线", - "thumbnailsView": "图库视图", - "unspecified": "未指定的", - "url": "URL", - "viewTypeTooltip": "更改视图", - "yes": "是" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/zh-TW/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/zh-TW/translation.json deleted file mode 100755 index 08b45836..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/zh-TW/translation.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "addItem": "添加項", - "addNewObject": "從 URL 建立新的物件", - "addSlotAbove": "添加插槽(上)", - "addSlotBelow": "添加插槽(下)", - "addSlotLeft": "添加插槽(左)", - "addSlotRight": "添加插槽(右)", - "addTagsHere": "添加標簽", - "bookmark": "添加書簽", - "bookmarkTitle": "為當前工作區創建書簽", - "bookmarkTooltip": "為當前進程創建書簽", - "bookView": "書本視圖", - "borderColorTooltip": "選擇邊框顏色", - "borderTypeTooltip": "選擇邊框樣式", - "brightnessTooltip": "調整亮度", - "cancel": "取消", - "cancelAnnotation": "你想取消這個注釋嗎?", - "changeLayout": "改變布局", - "changeLayoutTooltip": "更改可見插槽的數量", - "close": "關閉", - "closeTooltip": "關閉這個窗口", - "comments": "評論", - "contrastTooltip": "調整對比度", - "dashed": "虛線", - "delete": "刪除", - "deleteAnnotation": "你想刪除這個注釋和所有相關的形狀嗎?", - "deleteShape": "你想刪除這個形狀嗎?", - "details": "詳細資料", - "dotDashed": "點和虛線", - "dropToLoad": "拖放以裝載清單", - "edit": "編輯", - "editModalBtnDeleteAnnotation": "刪除這個注釋", - "editModalBtnSaveWithoutShapes": "存儲注釋但忽略形狀", - "editModalSaveAnnotationWithNoShapesMsg": "這個注釋沒有相關的形狀。", - "ellipseTooltip": "橢圓形注釋", - "fillColorTooltip": "選擇填充顏色", - "filterObjects": "過濾物件", - "freehandTooltip": "自由注釋", - "fullScreen": "全屏", - "fullScreenTooltip": "進入/退出全屏", - "fullScreenWindowTooltip": "進入/退出全屏", - "grayscaleTooltip": "灰度", - "imageView": "圖像視圖", - "invertTooltip": "反色", - "item": "項目", - "items": "項目", - "links": "鏈接", - "load": "載入", - "logo": "徽標", - "metadataTooltip": "查看這個物件的信息/元數據", - "more": "更多", - "newObject": "建立新的物件", - "no": "否", - "objectMetadata": "物件元數據", - "pinTooltip": "點注釋", - "polygonTooltip": "多邊形注釋", - "rectangleTooltip": "長方形注釋", - "resetTooltip": "重置圖像", - "rights": "版權", - "rightsStatus": "版權狀態", - "rotateLeftTooltip": "順時針旋轉 90 度", - "rotateRightTooltip": "逆時針旋轉 90 度", - "saturationTooltip": "調整色彩飽和度", - "save": "保存", - "scrollView": "滾動視圖", - "selectGrid": "選中下方單元格", - "sidePanelTooltip": "打開/關閉側邊欄", - "solid": "實線", - "thumbnailsView": "圖庫視圖", - "unspecified": "未指定的", - "url": "URL", - "viewTypeTooltip": "更改視圖", - "yes": "是" -} diff --git a/iiif-5-day-workshop/day-three/mirador/locales/zh/translation.json b/iiif-5-day-workshop/day-three/mirador/locales/zh/translation.json deleted file mode 100755 index 58896cbb..00000000 --- a/iiif-5-day-workshop/day-three/mirador/locales/zh/translation.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "addItem": "添加项", - "addNewObject": "从 URL 建立新的物件", - "addSlotAbove": "添加插槽(上)", - "addSlotBelow": "添加插槽(下)", - "addSlotLeft": "添加插槽(左)", - "addSlotRight": "添加插槽(右)", - "addTagsHere": "添加标签", - "bookmark": "添加书签", - "bookmarkTitle": "为当前工作区创建书签", - "bookmarkTooltip": "为当前进程创建书签", - "bookView": "书本视图", - "borderColorTooltip": "选择边框颜色", - "borderTypeTooltip": "选择边框样式", - "brightnessTooltip": "调整亮度", - "cancel": "取消", - "cancelAnnotation": "你想取消这个注释吗?", - "changeLayout": "更改布局", - "changeLayoutTooltip": "更改可见插槽的数量", - "close": "关闭", - "closeTooltip": "关闭这个窗口", - "comments": "评论", - "contrastTooltip": "调整对比度", - "dashed": "虚线", - "delete": "删除", - "deleteAnnotation": "你想删除这个注释和所有相关的形状吗?", - "deleteShape": "你想删除这个形状吗?", - "details": "详细资料", - "dotDashed": "点和虚线", - "dropToLoad": "拖放以装载清单", - "edit": "编辑", - "editModalBtnDeleteAnnotation": "删除这个注释", - "editModalBtnSaveWithoutShapes": "存储注释但忽略形状", - "editModalSaveAnnotationWithNoShapesMsg": "这个注释没有相关的形状。", - "ellipseTooltip": "椭圆形注释", - "fillColorTooltip": "选择填充颜色", - "filterObjects": "过滤物件", - "freehandTooltip": "自由注释", - "fullScreen": "全屏", - "fullScreenTooltip": "进入/退出全屏", - "fullScreenWindowTooltip": "进入/退出全屏", - "grayscaleTooltip": "灰度", - "imageView": "图像视图", - "invertTooltip": "反色", - "item": "项目", - "items": "项目", - "links": "链接", - "load": "载入", - "logo": "徽标", - "metadataTooltip": "查看这个物件的信息/元数据", - "more": "更多", - "newObject": "建立新的物件", - "no": "否", - "objectMetadata": "物件元数据", - "pinTooltip": "点注释", - "polygonTooltip": "多边形注释", - "rectangleTooltip": "长方形注释", - "resetTooltip": "重置图像", - "rights": "版权", - "rightsStatus": "版权状态", - "rotateLeftTooltip": "顺时针旋转 90 度", - "rotateRightTooltip": "逆时针旋转 90 度", - "saturationTooltip": "调整色彩饱和度", - "save": "保存", - "scrollView": "滚动视图", - "selectGrid": "选中下方单元格", - "sidePanelTooltip": "打开/关闭侧边栏", - "solid": "实线", - "thumbnailsView": "图库视图", - "unspecified": "未指定的", - "url": "URL", - "viewTypeTooltip": "更改视图", - "yes": "是" -} diff --git a/iiif-5-day-workshop/day-three/mirador/mirador.min.js b/iiif-5-day-workshop/day-three/mirador/mirador.min.js deleted file mode 100755 index 994b04ed..00000000 --- a/iiif-5-day-workshop/day-three/mirador/mirador.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){for((c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;s--;)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement&&(h=(d=a).documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0}),d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ye(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;nx",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y)for(n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return void 0!==w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;l--;)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){for(l=(t=(t||"").match(M)||[""]).length;l--;)if(d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){for(f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;o--;)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var n,r,i,o,a,s,t=w.event.fix(e),u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")&&w(e).children("tbody")[0]||e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r").prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&o("error"===e.type?404:200,e.type)}),r.head.appendChild(t[0])},abort:function(){n&&n()}}});var Yt=[],Qt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Yt.pop()||w.expando+"_"+Et++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Qt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Qt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=g(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Qt,"$1"+i):!1!==t.jsonp&&(t.url+=(kt.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Yt.push(i)),a&&g(o)&&o(a[0]),a=o=void 0}),"script"}),h.createHTMLDocument=function(){var e=r.implementation.createHTMLDocument("").body;return e.innerHTML="
    ",2===e.childNodes.length}(),w.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(h.createHTMLDocument?((i=(t=r.implementation.createHTMLDocument("")).createElement("base")).href=r.location.href,t.head.appendChild(i)):t=r),a=!n&&[],(o=A.exec(e))?[t.createElement(o[1])]:(o=xe([e],t,a),a&&a.length&&w(a).remove(),w.merge([],o.childNodes)));var i,o,a},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,c=w.css(e,"position"),f=w(e),p={};"static"===c&&(e.style.position="relative"),s=f.offset(),o=w.css(e,"top"),u=w.css(e,"left"),("absolute"===c||"fixed"===c)&&-1<(o+u).indexOf("auto")?(a=(r=f.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),g(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(p.top=t.top-s.top+a),null!=t.left&&(p.left=t.left-s.left+i),"using"in t?t.using.call(e,p):f.css(p)}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];return r?r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===w.css(e,"position");)e=e.offsetParent;return e||be})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return z(this,function(e,r,i){var o;if(y(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=_e(h.pixelPosition,function(e,n){if(n)return n=Fe(e,t),We.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return z(this,function(t,n,i){var o;return y(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return 0
    "))}function n(e){var i="button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";return e.on("mouseout",i,function(){t(this).removeClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).removeClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).removeClass("ui-datepicker-next-hover")}).on("mouseover",i,o)}function o(){t.datepicker._isDisabledDatepicker(m.inline?m.dpDiv.parent()[0]:m.input[0])||(t(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),t(this).addClass("ui-state-hover"),-1!==this.className.indexOf("ui-datepicker-prev")&&t(this).addClass("ui-datepicker-prev-hover"),-1!==this.className.indexOf("ui-datepicker-next")&&t(this).addClass("ui-datepicker-next-hover"))}function a(e,i){for(var s in t.extend(e,i),i)null==i[s]&&(e[s]=i[s]);return e}function r(t){return function(){var e=this.element.val();t.apply(this,arguments),this._refresh(),e!==this.element.val()&&this._trigger("change")}}t.ui=t.ui||{},t.ui.version="1.12.1";var h=0,l=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{(s=t._data(n,"events"))&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0],l=h+"-"+(e=e.split(".")[1]);return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?void(arguments.length&&this._createWidget(t,e)):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),(a=new i).options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?void(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}()):void(r[e]=s)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n&&a.widgetEventPrefix||e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,s,n=l.call(arguments,1),o=0,a=n.length;o",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,i){i=t(i||this.defaultElement||this)[0],this.element=t(i),this.uuid=h++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},i!==this&&(t.data(i,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===i&&this.destroy()}}),this.document=t(i.style?i.ownerDocument:i.document||i),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},e=(s=e.split(".")).shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||!0!==o.options.disabled&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){var s=this;return setTimeout(function(){return("string"==typeof t?s[t]:t).apply(s,arguments)},e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},(i=t.Event(i)).type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&!1===a.apply(this.element[0],[i].concat(s))||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?!0===n||"number"==typeof n?i:n.effect||i:e;"number"==typeof(n=n||{})&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
    "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),e===(i=o.offsetWidth)&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widtha(e+i)&&(u.horizontal="center"),fa(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?0a?0i)&&(t.left+=d+p+f):0a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,p="top"===e.my[1]?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];c<0?((s=t.top+p+f+g+e.collisionHeight-r-o)<0||a(c)>s)&&(t.top+=p+f+g):0a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}});var c="ui-effects-",u="ui-effects-style",d="ui-effects-animated",p=t;t.effects={effect:{}},function(t,e){function i(t,e,i){var s=u[e.type]||{};return null==t?i||!e.def?null:e.def:(t=s.floor?~~t:parseFloat(t),isNaN(t)?e.def:s.mod?(t+s.mod)%s.mod:t<0?0:t>s.max?s.max:t)}function s(i){var s=l(),n=s._rgba=[];return i=i.toLowerCase(),f(h,function(t,o){var a,r=o.re.exec(i),h=r&&o.parse(r),l=o.space||"rgba";return h?(a=s[l](h),s[c[l].cache]=a[c[l].cache],n=s._rgba=a._rgba,!1):e}),n.length?("0,0,0,0"===n.join()&&t.extend(n,o.transparent),s):o[i]}function n(t,e,i){return 6*(i=(i+1)%1)<1?t+6*(e-t)*i:2*i<1?e:3*i<2?t+6*(e-t)*(2/3-i):t}var o,r=/^([\-+])=\s*(\d+\.?\d*)/,h=[{re:/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[t[1],t[2],t[3],t[4]]}},{re:/rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,parse:function(t){return[2.55*t[1],2.55*t[2],2.55*t[3],t[4]]}},{re:/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,parse:function(t){return[parseInt(t[1],16),parseInt(t[2],16),parseInt(t[3],16)]}},{re:/#([a-f0-9])([a-f0-9])([a-f0-9])/,parse:function(t){return[parseInt(t[1]+t[1],16),parseInt(t[2]+t[2],16),parseInt(t[3]+t[3],16)]}},{re:/hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,space:"hsla",parse:function(t){return[t[1],t[2]/100,t[3]/100,t[4]]}}],l=t.Color=function(e,i,s,n){return new t.Color.fn.parse(e,i,s,n)},c={rgba:{props:{red:{idx:0,type:"byte"},green:{idx:1,type:"byte"},blue:{idx:2,type:"byte"}}},hsla:{props:{hue:{idx:0,type:"degrees"},saturation:{idx:1,type:"percent"},lightness:{idx:2,type:"percent"}}}},u={byte:{floor:!0,max:255},percent:{max:1},degrees:{mod:360,floor:!0}},d=l.support={},p=t("

    ")[0],f=t.each;p.style.cssText="background-color:rgba(1,1,1,.5)",d.rgba=-1c.mod/2?a+=c.mod:a-l>c.mod/2&&(a-=c.mod)),h[o]=i((l-a)*e+a,n)))}),this[n](h)},blend:function(e){if(1===this._rgba[3])return this;var i=this._rgba.slice(),s=i.pop(),n=l(e)._rgba;return l(t.map(i,function(t,e){return(1-s)*n[e]+s*t}))},toRgbaString:function(){var e="rgba(",i=t.map(this._rgba,function(t,e){return null==t?2").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),n={width:e.width(),height:e.height()},o=document.activeElement;try{o.id}catch(a){o=document.body}return e.wrap(s),(e[0]===o||t.contains(e[0],o))&&t(o).trigger("focus"),s=e.parent(),"static"===e.css("position")?(s.css({position:"relative"}),e.css({position:"relative"})):(t.extend(i,{position:e.css("position"),zIndex:e.css("z-index")}),t.each(["top","left","bottom","right"],function(t,s){i[s]=e.css(s),isNaN(parseInt(i[s],10))&&(i[s]="auto")}),e.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),e.css(n),s.css(i).show()},removeWrapper:function(e){var i=document.activeElement;return e.parent().is(".ui-effects-wrapper")&&(e.parent().replaceWith(e),(e[0]===i||t.contains(e[0],i))&&t(i).trigger("focus")),e}}),t.extend(t.effects,{version:"1.12.1",define:function(e,i,s){return s||(s=i,i="effect"),t.effects.effect[e]=s,t.effects.effect[e].mode=i,s},scaledDimensions:function(t,e,i){if(0===e)return{height:0,width:0,outerHeight:0,outerWidth:0};var s="horizontal"!==i?(e||100)/100:1,n="vertical"!==i?(e||100)/100:1;return{height:t.height()*n,width:t.width()*s,outerHeight:t.outerHeight()*n,outerWidth:t.outerWidth()*s}},clipToBox:function(t){return{width:t.clip.right-t.clip.left,height:t.clip.bottom-t.clip.top,left:t.clip.left,top:t.clip.top}},unshift:function(t,e,i){var s=t.queue();1").insertAfter(e).css({display:/^(inline|ruby)/.test(e.css("display"))?"inline-block":"block",visibility:"hidden",marginTop:e.css("marginTop"),marginBottom:e.css("marginBottom"),marginLeft:e.css("marginLeft"),marginRight:e.css("marginRight"),float:e.css("float")}).outerWidth(e.outerWidth()).outerHeight(e.outerHeight()).addClass("ui-effects-placeholder"),e.data(c+"placeholder",i)),e.css({position:s,left:n.left,top:n.top}),i},removePlaceholder:function(t){var e=c+"placeholder",i=t.data(e);i&&(i.remove(),t.removeData(e))},cleanUp:function(e){t.effects.restoreStyle(e),t.effects.removePlaceholder(e)},setTransition:function(e,i,s,n){return n=n||{},t.each(i,function(t,i){var o=e.cssUnit(i);0").appendTo("body").addClass(e.className).css({top:u.top-r,left:u.left-h,height:s.innerHeight(),width:s.innerWidth(),position:o?"fixed":"absolute"}).animate(c,e.duration,e.easing,function(){d.remove(),t.isFunction(i)&&i()})}}),t.fx.step.clip=function(e){e.clipInit||(e.start=t(e.elem).cssClip(),"string"==typeof e.end&&(e.end=s(e.end,e.elem)),e.clipInit=!0),t(e.elem).cssClip({top:e.pos*(e.end.top-e.start.top)+e.start.top,right:e.pos*(e.end.right-e.start.right)+e.start.right,bottom:e.pos*(e.end.bottom-e.start.bottom)+e.start.bottom,left:e.pos*(e.end.left-e.start.left)+e.start.left})}}(),function(){var e={};t.each(["Quad","Cubic","Quart","Quint","Expo"],function(t,i){e[i]=function(e){return Math.pow(e,t+2)}}),t.extend(e,{Sine:function(t){return 1-Math.cos(t*Math.PI/2)},Circ:function(t){return 1-Math.sqrt(1-t*t)},Elastic:function(t){return 0===t||1===t?t:-Math.pow(2,8*(t-1))*Math.sin((80*(t-1)-7.5)*Math.PI/15)},Back:function(t){return t*t*(3*t-2)},Bounce:function(t){for(var e,i=4;((e=Math.pow(2,--i))-1)/11>t;);return 1/Math.pow(4,3-i)-7.5625*Math.pow((3*e-2)/22-t,2)}}),t.each(e,function(e,i){t.easing["easeIn"+e]=i,t.easing["easeOut"+e]=function(t){return 1-i(1-t)},t.easing["easeInOut"+e]=function(t){return t<.5?i(2*t)/2:1-i(-2*t+2)/2}})}();t.effects;t.effects.define("blind","hide",function(e,i){var s={up:["bottom","top"],vertical:["bottom","top"],down:["top","bottom"],left:["right","left"],horizontal:["right","left"],right:["left","right"]},n=t(this),o=e.direction||"up",a=n.cssClip(),r={clip:t.extend({},a)},h=t.effects.createPlaceholder(n);r.clip[s[o][0]]=r.clip[s[o][1]],"show"===e.mode&&(n.cssClip(r.clip),h&&h.css(t.effects.clipToBox(r)),r.clip=a),h&&h.animate(t.effects.clipToBox(r),e.duration,e.easing),n.animate(r,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("bounce",function(e,i){var s,n,o,a=t(this),r=e.mode,h="hide"===r,l="show"===r,c=e.direction||"up",u=e.distance,d=e.times||5,p=2*d+(l||h?1:0),f=e.duration/p,g=e.easing,m="up"===c||"down"===c?"top":"left",_="up"===c||"left"===c,v=0,b=a.queue().length;for(t.effects.createPlaceholder(a),o=a.css(m),u||(u=a["top"===m?"outerHeight":"outerWidth"]()/3),l&&((n={opacity:1})[m]=o,a.css("opacity",0).css(m,_?2*-u:2*u).animate(n,f,g)),h&&(u/=Math.pow(2,d-1)),(n={})[m]=o;v").css({position:"absolute",visibility:"visible",left:-a*_,top:-o*v}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:_,height:v,left:r+(g?l*_:0),top:h+(g?c*v:0),opacity:g?0:1}).animate({left:r+(g?0:l*_),top:h+(g?0:c*v),opacity:g?1:0},e.duration||500,e.easing,s)}),t.effects.define("fade","toggle",function(e,i){var s="show"===e.mode;t(this).css("opacity",s?0:1).animate({opacity:s?1:0},{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("fold","hide",function(e,i){var s=t(this),n=e.mode,o="show"===n,a="hide"===n,r=e.size||15,h=/([0-9]+)%/.exec(r),c=!!e.horizFirst?["right","bottom"]:["bottom","right"],u=e.duration/2,d=t.effects.createPlaceholder(s),p=s.cssClip(),f={clip:t.extend({},p)},g={clip:t.extend({},p)},m=[p[c[0]],p[c[1]]],_=s.queue().length;h&&(r=parseInt(h[1],10)/100*m[a?0:1]),f.clip[c[0]]=r,g.clip[c[0]]=r,g.clip[c[1]]=0,o&&(s.cssClip(g.clip),d&&d.css(t.effects.clipToBox(g)),g.clip=p),s.queue(function(i){d&&d.animate(t.effects.clipToBox(f),u,e.easing).animate(t.effects.clipToBox(g),u,e.easing),i()}).animate(f,u,e.easing).animate(g,u,e.easing).queue(i),t.effects.unshift(s,_,4)}),t.effects.define("highlight","show",function(e,i){var s=t(this),n={backgroundColor:s.css("backgroundColor")};"hide"===e.mode&&(n.opacity=0),t.effects.saveStyle(s),s.css({backgroundImage:"none",backgroundColor:e.color||"#ffff99"}).animate(n,{queue:!1,duration:e.duration,easing:e.easing,complete:i})}),t.effects.define("size",function(e,i){var s,n,o,a=t(this),r=["fontSize"],h=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],l=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],c=e.mode,u="effect"!==c,d=e.scale||"both",p=e.origin||["middle","center"],f=a.css("position"),g=a.position(),m=t.effects.scaledDimensions(a),_=e.from||m,v=e.to||t.effects.scaledDimensions(a,0);t.effects.createPlaceholder(a),"show"===c&&(o=_,_=v,v=o),n={from:{y:_.height/m.height,x:_.width/m.width},to:{y:v.height/m.height,x:v.width/m.width}},("box"===d||"both"===d)&&(n.from.y!==n.to.y&&(_=t.effects.setTransition(a,h,n.from.y,_),v=t.effects.setTransition(a,h,n.to.y,v)),n.from.x!==n.to.x&&(_=t.effects.setTransition(a,l,n.from.x,_),v=t.effects.setTransition(a,l,n.to.x,v))),("content"===d||"both"===d)&&n.from.y!==n.to.y&&(_=t.effects.setTransition(a,r,n.from.y,_),v=t.effects.setTransition(a,r,n.to.y,v)),p&&(s=t.effects.getBaseline(p,m),_.top=(m.outerHeight-_.outerHeight)*s.y+g.top,_.left=(m.outerWidth-_.outerWidth)*s.x+g.left,v.top=(m.outerHeight-v.outerHeight)*s.y+g.top,v.left=(m.outerWidth-v.outerWidth)*s.x+g.left),a.css(_),("content"===d||"both"===d)&&(h=h.concat(["marginTop","marginBottom"]).concat(r),l=l.concat(["marginLeft","marginRight"]),a.find("*[width]").each(function(){var i=t(this),s=t.effects.scaledDimensions(i),o={height:s.height*n.from.y,width:s.width*n.from.x,outerHeight:s.outerHeight*n.from.y,outerWidth:s.outerWidth*n.from.x},a={height:s.height*n.to.y,width:s.width*n.to.x,outerHeight:s.height*n.to.y,outerWidth:s.width*n.to.x};n.from.y!==n.to.y&&(o=t.effects.setTransition(i,h,n.from.y,o),a=t.effects.setTransition(i,h,n.to.y,a)),n.from.x!==n.to.x&&(o=t.effects.setTransition(i,l,n.from.x,o),a=t.effects.setTransition(i,l,n.to.x,a)),u&&t.effects.saveStyle(i),i.css(o),i.animate(a,e.duration,e.easing,function(){u&&t.effects.restoreStyle(i)})})),a.animate(v,{queue:!1,duration:e.duration,easing:e.easing,complete:function(){var e=a.offset();0===v.opacity&&a.css("opacity",_.opacity),u||(a.css("position","static"===f?"relative":f).offset(e),t.effects.saveStyle(a)),i()}})}),t.effects.define("scale",function(e,i){var s=t(this),n=e.mode,o=parseInt(e.percent,10)||(0===parseInt(e.percent,10)?0:"effect"!==n?0:100),a=t.extend(!0,{from:t.effects.scaledDimensions(s),to:t.effects.scaledDimensions(s,o,e.direction||"both"),origin:e.origin||["middle","center"]},e);e.fade&&(a.from.opacity=1,a.to.opacity=0),t.effects.effect.size.call(this,a,i)}),t.effects.define("puff","hide",function(e,i){var s=t.extend(!0,{},e,{fade:!0,percent:parseInt(e.percent,10)||150});t.effects.effect.scale.call(this,s,i)}),t.effects.define("pulsate","show",function(e,i){var s=t(this),n=e.mode,o="show"===n,r=o||"hide"===n,h=2*(e.times||5)+(r?1:0),l=e.duration/h,c=0,u=1,d=s.queue().length;for((o||!s.is(":visible"))&&(s.css("opacity",0).show(),c=1);u?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),(s=this.attr("id"))&&(o=(e=this.eq(0).parents().last()).add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return(!s||"static"!==e.css("position"))&&n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||0<=i)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.widget("ui.accordion",{version:"1.12.1",options:{active:0,animate:{},classes:{"ui-accordion-header":"ui-corner-top","ui-accordion-header-collapsed":"ui-corner-all","ui-accordion-content":"ui-corner-bottom"},collapsible:!1,event:"click",header:"> li > :first-child, > :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},hideProps:{borderTopWidth:"hide",borderBottomWidth:"hide",paddingTop:"hide",paddingBottom:"hide",height:"hide"},showProps:{borderTopWidth:"show",borderBottomWidth:"show",paddingTop:"show",paddingBottom:"show",height:"show"},_create:function(){var e=this.options;this.prevShow=this.prevHide=t(),this._addClass("ui-accordion","ui-widget ui-helper-reset"),this.element.attr("role","tablist"),e.collapsible||!1!==e.active&&null!=e.active||(e.active=0),this._processPanels(),e.active<0&&(e.active+=this.headers.length),this._refresh()},_getCreateEventData:function(){return{header:this.active,panel:this.active.length?this.active.next():t()}},_createIcons:function(){var e,i,s=this.options.icons;s&&(e=t(""),this._addClass(e,"ui-accordion-header-icon","ui-icon "+s.header),e.prependTo(this.headers),i=this.active.children(".ui-accordion-header-icon"),this._removeClass(i,s.header)._addClass(i,null,s.activeHeader)._addClass(this.headers,"ui-accordion-icons"))},_destroyIcons:function(){this._removeClass(this.headers,"ui-accordion-icons"),this.headers.children(".ui-accordion-header-icon").remove()},_destroy:function(){var t;this.element.removeAttr("role"),this.headers.removeAttr("role aria-expanded aria-selected aria-controls tabIndex").removeUniqueId(),this._destroyIcons(),t=this.headers.next().css("display","").removeAttr("role aria-hidden aria-labelledby").removeUniqueId(),"content"!==this.options.heightStyle&&t.css("height","")},_setOption:function(t,e){return"active"===t?void this._activate(e):("event"===t&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(e)),this._super(t,e),"collapsible"!==t||e||!1!==this.options.active||this._activate(0),void("icons"===t&&(this._destroyIcons(),e&&this._createIcons())))},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t),this._toggleClass(null,"ui-state-disabled",!!t),this._toggleClass(this.headers.add(this.headers.next()),null,"ui-state-disabled",!!t)},_keydown:function(e){if(!e.altKey&&!e.ctrlKey){var i=t.ui.keyCode,s=this.headers.length,n=this.headers.index(e.target),o=!1;switch(e.keyCode){case i.RIGHT:case i.DOWN:o=this.headers[(n+1)%s];break;case i.LEFT:case i.UP:o=this.headers[(n-1+s)%s];break;case i.SPACE:case i.ENTER:this._eventHandler(e);break;case i.HOME:o=this.headers[0];break;case i.END:o=this.headers[s-1]}o&&(t(e.target).attr("tabIndex",-1),t(o).attr("tabIndex",0),t(o).trigger("focus"),e.preventDefault())}},_panelKeyDown:function(e){e.keyCode===t.ui.keyCode.UP&&e.ctrlKey&&t(e.currentTarget).prev().trigger("focus")},refresh:function(){var e=this.options;this._processPanels(),!1===e.active&&!0===e.collapsible||!this.headers.length?(e.active=!1,this.active=t()):!1===e.active?this._activate(0):this.active.length&&!t.contains(this.element[0],this.active[0])?this.headers.length===this.headers.find(".ui-state-disabled").length?(e.active=!1,this.active=t()):this._activate(Math.max(0,e.active-1)):e.active=this.headers.index(this.active),this._destroyIcons(),this._refresh()},_processPanels:function(){var t=this.headers,e=this.panels;this.headers=this.element.find(this.options.header),this._addClass(this.headers,"ui-accordion-header ui-accordion-header-collapsed","ui-state-default"),this.panels=this.headers.next().filter(":not(.ui-accordion-content-active)").hide(),this._addClass(this.panels,"ui-accordion-content","ui-helper-reset ui-widget-content"),e&&(this._off(t.not(this.headers)),this._off(e.not(this.panels)))},_refresh:function(){var e,i=this.options,s=i.heightStyle,n=this.element.parent();this.active=this._findActive(i.active),this._addClass(this.active,"ui-accordion-header-active","ui-state-active")._removeClass(this.active,"ui-accordion-header-collapsed"),this._addClass(this.active.next(),"ui-accordion-content-active"),this.active.next().show(),this.headers.attr("role","tab").each(function(){var e=t(this),i=e.uniqueId().attr("id"),s=e.next(),n=s.uniqueId().attr("id");e.attr("aria-controls",n),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false","aria-expanded":"false",tabIndex:-1}).next().attr({"aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0}).next().attr({"aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._createIcons(),this._setupEvents(i.event),"fill"===s?(e=n.height(),this.element.siblings(":visible").each(function(){var i=t(this),s=i.css("position");"absolute"!==s&&"fixed"!==s&&(e-=i.outerHeight(!0))}),this.headers.each(function(){e-=t(this).outerHeight(!0)}),this.headers.next().each(function(){t(this).height(Math.max(0,e-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===s&&(e=0,this.headers.next().each(function(){var i=t(this).is(":visible");i||t(this).show(),e=Math.max(e,t(this).css("height","").height()),i||t(this).hide()}).height(e))},_activate:function(e){var i=this._findActive(e)[0];i!==this.active[0]&&(i=i||this.active[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return"number"==typeof e?this.headers.eq(e):t()},_setupEvents:function(e){var i={keydown:"_keydown"};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.headers.add(this.headers.next())),this._on(this.headers,i),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._hoverable(this.headers),this._focusable(this.headers)},_eventHandler:function(e){var i,s,n=this.options,o=this.active,a=t(e.currentTarget),r=a[0]===o[0],h=r&&n.collapsible,l=h?t():a.next(),c=o.next(),u={oldHeader:o,oldPanel:c,newHeader:h?t():a,newPanel:l};e.preventDefault(),r&&!n.collapsible||!1===this._trigger("beforeActivate",e,u)||(n.active=!h&&this.headers.index(a),this.active=r?t():a,this._toggle(u),this._removeClass(o,"ui-accordion-header-active","ui-state-active"),n.icons&&(i=o.children(".ui-accordion-header-icon"),this._removeClass(i,null,n.icons.activeHeader)._addClass(i,null,n.icons.header)),r||(this._removeClass(a,"ui-accordion-header-collapsed")._addClass(a,"ui-accordion-header-active","ui-state-active"),n.icons&&(s=a.children(".ui-accordion-header-icon"),this._removeClass(s,null,n.icons.header)._addClass(s,null,n.icons.activeHeader)),this._addClass(a.next(),"ui-accordion-content-active")))},_toggle:function(e){var i=e.newPanel,s=this.prevShow.length?this.prevShow:e.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=i,this.prevHide=s,this.options.animate?this._animate(i,s,e):(s.hide(),i.show(),this._toggleComplete(e)),s.attr({"aria-hidden":"true"}),s.prev().attr({"aria-selected":"false","aria-expanded":"false"}),i.length&&s.length?s.prev().attr({tabIndex:-1,"aria-expanded":"false"}):i.length&&this.headers.filter(function(){return 0===parseInt(t(this).attr("tabIndex"),10)}).attr("tabIndex",-1),i.attr("aria-hidden","false").prev().attr({"aria-selected":"true","aria-expanded":"true",tabIndex:0})},_animate:function(t,e,i){var s,n,o,a=this,r=0,h=t.css("box-sizing"),l=t.length&&(!e.length||t.index()",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]))&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var i=this.element.find(".ui-menu-item").removeAttr("role aria-disabled").children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=96<=e.keyCode&&e.keyCode<=105?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),(i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i).length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var i,s,n,o,a=this,r=this.options.icons.submenu,h=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=h.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),(i=h.add(this.element).find(this.options.items)).not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),o=(n=i.not(".ui-menu-item, .ui-menu-divider")).children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),(i=e.children(".ui-menu")).length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),n<0?this.activeMenu.scrollTop(o+n):a",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))i=s=e=!0;else{i=s=e=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}}},keypress:function(s){if(e)return e=!1,void((!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault());if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,void t.preventDefault()):void this._searchTimeout(t)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?void delete this.cancelBlur:(clearTimeout(this.searching),this.close(t),void this._change(t))}}),this._initSource(),this.menu=t("

    ",{class:"select2-results__options select2-results__options--nested"});m.append(i),g.append(h),g.append(m)}else this.template(b,c);return a.data(c,"data",b),c},c.prototype.bind=function(b,c){var d=this,e=b.id+"-results";this.$results.attr("id",e),b.on("results:all",function(a){d.clear(),d.append(a.data),b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("results:append",function(a){d.append(a.data),b.isOpen()&&d.setClasses()}),b.on("query",function(a){d.hideMessages(),d.showLoading(a)}),b.on("select",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("unselect",function(){b.isOpen()&&(d.setClasses(),d.highlightFirstItem())}),b.on("open",function(){d.$results.attr("aria-expanded","true"),d.$results.attr("aria-hidden","false"),d.setClasses(),d.ensureHighlightVisible()}),b.on("close",function(){d.$results.attr("aria-expanded","false"),d.$results.attr("aria-hidden","true"),d.$results.removeAttr("aria-activedescendant")}),b.on("results:toggle",function(){var a=d.getHighlightedResults();0!==a.length&&a.trigger("mouseup")}),b.on("results:select",function(){var a=d.getHighlightedResults();if(0!==a.length){var b=a.data("data");"true"==a.attr("aria-selected")?d.trigger("close",{}):d.trigger("select",{data:b})}}),b.on("results:previous",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),c=b.index(a);if(0!==c){var e=c-1;0===a.length&&(e=0);var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top,h=f.offset().top,i=d.$results.scrollTop()+(h-g);0===e?d.$results.scrollTop(0):h-g<0&&d.$results.scrollTop(i)}}),b.on("results:next",function(){var a=d.getHighlightedResults(),b=d.$results.find("[aria-selected]"),e=b.index(a)+1;if(!(e>=b.length)){var f=b.eq(e);f.trigger("mouseenter");var g=d.$results.offset().top+d.$results.outerHeight(!1),h=f.offset().top+f.outerHeight(!1),i=d.$results.scrollTop()+h-g;0===e?d.$results.scrollTop(0):gthis.$results.outerHeight()||g<0)&&this.$results.scrollTop(f)}},c.prototype.template=function(b,c){var d=this.options.get("templateResult"),e=this.options.get("escapeMarkup"),f=d(b,c);null==f?c.style.display="none":"string"==typeof f?c.innerHTML=e(f):a(c).append(f)},c}),b.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),b.define("select2/selection/base",["jquery","../utils","../keys"],function(a,b,c){function d(a,b){this.$element=a,this.options=b,d.__super__.constructor.call(this)}return b.Extend(d,b.Observable),d.prototype.render=function(){var b=a('');return this._tabindex=0,null!=this.$element.data("old-tabindex")?this._tabindex=this.$element.data("old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),b.attr("title",this.$element.attr("title")),b.attr("tabindex",this._tabindex),this.$selection=b},d.prototype.bind=function(a,b){var d=this,e=(a.id,a.id+"-results");this.container=a,this.$selection.on("focus",function(a){d.trigger("focus",a)}),this.$selection.on("blur",function(a){d._handleBlur(a)}),this.$selection.on("keydown",function(a){d.trigger("keypress",a),a.which===c.SPACE&&a.preventDefault()}),a.on("results:focus",function(a){d.$selection.attr("aria-activedescendant",a.data._resultId)}),a.on("selection:update",function(a){d.update(a.data)}),a.on("open",function(){d.$selection.attr("aria-expanded","true"),d.$selection.attr("aria-owns",e),d._attachCloseHandler(a)}),a.on("close",function(){d.$selection.attr("aria-expanded","false"),d.$selection.removeAttr("aria-activedescendant"),d.$selection.removeAttr("aria-owns"),d.$selection.focus(),d._detachCloseHandler(a)}),a.on("enable",function(){d.$selection.attr("tabindex",d._tabindex)}),a.on("disable",function(){d.$selection.attr("tabindex","-1")})},d.prototype._handleBlur=function(b){var c=this;window.setTimeout(function(){document.activeElement==c.$selection[0]||a.contains(c.$selection[0],document.activeElement)||c.trigger("blur",b)},1)},d.prototype._attachCloseHandler=function(b){a(document.body).on("mousedown.select2."+b.id,function(b){var d=a(b.target).closest(".select2");a(".select2.select2-container--open").each(function(){var b=a(this);this!=d[0]&&b.data("element").select2("close")})})},d.prototype._detachCloseHandler=function(b){a(document.body).off("mousedown.select2."+b.id)},d.prototype.position=function(a,b){b.find(".selection").append(a)},d.prototype.destroy=function(){this._detachCloseHandler(this.container)},d.prototype.update=function(a){throw new Error("The `update` method must be defined in child classes.")},d}),b.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(a,b,c,d){function e(){e.__super__.constructor.apply(this,arguments)}return c.Extend(e,b),e.prototype.render=function(){var a=e.__super__.render.call(this);return a.addClass("select2-selection--single"),a.html(''),a},e.prototype.bind=function(a,b){var c=this;e.__super__.bind.apply(this,arguments);var d=a.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",d),this.$selection.attr("aria-labelledby",d),this.$selection.on("mousedown",function(a){1===a.which&&c.trigger("toggle",{originalEvent:a})}),this.$selection.on("focus",function(a){}),this.$selection.on("blur",function(a){}),a.on("focus",function(b){a.isOpen()||c.$selection.focus()}),a.on("selection:update",function(a){c.update(a.data)})},e.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},e.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},e.prototype.selectionContainer=function(){return a("")},e.prototype.update=function(a){if(0!==a.length){var b=a[0],c=this.$selection.find(".select2-selection__rendered"),d=this.display(b,c);c.empty().append(d),c.prop("title",b.title||b.text)}else this.clear()},e}),b.define("select2/selection/multiple",["jquery","./base","../utils"],function(a,b,c){function d(a,b){d.__super__.constructor.apply(this,arguments)}return c.Extend(d,b),d.prototype.render=function(){var a=d.__super__.render.call(this);return a.addClass("select2-selection--multiple"),a.html('
      '),a},d.prototype.bind=function(b,c){var e=this;d.__super__.bind.apply(this,arguments),this.$selection.on("click",function(a){e.trigger("toggle",{originalEvent:a})}),this.$selection.on("click",".select2-selection__choice__remove",function(b){if(!e.options.get("disabled")){var f=a(this).parent().data("data");e.trigger("unselect",{originalEvent:b,data:f})}})},d.prototype.clear=function(){this.$selection.find(".select2-selection__rendered").empty()},d.prototype.display=function(a,b){var c=this.options.get("templateSelection");return this.options.get("escapeMarkup")(c(a,b))},d.prototype.selectionContainer=function(){return a('
    • ×
    • ')},d.prototype.update=function(a){if(this.clear(),0!==a.length){for(var b=[],d=0;d×
      ');d.data("data",c),this.$selection.find(".select2-selection__rendered").prepend(d)}},c}),b.define("select2/selection/search",["jquery","../utils","../keys"],function(a,b,c){function d(a,b,c){a.call(this,b,c)}return d.prototype.render=function(b){var c=a('');this.$searchContainer=c,this.$search=c.find("input");var d=b.call(this);return this._transferTabIndex(),d},d.prototype.bind=function(a,b,d){var e=this;a.call(this,b,d),b.on("open",function(){e.$search.trigger("focus")}),b.on("close",function(){e.$search.val(""),e.$search.removeAttr("aria-activedescendant"),e.$search.trigger("focus")}),b.on("enable",function(){e.$search.prop("disabled",!1),e._transferTabIndex()}),b.on("disable",function(){e.$search.prop("disabled",!0)}),b.on("focus",function(a){e.$search.trigger("focus")}),b.on("results:focus",function(a){e.$search.attr("aria-activedescendant",a.id)}),this.$selection.on("focusin",".select2-search--inline",function(a){e.trigger("focus",a)}),this.$selection.on("focusout",".select2-search--inline",function(a){e._handleBlur(a)}),this.$selection.on("keydown",".select2-search--inline",function(a){if(a.stopPropagation(),e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented(),a.which===c.BACKSPACE&&""===e.$search.val()){var b=e.$searchContainer.prev(".select2-selection__choice");if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:b.term,params:b}}):a.call(this,b,c)},a}),b.define("select2/data/maximumSelectionLength",[],function(){function a(a,b,c){this.maximumSelectionLength=c.get("maximumSelectionLength"),a.call(this,b,c)}return a.prototype.query=function(a,b,c){var d=this;this.current(function(e){var f=null!=e?e.length:0;0=d.maximumSelectionLength?d.trigger("results:message",{message:"maximumSelected",args:{maximum:d.maximumSelectionLength}}):a.call(d,b,c)})},a}),b.define("select2/dropdown",["jquery","./utils"],function(a,b){function c(a,b){this.$element=a,this.options=b,c.__super__.constructor.call(this)}return b.Extend(c,b.Observable),c.prototype.render=function(){var b=a('');return b.attr("dir",this.options.get("dir")),this.$dropdown=b},c.prototype.bind=function(){},c.prototype.position=function(a,b){},c.prototype.destroy=function(){this.$dropdown.remove()},c}),b.define("select2/dropdown/search",["jquery","../utils"],function(a,b){function c(){}return c.prototype.render=function(b){var c=b.call(this),d=a('');return this.$searchContainer=d,this.$search=d.find("input"),c.prepend(d),c},c.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),this.$search.on("keydown",function(a){e.trigger("keypress",a),e._keyUpPrevented=a.isDefaultPrevented()}),this.$search.on("input",function(b){a(this).off("keyup")}),this.$search.on("keyup input",function(a){e.handleSearch(a)}),c.on("open",function(){e.$search.attr("tabindex",0),e.$search.focus(),window.setTimeout(function(){e.$search.focus()},0)}),c.on("close",function(){e.$search.attr("tabindex",-1),e.$search.val("")}),c.on("focus",function(){c.isOpen()||e.$search.focus()}),c.on("results:all",function(a){null!=a.query.term&&""!==a.query.term||(e.showSearch(a)?e.$searchContainer.removeClass("select2-search--hide"):e.$searchContainer.addClass("select2-search--hide"))})},c.prototype.handleSearch=function(a){if(!this._keyUpPrevented){var b=this.$search.val();this.trigger("query",{term:b})}this._keyUpPrevented=!1},c.prototype.showSearch=function(a,b){return!0},c}),b.define("select2/dropdown/hidePlaceholder",[],function(){function a(a,b,c,d){this.placeholder=this.normalizePlaceholder(c.get("placeholder")),a.call(this,b,c,d)}return a.prototype.append=function(a,b){b.results=this.removePlaceholder(b.results),a.call(this,b)},a.prototype.normalizePlaceholder=function(a,b){return"string"==typeof b&&(b={id:"",text:b}),b},a.prototype.removePlaceholder=function(a,b){for(var c=b.slice(0),d=b.length-1;0<=d;d--){var e=b[d];this.placeholder.id===e.id&&c.splice(d,1)}return c},a}),b.define("select2/dropdown/infiniteScroll",["jquery"],function(a){function b(a,b,c,d){this.lastParams={},a.call(this,b,c,d),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return b.prototype.append=function(a,b){this.$loadingMore.remove(),this.loading=!1,a.call(this,b),this.showLoadingMore(b)&&this.$results.append(this.$loadingMore)},b.prototype.bind=function(b,c,d){var e=this;b.call(this,c,d),c.on("query",function(a){e.lastParams=a,e.loading=!0}),c.on("query:append",function(a){e.lastParams=a,e.loading=!0}),this.$results.on("scroll",function(){var b=a.contains(document.documentElement,e.$loadingMore[0]);!e.loading&&b&&e.$results.offset().top+e.$results.outerHeight(!1)+50>=e.$loadingMore.offset().top+e.$loadingMore.outerHeight(!1)&&e.loadMore()})},b.prototype.loadMore=function(){this.loading=!0;var b=a.extend({},{page:1},this.lastParams);b.page++,this.trigger("query:append",b)},b.prototype.showLoadingMore=function(a,b){return b.pagination&&b.pagination.more},b.prototype.createLoadingMore=function(){var b=a('
    • '),c=this.options.get("translations").get("loadingMore");return b.html(c(this.lastParams)),b},b}),b.define("select2/dropdown/attachBody",["jquery","../utils"],function(a,b){function c(b,c,d){this.$dropdownParent=d.get("dropdownParent")||a(document.body),b.call(this,c,d)}return c.prototype.bind=function(a,b,c){var d=this,e=!1;a.call(this,b,c),b.on("open",function(){d._showDropdown(),d._attachPositioningHandler(b),e||(e=!0,b.on("results:all",function(){d._positionDropdown(),d._resizeDropdown()}),b.on("results:append",function(){d._positionDropdown(),d._resizeDropdown()}))}),b.on("close",function(){d._hideDropdown(),d._detachPositioningHandler(b)}),this.$dropdownContainer.on("mousedown",function(a){a.stopPropagation()})},c.prototype.destroy=function(a){a.call(this),this.$dropdownContainer.remove()},c.prototype.position=function(a,b,c){b.attr("class",c.attr("class")),b.removeClass("select2"),b.addClass("select2-container--open"),b.css({position:"absolute",top:-999999}),this.$container=c},c.prototype.render=function(b){var c=a(""),d=b.call(this);return c.append(d),this.$dropdownContainer=c},c.prototype._hideDropdown=function(a){this.$dropdownContainer.detach()},c.prototype._attachPositioningHandler=function(c,d){var e=this,f="scroll.select2."+d.id,g="resize.select2."+d.id,h="orientationchange.select2."+d.id,i=this.$container.parents().filter(b.hasScroll);i.each(function(){a(this).data("select2-scroll-position",{x:a(this).scrollLeft(),y:a(this).scrollTop()})}),i.on(f,function(b){var c=a(this).data("select2-scroll-position");a(this).scrollTop(c.y)}),a(window).on(f+" "+g+" "+h,function(a){e._positionDropdown(),e._resizeDropdown()})},c.prototype._detachPositioningHandler=function(c,d){var e="scroll.select2."+d.id,f="resize.select2."+d.id,g="orientationchange.select2."+d.id;this.$container.parents().filter(b.hasScroll).off(e),a(window).off(e+" "+f+" "+g)},c.prototype._positionDropdown=function(){var b=a(window),c=this.$dropdown.hasClass("select2-dropdown--above"),d=this.$dropdown.hasClass("select2-dropdown--below"),e=null,f=this.$container.offset();f.bottom=f.top+this.$container.outerHeight(!1);var g={height:this.$container.outerHeight(!1)};g.top=f.top,g.bottom=f.top+g.height;var h_height=this.$dropdown.outerHeight(!1),i_top=b.scrollTop(),i_bottom=b.scrollTop()+b.height(),j=i_topf.bottom+h_height,l={left:f.left,top:g.bottom},m=this.$dropdownParent;"static"===m.css("position")&&(m=m.offsetParent());var n=m.offset();l.top-=n.top,l.left-=n.left,c||d||(e="below"),k||!j||c?!j&&k&&c&&(e="below"):e="above",("above"==e||c&&"below"!==e)&&(l.top=g.top-n.top-h_height),null!=e&&(this.$dropdown.removeClass("select2-dropdown--below select2-dropdown--above").addClass("select2-dropdown--"+e),this.$container.removeClass("select2-container--below select2-container--above").addClass("select2-container--"+e)),this.$dropdownContainer.css(l)},c.prototype._resizeDropdown=function(){var a={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(a.minWidth=a.width,a.position="relative",a.width="auto"),this.$dropdown.css(a)},c.prototype._showDropdown=function(a){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},c}),b.define("select2/dropdown/minimumResultsForSearch",[],function(){function b(a,b,c,d){this.minimumResultsForSearch=c.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),a.call(this,b,c,d)}return b.prototype.showSearch=function(b,c){return!(function a(b){for(var c=0,d=0;d
      ');return b.attr("dir",this.options.get("dir")),this.$container=b,this.$container.addClass("select2-container--"+this.options.get("theme")),b.data("element",this.$element),b},e}),b.define("select2/compat/utils",["jquery"],function(a){return{syncCssClasses:function(b,c,d){var e,f,g=[];(e=a.trim(b.attr("class")))&&a((e=""+e).split(/\s+/)).each(function(){0===this.indexOf("select2-")&&g.push(this)}),(e=a.trim(c.attr("class")))&&a((e=""+e).split(/\s+/)).each(function(){0!==this.indexOf("select2-")&&null!=(f=d(this))&&g.push(f)}),b.attr("class",g.join(" "))}}}),b.define("select2/compat/containerCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("containerCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptContainerCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("containerCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/dropdownCss",["jquery","./utils"],function(a,b){function c(a){return null}function d(){}return d.prototype.render=function(d){var e=d.call(this),f=this.options.get("dropdownCssClass")||"";a.isFunction(f)&&(f=f(this.$element));var g=this.options.get("adaptDropdownCssClass");if(g=g||c,-1!==f.indexOf(":all:")){f=f.replace(":all:","");var h=g;g=function(a){var b=h(a);return null!=b?b+" "+a:a}}var i=this.options.get("dropdownCss")||{};return a.isFunction(i)&&(i=i(this.$element)),b.syncCssClasses(e,this.$element,g),e.css(i),e.addClass(f),e},d}),b.define("select2/compat/initSelection",["jquery"],function(a){function b(a,b,c){c.get("debug")&&window.console&&console.warn&&console.warn("Select2: The `initSelection` option has been deprecated in favor of a custom data adapter that overrides the `current` method. This method is now called multiple times instead of a single time when the instance is initialized. Support will be removed for the `initSelection` option in future versions of Select2"),this.initSelection=c.get("initSelection"),this._isInitialized=!1,a.call(this,b,c)}return b.prototype.current=function(b,c){var d=this;this._isInitialized?b.call(this,c):this.initSelection.call(null,this.$element,function(b){d._isInitialized=!0,a.isArray(b)||(b=[b]),c(b)})},b}),b.define("select2/compat/inputData",["jquery"],function(a){function b(a,b,c){this._currentData=[],this._valueSeparator=c.get("valueSeparator")||",","hidden"===b.prop("type")&&c.get("debug")&&console&&console.warn&&console.warn("Select2: Using a hidden input with Select2 is no longer supported and may stop working in the future. It is recommended to use a `','',"
      ",""].join(""))}}(Mirador),function($){$.MainMenu=function(options){jQuery.extend(!0,this,{element:null,mainMenuHeight:null,mainMenuWidth:null,windowOptionsMenu:null,loadWindow:null,clearLocalStorage:"",viewerCls:"mirador-viewer",mainMenuBarCls:"mirador-main-menu-bar",mainMenuCls:"mirador-main-menu",windowOptionsMenuCls:"mirador-window-options-menu",clearLocalStorageCls:"clear-local-storage",clearLocalStorageDialogCls:"mirador-main-menu-clear-local-storage",collectionsListingCls:"mirador-listing-collections",state:null,eventEmitter:null},options),this.element=this.element||jQuery("
      "),this.init()},$.MainMenu.prototype={init:function(){this.element.addClass(this.mainMenuBarCls).appendTo(this.appendTo),this.element.append(this.template({mainMenuCls:this.mainMenuCls,showBookmark:this.state.getStateProperty("mainMenuSettings").buttons.bookmark,showLayout:this.state.getStateProperty("mainMenuSettings").buttons.layout,showOptions:this.state.getStateProperty("mainMenuSettings").buttons.options,showFullScreenViewer:this.state.getStateProperty("mainMenuSettings").buttons.fullScreenViewer,userButtons:this.state.getStateProperty("mainMenuSettings").userButtons,userLogo:this.state.getStateProperty("mainMenuSettings").userLogo})),this.element.find(".mainmenu-button").each(function(){jQuery(this).qtip({content:{text:jQuery(this).attr("title")},position:{my:"top center",at:"bottom center"},style:{classes:"qtip-dark qtip-shadow qtip-rounded"}})}),this.listenForActions(),this.bindEvents()},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("MAINMENU_FULLSCREEN_BUTTON",function(event){var fullScreenButton=_this.element.find(".fullscreen-viewer span");fullScreenButton.hasClass("fa-expand")?fullScreenButton.removeClass("fa-expand").addClass("fa-compress"):fullScreenButton.removeClass("fa-compress").addClass("fa-expand")})},bindEvents:function(){var _this=this;this.element.find(".change-layout").on("click",function(){_this.eventEmitter.publish("TOGGLE_WORKSPACE_PANEL"),_this.element.find(".bookmark-workspace").removeClass("active"),jQuery(this).hasClass("active")?jQuery(this).removeClass("active"):jQuery(this).addClass("active")}),this.element.find(".bookmark-workspace").on("click",function(){_this.eventEmitter.publish("TOGGLE_BOOKMARK_PANEL"),_this.element.find(".change-layout").removeClass("active"),jQuery(this).hasClass("active")?jQuery(this).removeClass("active"):jQuery(this).addClass("active")}),this.element.find(".window-options").on("click",function(){}),this.element.find(".fullscreen-viewer").on("click",function(){_this.eventEmitter.publish("TOGGLE_FULLSCREEN")})},template:$.Handlebars.compile(["{{#if userLogo}}",'","{{/if}}",'","{{#if userButtons}}","{{userbtns userButtons}}","{{/if}}"].join(""))};var processUserButtons=function(btns){for(var output=[],btns_len=btns.length,i=0;i"),$a=jQuery("");try{if(btn.li_attributes&&$li.attr(btn.li_attributes),!btn.label)throw"userButtons must have labels";return $a.text(btn.label),btn.iconClass&&$a.prepend(' '),btn.attributes&&$a.attr(btn.attributes),$li.append($a),btn.sublist&&($sub_ul=jQuery("
      "].join(""))}}(Mirador),function($){$.WorkspacePanel=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,workspace:null,state:null,eventEmitter:null},options),this.init()},$.WorkspacePanel.prototype={init:function(){var templateData={rows:$.layoutDescriptionFromGridString(this.state.getStateProperty("workspacePanelSettings").maxColumns+"x"+this.state.getStateProperty("workspacePanelSettings").maxRows).children.map(function(column,rowIndex){return column.columns=column.children.map(function(row,columnIndex){return row.gridString=rowIndex+1+"x"+(columnIndex+1),row}),column})};this.element=jQuery(this.template(templateData)).appendTo(this.appendTo);var backgroundImage=this.state.getStateProperty("buildPath")+this.state.getStateProperty("imagesPath")+"debut_dark.png";this.element.css("background-image","url("+backgroundImage+")").css("background-repeat","repeat"),this.bindEvents(),this.listenForActions()},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("workspacePanelVisible.set",function(_,stateValue){_this.onPanelVisible(_,stateValue)})},bindEvents:function(){var _this=this;_this.element.find(".grid-item").on("click",function(){var gridString=jQuery(this).data("gridstring");_this.select(gridString)}),_this.element.find(".grid-item").on("mouseover",function(){var gridString=jQuery(this).data("gridstring");_this.hover(gridString)}),_this.element.find(".select-grid").on("mouseout",function(){_this.reset()})},select:function(gridString){var layoutDescription=$.layoutDescriptionFromGridString(gridString);this.eventEmitter.publish("RESET_WORKSPACE_LAYOUT",{layoutDescription:layoutDescription}),this.eventEmitter.publish("TOGGLE_WORKSPACE_PANEL")},hover:function(gridString){var highestRow=gridString.charAt(0),highestColumn=gridString.charAt(2),gridItems=this.element.find(".grid-item");gridItems.removeClass("hovered"),gridItems.filter(function(index){var gridString=jQuery(this).data("gridstring");return gridString.charAt(0)<=highestRow&&gridString.charAt(2)<=highestColumn}).addClass("hovered"),this.element.find(".grid-instructions").hide(),this.element.find(".grid-text").text(gridString).show()},reset:function(){this.element.find(".grid-item").removeClass("hovered"),this.element.find(".grid-instructions").show(),this.element.find(".grid-text").hide()},hide:function(){jQuery(this.element).hide({effect:"fade",duration:160,easing:"easeOutCubic"})},show:function(){jQuery(this.element).show({effect:"fade",duration:160,easing:"easeInCubic",complete:function(){jQuery(this).css("display","block")}})},onPanelVisible:function(_,stateValue){stateValue?this.show():this.hide()},template:$.Handlebars.compile(['
      ','

      {{t "changeLayout"}}

      ','

      ','

      {{t "selectGrid"}}

      ','
      ',"{{#each rows}}",'
      ',"{{#each columns}}",'','
      ',"
      ","{{/each}}","
      ","{{/each}}","
      ","
      "].join(""))}}(Mirador),function($){$.Manifest=function(manifestUri,location,manifestContent){manifestContent?(jQuery.extend(!0,this,{jsonLd:null,location:location,uri:manifestUri,request:null}),this.initFromManifestContent(manifestContent)):-1!==manifestUri.indexOf("info.json")?(jQuery.extend(!0,this,{jsonLd:null,location:location,uri:manifestUri,request:null}),this.initFromInfoJson(manifestUri)):(jQuery.extend(!0,this,{jsonLd:null,location:location,uri:manifestUri,request:null}),this.init(manifestUri))},$.Manifest.prototype={init:function(manifestUri){var _this=this;this.request=jQuery.ajax({url:manifestUri,dataType:"json",async:!0}),this.request.done(function(jsonLd){_this.jsonLd=jsonLd})},buildCanvasMap:function(){var _this=this;this.canvasMap={},this.getCanvases()&&this.getCanvases().forEach(function(canvas){_this.canvasMap[canvas["@id"]]=canvas})},initFromInfoJson:function(infoJsonUrl){var _this=this;this.request=jQuery.ajax({url:infoJsonUrl,dataType:"json",async:!0}),this.request.done(function(jsonLd){_this.jsonLd=_this.generateInfoWrapper(jsonLd)})},initFromManifestContent:function(manifestContent){var _this=this;this.request=jQuery.Deferred(),this.request.done(function(jsonLd){_this.jsonLd=jsonLd}),_this.request.resolve(manifestContent)},getThumbnailForCanvas:function(canvas,width){var service,thumbnailUrl,version="1.1",compliance=-1;if(width=parseInt(width,10),canvas.hasOwnProperty("thumbnail"))"string"==typeof canvas.thumbnail?thumbnailUrl=canvas.thumbnail:canvas.thumbnail.hasOwnProperty("service")?((service=canvas.thumbnail.service).hasOwnProperty("profile")&&(compliance=$.Iiif.getComplianceLevelFromProfile(service.profile)),0===compliance?thumbnailUrl=canvas.thumbnail["@id"]:(service.hasOwnProperty("@context")&&(version=$.Iiif.getVersionFromContext(service["@context"])),thumbnailUrl=$.Iiif.makeUriWithWidth(service["@id"],width,version))):thumbnailUrl=canvas.thumbnail["@id"];else{var resource=canvas.images[0].resource;(service=resource.default?resource.default.service:resource.service).hasOwnProperty("@context")&&(version=$.Iiif.getVersionFromContext(service["@context"])),thumbnailUrl=$.Iiif.makeUriWithWidth(service["@id"],width,version)}return thumbnailUrl},getVersion:function(){return{"http://www.shared-canvas.org/ns/context.json":"1","http://iiif.io/api/presentation/1/context.json":"1","http://iiif.io/api/presentation/2/context.json":"2","http://iiif.io/api/presentation/2.1/context.json":"2.1"}[this.jsonLd["@context"]]},getCanvases:function(){return this.jsonLd.sequences&&this.jsonLd.sequences[0].canvases},getAnnotationsListUrls:function(canvasId){var canvas=jQuery.grep(this.getCanvases(),function(canvas,index){return canvas["@id"]===canvasId})[0],annotationsListUrls=[];if(canvas&&canvas.otherContent)for(var i=0;i',"",""].join("")),viewerTemplate:$.Handlebars.compile(['
      ',"{{#each annotations}}",'
      ','
      ','{{#if showUpdate}}{{t "edit"}}{{/if}}','{{#if showDelete}}{{t "delete"}}{{/if}}',"
      ",'
      ','{{#if username}}

      {{username}}:

      {{/if}}',"

      {{{annoText}}}

      ","
      ",'
      ',"{{#each tags}}",'{{this}}',"{{/each}}","
      ","
      ","{{/each}}","
      "].join(""))}}(Mirador),function($){$.CatchEndpoint=function(options){jQuery.extend(this,{token:null,prefix:null,params:"",dfd:null,context_id:"None",collection_id:"None",userid:"test@mirador.org",username:"mirador-test",annotationsList:[],annotationsListCatch:null,windowID:null,eventEmitter:null},options),this.init()},$.CatchEndpoint.prototype={init:function(){this.catchOptions={user:{id:this.userid,name:this.username},permissions:{read:[],update:[this.userid],delete:[this.userid],admin:[this.userid]}}},set:function(prop,value,options){options?this[options.parent][prop]=value:this[prop]=value},search:function(options,successCallback,errorCallback){var _this=this;this.annotationsList=[],jQuery.ajax({url:this.prefix+"/search"+this.params,type:"GET",dataType:"json",headers:{"x-annotator-auth-token":this.token},data:{uri:options.uri,userid:options.userid?options.userid:void 0,username:options.username?options.username:void 0,text:options.text?options.text:void 0,tag:options.tag?options.tag:void 0,parentid:options.parentid?options.parentid:void 0,contextId:_this.context_id,collectionId:_this.collection_id,media:options.media?options.media:"image",limit:options.limit?options.limit:-1},contentType:"application/json; charset=utf-8",success:function(data){"function"==typeof successCallback?successCallback(data):(_this.annotationsListCatch=data.rows,jQuery.each(_this.annotationsListCatch,function(index,value){_this.annotationsList.push(_this.getAnnotationInOA(value))}),_this.dfd.resolve(!0),_this.eventEmitter.publish("catchAnnotationsLoaded."+_this.windowID,_this.annotationsListCatch))},error:function(){"function"==typeof errorCallback?errorCallback():console.log("There was an error searching this endpoint")}})},deleteAnnotation:function(annotationID,successCallback,errorCallback){var _this=this;jQuery.ajax({url:this.prefix+"/destroy/"+annotationID+this.params,type:"DELETE",dataType:"json",headers:{"x-annotator-auth-token":this.token},contentType:"application/json; charset=utf-8",success:function(data){"function"==typeof successCallback&&successCallback(),_this.eventEmitter.publish("catchAnnotationDeleted."+_this.windowID,annotationID)},error:function(){"function"==typeof errorCallback&&errorCallback()}})},update:function(oaAnnotation,successCallback,errorCallback){var annotations=this.getAnnotationInEndpoint(oaAnnotation),_this=this;annotations.forEach(function(annotation){var annotationID=annotation.id;jQuery.ajax({url:_this.prefix+"/update/"+annotationID+_this.params,type:"POST",dataType:"json",headers:{"x-annotator-auth-token":_this.token},data:JSON.stringify(annotation),contentType:"application/json; charset=utf-8",success:function(data){"function"==typeof successCallback&&successCallback(_this.getAnnotationInOA(data)),_this.eventEmitter.publish("catchAnnotationUpdated."+_this.windowID,annotation)},error:function(){"function"==typeof errorCallback&&errorCallback()}})})},create:function(oaAnnotation,successCallback,errorCallback){var _this=this;this.getAnnotationInEndpoint(oaAnnotation).forEach(function(annotation){_this.createCatchAnnotation(annotation,successCallback,errorCallback)})},createCatchAnnotation:function(catchAnnotation,successCallback,errorCallback){var _this=this;jQuery.ajax({url:this.prefix+"/create"+this.params,type:"POST",dataType:"json",headers:{"x-annotator-auth-token":this.token},data:JSON.stringify(catchAnnotation),contentType:"application/json; charset=utf-8",success:function(data){"function"==typeof successCallback&&successCallback(_this.getAnnotationInOA(data)),_this.eventEmitter.publish("catchAnnotationCreated."+_this.windowID,data)},error:function(){"function"==typeof errorCallback&&errorCallback()}})},userAuthorize:function(action,annotation){if(this.roles&&(-1!==this.roles.indexOf("Instructor")||-1!==this.roles.indexOf("Administrator")))return!0;if(annotation.permissions){var permissionUserIds=annotation.permissions[action]||[];return 0===permissionUserIds.length||-1!==permissionUserIds.indexOf(this.userid)}return!annotation.user||this.userid===annotation.user.userid},getAnnotationInOA:function(annotation){var id,on,annotatedBy,value,motivation=[],resource=[];(id=annotation.id,0currentCanvasModel.getBounds().width&&(mousePosition.x=currentCanvasModel.getBounds().width),mousePosition.y<0&&(mousePosition.y=0),mousePosition.y>currentCanvasModel.getBounds().height&&(mousePosition.y=currentCanvasModel.getBounds().height),this.horizontallyFlipped&&(mousePosition.x=currentCanvasModel.getBounds().width-mousePosition.x),mousePosition},adjustDeltaForShape:function(lastPoint,currentPoint,delta,bounds){var originWindow=this.state.getWindowObjectById(this.windowId),currentCanvasModel=originWindow.canvases[originWindow.canvasID];return lastPoint.xcurrentCanvasModel.getBounds().width&&(delta.x=currentCanvasModel.getBounds().width-(bounds.x+bounds.width)):bounds.x<0&&(delta.x=Math.abs(bounds.x)),this.horizontallyFlipped&&(delta.x=-delta.x),lastPoint.ycurrentCanvasModel.getBounds().height&&(delta.y=currentCanvasModel.getBounds().height-(bounds.y+bounds.height)):bounds.y<0&&(delta.y=Math.abs(bounds.y)),delta},onMouseUp:function(event){this.overlay.disabled||(event.stopPropagation(),this.overlay.currentTool&&this.overlay.currentTool.onMouseUp(event,this.overlay))},onMouseDrag:function(event){if(this.overlay.disabled){var absolutePoint={x:event.event.clientX,y:event.event.clientY};this.overlay.eventEmitter.publish("updateTooltips."+this.overlay.windowId,[event.point,absolutePoint])}else if(event.stopPropagation(),this.overlay.currentTool){if("Freehand"===this.overlay.currentTool.name&&"create"===this.overlay.mode)event.point=this.overlay.getMousePositionInImage(event.point),event.delta=event.point-event.lastPoint;else if(this.overlay.path){var bounds=this.overlay.path.bounds;event.delta=this.overlay.adjustDeltaForShape(event.lastPoint,event.point,event.delta,bounds)}this.overlay.currentTool.onMouseDrag(event,this.overlay)}this.overlay.paperScope.view.draw()},onMouseMove:function(event){if(this.overlay.disabled){var absolutePoint={x:event.event.clientX,y:event.event.clientY};this.overlay.eventEmitter.publish("updateTooltips."+this.overlay.windowId,[event.point,absolutePoint])}else this.overlay.paperScope.project.hitTest(event.point,this.overlay.hitOptions)?this.overlay.eventEmitter.publish("POINTER_CURSOR."+this.overlay.windowId):this.overlay.currentTool&&!this.overlay.path?this.overlay.eventEmitter.publish("CROSSHAIR_CURSOR."+this.overlay.windowId):this.overlay.eventEmitter.publish("DEFAULT_CURSOR."+this.overlay.windowId),event.stopPropagation(),this.overlay.currentTool&&this.overlay.currentTool.onMouseMove(event,this.overlay);this.overlay.paperScope.view.draw()},onMouseDown:function(event){if(!this.overlay.disabled){event.stopPropagation();var time=(new Date).getTime();if(time-this.overlay.latestMouseDownTime"}else{this.updateSelection(!1,shapes[0]),shapes[0].data.fixedSize&&this.fitFixedSizeShapes(shapes[0]);var annoSingle=shapes[0].data.annotation;shapes[0].data.annotation=null,svg+=shapes[0].exportSVG({asString:!0}),shapes[0].data.annotation=annoSingle}return svg+=""},onDrawFinish:function(){var shape=this.path;if(shape){this.inEditOrCreateMode=!0,this.hoveredPath&&this.updateSelection(!1,this.hoveredPath);var newlyCreatedStrokeFactor=this.drawingToolsSettings.newlyCreatedShapeStrokeWidthFactor||5;if(shape.data.newlyCreatedStrokeFactor=newlyCreatedStrokeFactor,shape.data.newlyCreated=!0,shape.strokeWidth=shape.data.strokeWidth*newlyCreatedStrokeFactor,this.hoveredPath=shape,this.segment=null,this.path=null,this.mode="",this.draftPaths.push(shape),shape.data.editable=!0,this.updateSelection(!0,this.hoveredPath),void 0!==this.annoTooltip&&this.annoTooltip||(this.annoTooltip=new $.AnnotationTooltip({targetElement:jQuery(this.canvas).parents(".mirador-osd"),state:this.state,eventEmitter:this.eventEmitter,windowId:this.windowId})),this.availableExternalCommentsPanel)this.eventEmitter.publish("annotationShapeCreated."+this.windowId,[this,shape]);else{var _this=this;void 0!==this.annoEditorVisible&&this.annoEditorVisible||(this.annoTooltip.showEditor({annotation:{},onSaveClickCheck:function(){return _this.draftPaths.length},onAnnotationCreated:function(oaAnno){_this.eventEmitter.publish("onAnnotationCreated."+_this.windowId,[oaAnno])}}),_this.annoEditorVisible=!0)}}},onEditFinish:function(){var _this=this;jQuery.each(this.draftPaths,function(index,value){_this.path.name===value.name&&(_this.draftPaths[index]=_this.path)})},clearDraftData:function(){for(var idx=0;idx{{#if content}}{{content}}{{/if}}','"].join(""))},$.Handlebars.registerHelper("ifContains",function(array,value,options){return-1<(array=array instanceof Array?array:[array]).indexOf(value)?options.fn(this):""})}(Mirador),function($){$.Slot=function(options){jQuery.extend(!0,this,{workspaceSlotCls:"slot",slotID:null,layoutAddress:null,focused:null,appendTo:null,window:null,windowElement:null,state:null,eventEmitter:null},options),this.init()},$.Slot.prototype={init:function(){this.events=[],this.element=jQuery(this.template({workspaceSlotCls:this.workspaceSlotCls,slotID:this.slotId})),this.element.appendTo(this.appendTo),this.bindEvents(),this.listenForActions()},listenForActions:function(){var _this=this;this.events=[_this.eventEmitter.subscribe("slotRemoved",function(event,slot){_this.slotID===slot.slotID&&_this.clearSlot()}),_this.eventEmitter.subscribe("layoutChanged",function(event,layoutRoot){_this.window&&(_this.window.slotAddress=_this.layoutAddress,_this.eventEmitter.publish("windowSlotAddressUpdated",{id:_this.window.id,slotAddress:_this.window.slotAddress}))}),_this.eventEmitter.subscribe("HIDE_REMOVE_SLOT",function(event){_this.element.find(".remove-slot-option").hide(),_this.window&&_this.eventEmitter.publish("HIDE_REMOVE_OBJECT."+_this.window.id)}),_this.eventEmitter.subscribe("SHOW_REMOVE_SLOT",function(event){_this.element.find(".remove-slot-option").show(),_this.window&&_this.eventEmitter.publish("SHOW_REMOVE_OBJECT."+_this.window.id)}),_this.eventEmitter.subscribe("ADD_ITEM_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.addItem()}),_this.eventEmitter.subscribe("REMOVE_SLOT_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.eventEmitter.publish("REMOVE_NODE",_this)}),_this.eventEmitter.subscribe("SPLIT_RIGHT_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.eventEmitter.publish("SPLIT_RIGHT",_this)}),_this.eventEmitter.subscribe("SPLIT_LEFT_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.eventEmitter.publish("SPLIT_LEFT",_this)}),_this.eventEmitter.subscribe("SPLIT_DOWN_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.eventEmitter.publish("SPLIT_DOWN",_this)}),_this.eventEmitter.subscribe("SPLIT_UP_FROM_WINDOW",function(event,id){_this.window&&_this.window.id===id&&_this.eventEmitter.publish("SPLIT_UP",_this)})]},bindEvents:function(){var _this=this,dropTarget=this.element.find(".dropMask");this.element.find(".addItemLink").on("click",function(){_this.addItem()}),this.element.find(".remove-slot-option").on("click",function(){_this.eventEmitter.publish("REMOVE_NODE",_this)}),this.element.on("dragover",function(e){e.preventDefault(),dropTarget.show()}),dropTarget.on("dragenter",function(e){e.preventDefault(),_this.element.addClass("draggedOver")}),dropTarget.on("dragleave",function(e){e.preventDefault(),_this.element.removeClass("draggedOver"),dropTarget.hide()}),this.element.on("drop",function(e){_this.dropItem(e)})},dropItem:function(e){var _this=this;e.preventDefault();var text_url=e.originalEvent.dataTransfer.getData("text/plain");text_url?_this.handleDrop(text_url):e.originalEvent.dataTransfer.items[0].getAsString(function(url){_this.handleDrop(url)})},handleDrop:function(url){var _this=this;url=url||text_url;var windowConfig,manifestUrl=$.getQueryParams(url).manifest||url,collectionUrl=$.getQueryParams(url).collection,canvasId=$.getQueryParams(url).canvas,imageInfoUrl=$.getQueryParams(url).image;void 0!==_this.state.getStateProperty("manifests")[manifestUrl]?(windowConfig={manifest:_this.state.getStateProperty("manifests")[manifestUrl],slotAddress:_this.getAddress()},canvasId&&(windowConfig.canvasID=canvasId,windowConfig.viewType="ImageView"),_this.eventEmitter.publish("ADD_WINDOW",windowConfig)):void 0!==imageInfoUrl?_this.state.getStateProperty("manifests")[imageInfoUrl]||_this.eventEmitter.publish("ADD_MANIFEST_FROM_URL",[imageInfoUrl,"(Added from URL)"]):void 0!==collectionUrl?(jQuery.getJSON(collectionUrl).done(function(data,status,jqXHR){data.hasOwnProperty("manifests")?jQuery.each(data.manifests,function(ci,mfst){_this.state.getStateProperty("manifests")[imageInfoUrl]||_this.eventEmitter.publish("ADD_MANIFEST_FROM_URL",[mfst["@id"],"(Added from URL)"])}):data.hasOwnProperty("members")&&jQuery.each(data.members,function(ci,mfst){_this.state.getStateProperty("manifests")[imageInfoUrl]||_this.eventEmitter.publish("ADD_MANIFEST_FROM_URL",[mfst["@id"],"(Added from URL)"])})}),_this.addItem()):_this.state.getStateProperty("manifests")[imageInfoUrl]||_this.eventEmitter.publish("ADD_MANIFEST_FROM_URL",[manifestUrl,"(Added from URL)"]),_this.eventEmitter.subscribe("manifestReceived",function(event,manifest){var windowConfig;manifest.jsonLd["@id"]!==manifestUrl&&manifest.jsonLd["@id"]+"/info.json"!==imageInfoUrl||(windowConfig={manifest:manifest,slotAddress:_this.getAddress()},manifest.jsonLd["@id"]+"/info.json"===imageInfoUrl&&(canvasId=manifest.jsonLd.sequences[0].canvases[0]["@id"]),canvasId&&(windowConfig.canvasID=canvasId,windowConfig.viewType="ImageView"),_this.eventEmitter.publish("ADD_WINDOW",windowConfig))})},destroyEvents:function(){var _this=this;this.events.forEach(function(event){_this.eventEmitter.unsubscribe(event.name,event.handler)})},clearSlot:function(){this.destroyEvents(),this.window&&delete this.window},getAddress:function(){return this.layoutAddress},addItem:function(){this.focused=!0,this.eventEmitter.publish("ADD_SLOT_ITEM",this)},template:$.Handlebars.compile(['
      ',' {{t "close"}}','
      ','

      ',"+",'
      ','',"
      ","

      ",'

      {{t "addItem"}}

      ','

      {{t "dropToLoad"}}

      ',"
      ",'','',"
      "].join(""))}}(Mirador),function($){$.Window=function(options){jQuery.extend(this,{state:null,eventEmitter:null,element:null,scrollImageRatio:.9,canvasID:null,currentCanvasModel:null,focusImages:[],imagesList:null,canvasModels:null,annotationsList:[],endpoint:null,currentImageMode:"ImageView",imageModes:["ImageView","BookView"],originalImageModes:["ImageView","BookView"],focuses:["ThumbnailsView","ImageView","ScrollView","BookView"],focusModules:{ThumbnailsView:null,ImageView:null,ScrollView:null,BookView:null},focusOverlaysAvailable:{ThumbnailsView:{overlay:{MetadataView:!1},bottomPanel:{"":!1}},ImageView:{overlay:{MetadataView:!1},bottomPanel:{ThumbnailsView:!0}},ScrollView:{overlay:{MetadataView:!1},bottomPanel:{"":!1}},BookView:{overlay:{MetadataView:!1},bottomPanel:{ThumbnailsView:!0}}},windowOptions:null,sidePanel:null,annotationsAvailable:{ThumbnailsView:!1,ImageView:!0,ScrollView:!1,BookView:!1},bottomPanel:null,overlay:null,annoEndpointAvailable:!1,iconClasses:{ImageView:"fa fa-photo fa-lg fa-fw",BookView:"fa fa-columns fa-lg fa-fw",ScrollView:"fa fa-ellipsis-h fa-lg fa-fw",ThumbnailsView:"fa fa-th fa-lg fa-rotate-90 fa-fw"},userButtons:null},options),this.init(),this.bindAnnotationEvents()},$.Window.prototype={init:function(){var _this=this,manifest=_this.manifest.jsonLd,focusState=_this.viewType,templateData={};for(this.events=[];0<_this.annotationsList.length;)_this.annotationsList.pop();switch(_this.eventEmitter.unsubscribe("currentCanvasIDUpdated."+_this.id),_this.eventEmitter.publish("DESTROY_EVENTS."+_this.id),_this.removeBookView(),"right-to-left"==_this.manifest.getViewingDirection()?_this.vDirectionStatus="rtl":_this.vDirectionStatus="",this.imageModes=this.originalImageModes,this.imageModes=jQuery.map(this.imageModes,function(value,index){return-1===jQuery.inArray(value,_this.focuses)?null:value}),_this.imagesList=_this.manifest.getCanvases(),1===_this.imagesList.length&&(_this.bottomPanelVisible=!1),_this.canvasID||(_this.canvasID=_this.imagesList[0]["@id"]),_this.canvases=_this.buildCanvasesIndex(_this.manifest.getCanvases()),"rtl"==_this.vDirectionStatus?(_this.imagesListLtr=_this.imagesList.concat(),_this.imagesListRtl=_this.imagesList.concat(),_this.imagesListRtl.reverse()):(_this.imagesListRtl=[],_this.imagesListLtr=[]),this.annoEndpointAvailable=!jQuery.isEmptyObject(_this.state.getStateProperty("annotationEndpoint")),this.canvasControls.annotations.annotationLayer||(this.canvasControls.annotations.annotationCreation=!1,this.annoEndpointAvailable=!1,this.canvasControls.annotations.annotationState="off"),_this.getAnnotations(),this.canvasControls.imageManipulation.manipulationLayer&&(this.canvasControls.imageManipulation.manipulationLayer=!Object.keys(this.canvasControls.imageManipulation.controls).every(function(element,index,array){return!1===_this.canvasControls.imageManipulation.controls[element]})),_this.eventEmitter.publish("windowUpdated",{id:_this.id,annotationsAvailable:this.annotationsAvailable}),void 0===this.bottomPanelAvailable||this.bottomPanelAvailable||jQuery.each(this.focusOverlaysAvailable,function(key,value){_this.focusOverlaysAvailable[key].bottomPanel={"":!1}}),templateData.sidePanel=this.sidePanelAvailable,this.sidePanelAvailable&&(templateData.sidePanel=!Object.keys(this.sidePanelOptions).every(function(element,index,array){return!1===_this.sidePanelOptions[element]})),void 0===this.overlayAvailable||this.overlayAvailable?templateData.MetadataView=!0:jQuery.each(this.focusOverlaysAvailable,function(key,value){_this.focusOverlaysAvailable[key].overlay={"":!1}}),templateData.iconClasses={},jQuery.each(this.focuses,function(index,value){templateData[value]=!0,templateData.iconClasses[value]=_this.iconClasses[value]}),templateData.title=$.JsonLd.getTextValue(manifest.label),templateData.displayLayout=this.displayLayout,templateData.layoutOptions=this.layoutOptions,this.displayLayout&&(templateData.displayLayout=!Object.keys(this.layoutOptions).every(function(element,index,array){return!1===_this.layoutOptions[element]})),templateData.currentFocusClass=_this.iconClasses[_this.viewType],templateData.showFullScreen=_this.fullScreen,templateData.userButtons=_this.userButtons,_this.element=jQuery(this.template(templateData)).appendTo(_this.appendTo),this.element.find(".manifest-info .mirador-tooltip").each(function(){jQuery(this).qtip({content:{text:jQuery(this).attr("title")},position:{my:"top center",at:"bottom center",adjust:{method:"shift",y:-11},container:_this.element,viewport:!0},style:{classes:"qtip-dark qtip-shadow qtip-rounded"}})}),this.element.find(".manifest-info .window-manifest-title").qtip({content:{text:jQuery(this).attr("title")},position:{my:"top center",at:"bottom left",adjust:{method:"shift",x:20,y:1},container:_this.element,viewport:!0},style:{classes:"qtip-dark qtip-shadow qtip-rounded"}}),_this.eventEmitter.publish("WINDOW_ELEMENT_UPDATED",{windowId:_this.id,element:_this.element}),_this.clearViews(),_this.clearPanelsAndOverlay(),this.listenForActions(),_this.bindNavigation(),focusState){case"ThumbnailsView":_this.toggleThumbnails(_this.canvasID);break;case"ImageView":_this.toggleImageView(_this.canvasID);break;case"BookView":_this.toggleBookView(_this.canvasID);break;case"ScrollView":_this.toggleScrollView(_this.canvasID)}_this.state.getSlots().length<=1&&_this.element.find(".remove-object-option").hide(),this.bindEvents(),this.bottomPanelVisibility(this.bottomPanelVisible),this.sidePanelVisibility(this.sidePanelVisible,"0s"),this.events.push(this.eventEmitter.subscribe("windowRemoved",function(event,id){_this.id===id&&_this.destroy()}))},buildCanvasesIndex:function(canvases){var _this=this;return canvases.reduce(function(canvasesIndex,canvas,index){var canvasEmitter=new $.EventEmitter;canvasEmitter.on=canvasEmitter.subscribe.bind(canvasEmitter),canvasEmitter.off=canvasEmitter.unsubscribe.bind(canvasEmitter),canvasEmitter.emit=canvasEmitter.publish.bind(canvasEmitter),canvasEmitter.subscribe("image-status-updated",function(event,imageResource){_this.eventEmitter.publish("image-status-updated"+_this.id,imageResource)}),canvasEmitter.subscribe("image-needed",function(event,imageResource){_this.eventEmitter.publish("image-needed"+_this.id,imageResource)}),canvasEmitter.subscribe("image-show",function(event,imageResource){_this.eventEmitter.publish("image-show"+_this.id,imageResource)}),canvasEmitter.subscribe("image-hide",function(event,imageResource){_this.eventEmitter.publish("image-hide"+_this.id,imageResource)}),canvasEmitter.subscribe("image-removed",function(event,imageResource){_this.eventEmitter.publish("image-removed"+_this.id,imageResource)}),canvasEmitter.subscribe("image-opacity-updated",function(event,imageResource){_this.eventEmitter.publish("image-opacity-updated"+_this.id,imageResource)});var eventedCanvas=new iiifEventedCanvas({canvas:canvas,index:index,dispatcher:canvasEmitter});return canvasesIndex[canvas["@id"]]=eventedCanvas,canvasesIndex},{})},destroy:function(){var _this=this;this.events.forEach(function(event){_this.eventEmitter.unsubscribe(event.name,event.handler)}),this.element.remove()},update:function(options){jQuery.extend(this,options),this.windowOptions&&(this.windowOptions.osdBounds=null,this.windowOptions.zoomLevel=null),this.init()},removeBookView:function(){this.focuses=this.availableViews;var manifest=this.manifest.jsonLd;manifest.sequences[0].viewingHint&&"paged"!==manifest.sequences[0].viewingHint.toLowerCase()&&(this.focuses=jQuery.grep(this.focuses,function(value){return"BookView"!==value}))},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("bottomPanelSet."+_this.id,function(event,visible){var panel=_this.element.find(".bottomPanel");!0===visible?panel.css({transform:"translateY(0)"}):panel.css({transform:"translateY(100%)"})}),_this.events.push(_this.eventEmitter.subscribe("HIDE_REMOVE_OBJECT."+_this.id,function(event){_this.element.find(".remove-object-option").hide()})),_this.events.push(this.eventEmitter.subscribe("SHOW_REMOVE_OBJECT."+_this.id,function(event){_this.element.find(".remove-object-option").show()})),_this.events.push(_this.eventEmitter.subscribe("sidePanelStateUpdated."+this.id,function(event,state){state.open?(_this.element.find(".mirador-icon-toc").addClass("selected"),_this.element.find(".view-container").removeClass("maximised")):(_this.element.find(".mirador-icon-toc").removeClass("selected"),_this.element.find(".view-container").addClass("maximised"))})),_this.events.push(_this.eventEmitter.subscribe("sidePanelVisibilityByTab."+this.id,function(event,visible){_this.sidePanelVisibility(visible,"0s")})),_this.events.push(_this.eventEmitter.subscribe("SET_CURRENT_CANVAS_ID."+this.id,function(event,canvasID){"string"==typeof canvasID?_this.setCurrentCanvasID(canvasID):(_this.canvasID!==canvasID.canvasID&&_this.setCurrentCanvasID(canvasID.canvasID),_this.eventEmitter.publish("fitBounds."+_this.id,canvasID.bounds))})),_this.events.push(_this.eventEmitter.subscribe("REMOVE_CLASS."+this.id,function(event,className){_this.element.find(".view-container").removeClass(className)})),_this.events.push(_this.eventEmitter.subscribe("ADD_CLASS."+this.id,function(event,className){_this.element.find(".view-container").addClass(className)})),_this.events.push(_this.eventEmitter.subscribe("UPDATE_FOCUS_IMAGES."+this.id,function(event,images){_this.updateFocusImages(images.array)})),_this.events.push(_this.eventEmitter.subscribe("HIDE_ICON_TOC."+this.id,function(event){_this.element.find(".mirador-icon-toc").hide()})),_this.events.push(_this.eventEmitter.subscribe("SHOW_ICON_TOC."+this.id,function(event){_this.element.find(".mirador-icon-toc").show()})),_this.events.push(_this.eventEmitter.subscribe("SET_BOTTOM_PANEL_VISIBILITY."+this.id,function(event,visibility){null!=visibility?_this.bottomPanelVisibility(visibility):_this.bottomPanelVisibility(_this.bottomPanelVisible)})),_this.events.push(_this.eventEmitter.subscribe("TOGGLE_BOTTOM_PANEL_VISIBILITY."+this.id,function(event){var visible=!_this.bottomPanelVisible;_this.bottomPanelVisibility(visible)})),_this.events.push(_this.eventEmitter.subscribe("DISABLE_WINDOW_FULLSCREEN",function(event){_this.element.find(".mirador-osd-fullscreen").hide()})),_this.events.push(_this.eventEmitter.subscribe("ENABLE_WINDOW_FULLSCREEN",function(event){_this.element.find(".mirador-osd-fullscreen").show()}))},bindEvents:function(){var _this=this;jQuery(window).resize($.debounce(function(){if(_this.focusModules.ScrollView){var containerHeight=_this.element.find(".view-container").height(),triggerShow=!1;"ScrollView"===_this.viewType&&(triggerShow=!0),_this.focusModules.ScrollView.reloadImages(Math.floor(containerHeight*_this.scrollImageRatio),triggerShow)}},300)),this.element.find(".mirador-osd-fullscreen").on("click",function(){$.fullscreenElement()?$.exitFullscreen():$.enterFullscreen(_this.element[0])}),jQuery(document).on("webkitfullscreenchange mozfullscreenchange fullscreenchange",function(){_this.toggleFullScreen()})},bindAnnotationEvents:function(){var _this=this;_this.eventEmitter.subscribe("annotationCreated."+_this.id,function(event,oaAnno,eventCallback){_this.endpoint.create(oaAnno,function(data){String(data["@id"]),_this.annotationsList.push(data),_this.eventEmitter.publish("ANNOTATIONS_LIST_UPDATED",{windowId:_this.id,annotationsList:_this.annotationsList}),eventCallback()},function(){console.log("There was an error saving this new annotation")})}),_this.eventEmitter.subscribe("annotationUpdated."+_this.id,function(event,oaAnno){_this.endpoint.update(oaAnno,function(data){jQuery.each(_this.annotationsList,function(index,value){if(value["@id"]===data["@id"])return _this.annotationsList[index]=data,!1}),_this.eventEmitter.publish("ANNOTATIONS_LIST_UPDATED",{windowId:_this.id,annotationsList:_this.annotationsList})},function(){console.log("There was an error updating this annotation")})}),_this.eventEmitter.subscribe("annotationDeleted."+_this.id,function(event,annoId){_this.endpoint.deleteAnnotation(annoId,function(){_this.annotationsList=jQuery.grep(_this.annotationsList,function(e){return e["@id"]!==annoId}),_this.eventEmitter.publish("removeOverlay."+_this.id,annoId),_this.eventEmitter.publish("ANNOTATIONS_LIST_UPDATED",{windowId:_this.id,annotationsList:_this.annotationsList})},function(){})}),_this.eventEmitter.subscribe("updateAnnotationList."+_this.id,function(event){for(;0<_this.annotationsList.length;)_this.annotationsList.pop();_this.getAnnotations()})},clearViews:function(){var _this=this;jQuery.each(_this.focusModules,function(key,value){_this.focusModules[key]=null})},clearPanelsAndOverlay:function(){this.sidePanel=null,this.bottomPanel=null,this.overlay=null},updatePanelsAndOverlay:function(state){var _this=this;jQuery.each(this.focusOverlaysAvailable[state],function(panelType,viewOptions){jQuery.each(viewOptions,function(view,displayed){""!==view&&null===_this[panelType]&&(_this[panelType]=new $[view]({manifest:_this.manifest,appendTo:_this.element.find("."+panelType),state:_this.state,eventEmitter:_this.eventEmitter,windowId:_this.id,panel:!0,canvasID:_this.canvasID,canvases:_this.canvases,imagesList:_this.imagesList,imagesListLtr:_this.imagesListLtr,imagesListRtl:_this.imagesListRtl,vDirectionStatus:_this.vDirectionStatus,thumbInfo:{thumbsHeight:80,listingCssCls:"panel-listing-thumbs",thumbnailCls:"panel-thumbnail-view"}})),displayed=_this.focusOverlaysAvailable[state][panelType][view],""!==view&&displayed&&_this.togglePanels(panelType,displayed,view,state),""===view&&_this[panelType]&&_this.togglePanels(panelType,displayed,view,state),""===view&&_this.adjustFocusSize(panelType,displayed)})})},updateSidePanel:function(){if(this.sidePanelAvailable){var tocTabAvailable=this.sidePanelOptions.tocTabAvailable,annotationsTabAvailable=this.sidePanelOptions.annotations,layersTabAvailable=this.sidePanelOptions.layersTabAvailable,searchTabAvailable=this.sidePanelOptions.searchTabAvailable,hasStructures=!0,structures=this.manifest.getStructures();structures&&0!==structures.length||(hasStructures=!1),null===this.sidePanel?this.sidePanel=new $.SidePanel({windowId:this.id,state:this.state,eventEmitter:this.eventEmitter,appendTo:this.element.find(".sidePanel"),manifest:this.manifest,canvasID:this.canvasID,canvases:this.canvases,layersTabAvailable:layersTabAvailable,tocTabAvailable:tocTabAvailable,searchTabAvailable:searchTabAvailable,annotationsTabAvailable:annotationsTabAvailable,hasStructures:hasStructures}):this.sidePanel.update("annotations",annotationsTabAvailable)}},get:function(prop,parent){return parent?this[parent][prop]:this[prop]},set:function(prop,value,options){options?this[options.parent][prop]=value:this[prop]=value},togglePanels:function(panelType,panelState,viewType,focusState){this.focusOverlaysAvailable[focusState][panelType][viewType]=panelState,this[panelType].toggle(panelState),this.adjustFocusSize(panelType,panelState)},sidePanelVisibility:function(visible,transitionDuration){this.sidePanelVisible=visible;var tocIconElement=this.element.find(".mirador-icon-toc"),sidePanelElement=this.element.find(".sidePanel"),viewContainerElement=this.element.find(".view-container");sidePanelElement.css("transition-duration",transitionDuration),viewContainerElement.css("transition",transitionDuration),visible&&sidePanelElement.hasClass("minimized")?(tocIconElement.addClass("selected"),sidePanelElement.removeClass("minimized").width(280).css("border-right","1px solid lightgray"),viewContainerElement.css("margin-left",280)):visible||sidePanelElement.hasClass("minimized")||(tocIconElement.removeClass("selected"),viewContainerElement.css("margin-left",0),sidePanelElement.addClass("minimized").css("border","none").width(0)),this.eventEmitter.publish("windowUpdated",{id:this.id,sidePanelVisible:visible})},bottomPanelVisibility:function(visible){this.bottomPanelVisible=visible,this.eventEmitter.publish("bottomPanelSet."+this.id,visible),this.eventEmitter.publish("windowUpdated",{id:this.id,bottomPanelVisible:visible})},adjustFocusSize:function(panelType,panelState){"bottomPanel"===panelType?this.focusModules[this.viewType].adjustHeight("focus-max-height",panelState):"sidePanel"===panelType&&this.focusModules[this.viewType].adjustWidth("focus-max-width",panelState)},toggleMetadataOverlay:function(focusState){var currentState=this.focusOverlaysAvailable[focusState].overlay.MetadataView;currentState?this.element.find(".mirador-icon-metadata-view").removeClass("selected"):this.element.find(".mirador-icon-metadata-view").addClass("selected"),jQuery.each(this.focusOverlaysAvailable,function(focusType,options){focusState!==focusType&&(this.overlay.MetadataView=!currentState)}),this.togglePanels("overlay",!currentState,"MetadataView",focusState)},toggleFocus:function(focusState,imageMode){this.viewType=focusState,imageMode&&-1 i:first").removeClass().addClass(this.iconClasses[this.viewType]),this.focusOverlaysAvailable[this.viewType].overlay.MetadataView&&this.element.find(".mirador-icon-metadata-view").addClass("selected")},getAnnotations:function(){var _this=this,urls=_this.manifest.getAnnotationsListUrls(_this.canvasID);if(0!==urls.length&&jQuery.each(urls,function(index,url){jQuery.get(url,function(list){var annotations=list.resources;jQuery.each(annotations,function(index,value){void 0===value["@id"]&&(value["@id"]=$.genUUID()),value.endpoint="manifest"}),_this.annotationsList=_this.annotationsList.concat(annotations),_this.eventEmitter.publish("ANNOTATIONS_LIST_UPDATED",{windowId:_this.id,annotationsList:_this.annotationsList})})}),this.annoEndpointAvailable){var dfd=jQuery.Deferred(),module=_this.state.getStateProperty("annotationEndpoint").module,options=_this.state.getStateProperty("annotationEndpoint").options||{};options.name=_this.state.getStateProperty("annotationEndpoint").name,_this.endpoint&&null!==_this.endpoint?_this.endpoint.set("dfd",dfd):(options.dfd=dfd,options.windowID=_this.id,options.imagesList=_this.imagesList,options.eventEmitter=_this.eventEmitter,_this.endpoint=new $[module](options)),_this.endpoint.search({uri:_this.canvasID}),dfd.done(function(loaded){_this.annotationsList=_this.annotationsList.concat(_this.endpoint.annotationsList),_this.annotationsList=jQuery.grep(_this.annotationsList,function(value,index){return void 0!==value.on}),_this.eventEmitter.publish("ANNOTATIONS_LIST_UPDATED",{windowId:_this.id,annotationsList:_this.annotationsList})})}},toggleFullScreen:function(){OpenSeadragon.isFullScreen()?(this.element.find(".mirador-osd-fullscreen i").removeClass("fa-expand").addClass("fa-compress"),this.element.find(".mirador-osd-toggle-bottom-panel").hide(),this.eventEmitter.publish("SET_BOTTOM_PANEL_VISIBILITY."+this.id,!1)):(this.element.find(".mirador-osd-fullscreen i").removeClass("fa-compress").addClass("fa-expand"),this.element.find(".mirador-osd-toggle-bottom-panel").show(),this.eventEmitter.publish("SET_BOTTOM_PANEL_VISIBILITY."+this.id,!0))},bindNavigation:function(){var _this=this;this.element.find(".mirador-icon-view-type").on("mouseenter",function(){_this.element.find(".image-list").stop().slideFadeToggle(300)}).on("mouseleave",function(){_this.element.find(".image-list").stop().slideFadeToggle(300)}),this.element.find(".mirador-icon-window-menu").on("mouseenter",function(){_this.element.find(".slot-controls").stop().slideFadeToggle(300)}).on("mouseleave",function(){_this.element.find(".slot-controls").stop().slideFadeToggle(300)}),this.element.find(".single-image-option").on("click",function(){_this.toggleImageView(_this.canvasID)}),this.element.find(".book-option").on("click",function(){_this.toggleBookView(_this.canvasID)}),this.element.find(".scroll-option").on("click",function(){_this.toggleScrollView(_this.canvasID)}),this.element.find(".thumbnails-option").on("click",function(){_this.toggleThumbnails(_this.canvasID)}),this.element.find(".mirador-icon-metadata-view").on("click",function(){_this.toggleMetadataOverlay(_this.viewType)}),this.element.find(".mirador-icon-toc").on("click",function(){_this.sidePanelVisibility(!_this.sidePanelVisible,"0.3s")}),this.element.find(".new-object-option").on("click",function(){_this.eventEmitter.publish("ADD_ITEM_FROM_WINDOW",_this.id)}),this.element.find(".remove-object-option").on("click",function(){_this.eventEmitter.publish("REMOVE_SLOT_FROM_WINDOW",_this.id)}),this.element.find(".add-slot-right").on("click",function(){_this.eventEmitter.publish("SPLIT_RIGHT_FROM_WINDOW",_this.id)}),this.element.find(".add-slot-left").on("click",function(){_this.eventEmitter.publish("SPLIT_LEFT_FROM_WINDOW",_this.id)}),this.element.find(".add-slot-below").on("click",function(){_this.eventEmitter.publish("SPLIT_DOWN_FROM_WINDOW",_this.id)}),this.element.find(".add-slot-above").on("click",function(){_this.eventEmitter.publish("SPLIT_UP_FROM_WINDOW",_this.id)})},template:$.Handlebars.compile(['"].join(""))};var processUserButton=function(button){var $a=jQuery(""),$i=jQuery("",{class:"fa fa-lg fa-fw"});try{if(!button.iconClass)throw"userButtons must have an iconClass";return button.attributes&&$a.attr(button.attributes),$a.addClass("mirador-btn"),$i.addClass(button.iconClass),$a.append($i),$a.get(0).outerHTML}catch(error){return console&&console.error&&console.error(error),""}};$.Handlebars.registerHelper("windowuserbtns",function(userButtons){return new $.Handlebars.SafeString((buttons=userButtons,buttons.map(function(button,index){return processUserButton(button)})).join(""));var buttons})}(Mirador),function($){$.AnnotationsLayer=function(options){jQuery.extend(!0,this,{annotationsList:null,viewer:null,drawTool:null,selected:null,hovered:null,windowId:null,mode:"default",element:null,eventEmitter:null},options),this.init()},$.AnnotationsLayer.DISPLAY_ANNOTATIONS="displayAnnotations",$.AnnotationsLayer.prototype={init:function(){this.eventEmitter.unsubscribe("modeChange."+this.windowId),this.eventEmitter.unsubscribe("slotLeave."+this.windowId),this.eventEmitter.unsubscribe("slotEnter."+this.windowId),this.createStateMachine(),this.createRenderer(),this.bindEvents(),this.listenForActions()},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("modeChange."+_this.windowId,function(event,modeName){_this.mode=modeName,_this.modeSwitch()}),_this.eventEmitter.subscribe("annotationListLoaded."+_this.windowId,function(event){_this.annotationsList=_this.state.getWindowAnnotationsList(_this.windowId),_this.updateRenderer()}),_this.eventEmitter.subscribe("slotLeave."+_this.windowId,function(event,eventData){"display"==_this.layerState.current&&(_this.layerState.defaultState(),_this.modeSwitch())}),_this.eventEmitter.subscribe("slotEnter."+_this.windowId,function(event,eventData){_this.element.showAnno&&"display"==_this.layerState.current&&(_this.layerState.defaultState(),_this.modeSwitch())})},bindEvents:function(){},createStateMachine:function(){var _this=this;this.layerState=StateMachine.create({events:[{name:"startup",from:"none",to:"default"},{name:"defaultState",from:["default","display","create","edit"],to:"default"},{name:"displayAnnotations",from:["default","display","create","edit","newShape"],to:"display"},{name:"createAnnotation",from:["default","display"],to:"create"},{name:"createShape",from:"edit",to:"newShape"},{name:"editAnnotation",from:["default","display","newShape"],to:"edit"}],callbacks:{onstartup:function(event){_this.drawTool.enterDefault()},ondefaultState:function(event){_this.drawTool.enterDefault()},ondisplayAnnotations:function(event){_this.drawTool.enterDisplayAnnotations()},oncreateAnnotation:function(event){_this.drawTool.enterCreateAnnotation()},oncreateShape:function(event){_this.drawTool.enterCreateShape()},oneditAnnotation:function(event){_this.drawTool.enterEditAnnotation()}}})},createRenderer:function(){this.drawTool=new $.OsdRegionDrawTool({osdViewer:this.viewer,parent:this,list:this.annotationsList,visible:!1,windowId:this.windowId,state:this.state,eventEmitter:this.eventEmitter}),this.layerState.startup()},updateRenderer:function(){this.drawTool.list=this.annotationsList},modeSwitch:function(){"displayAnnotations"===this.mode?this.layerState.displayAnnotations():"editingAnnotation"===this.mode?this.layerState.editAnnotation():"creatingAnnotation"===this.mode?"edit"!==this.layerState.current?this.layerState.createAnnotation():this.layerState.createShape():"default"===this.mode&&this.layerState.defaultState()}}}(Mirador),function($){$.AnnotationsTab=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,manifest:null,visible:null,state:null,eventEmitter:null},options),this.init()},$.AnnotationsTab.prototype={init:function(){this.windowId=this.windowId,this.localState({id:"annotationsTab",visible:this.visible,annotationLists:[],selectedList:null,empty:!0,focusedList:null},!0),this.listenForActions(),this.render(this.localState()),this.loadTabComponents(),this.bindEvents()},localState:function(state,initial){return arguments.length&&(this.annoTabState=state,initial||this.eventEmitter.publish("annotationsTabStateUpdated."+this.windowId,this.annoTabState)),this.annoTabState},loadTabComponents:function(){},tabStateUpdated:function(visible){var localState=this.localState();localState.visible=!localState.visible,this.localState(localState)},annotationListLoaded:function(){var annotationSources=[],localState=this.localState();jQuery.each(this.state.getWindowAnnotationsList(this.windowId),function(index,value){"string"==typeof value.endpoint?annotationSources.push("manifest"):annotationSources.push(value.endpoint.name)}),annotationSources=annotationSources.filter(function(itm,i,annotationSources){return i==annotationSources.indexOf(itm)}),localState.annotationLists=annotationSources.map(function(annotationSource){return{annotationSource:annotationSource,layer:null,selected:annotationSource===localState.selectedList,focused:!1}}),localState.annotationLists.length&&(localState.empty=!1),this.localState(localState)},deselectList:function(listId){var localState=this.localState();localState.selectedList=null,localState.annotationLists.forEach(function(list){list.selected=!1}),this.localState(localState)},selectList:function(listId){var localState=this.localState();localState.selectedList=listId,localState.annotationLists.forEach(function(list){list.selected=list.annotationSource===listId}),this.localState(localState)},focusList:function(listId){var localState=this.localState();localState.focusedList=listId,localState.annotationLists.forEach(function(list){list.focused=list.annotationSource===listId}),this.localState(localState)},toggle:function(){},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("annotationsTabStateUpdated."+_this.windowId,function(_,data){_this.render(data)}),_this.eventEmitter.subscribe("tabStateUpdated."+_this.windowId,function(_,data){_this.tabStateUpdated("annotationsTab"==data.tabs[data.selectedTabIndex].options.id)}),_this.eventEmitter.subscribe("annotationListLoaded."+_this.windowId,function(_,data){_this.annotationListLoaded()}),_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,function(event){_this.eventEmitter.subscribe("annotationListLoaded."+_this.windowId,function(event){_this.annotationListLoaded()}),_this.selectList(_this.localState().selectedList)}),_this.eventEmitter.subscribe("listSelected."+_this.windowId,function(event,listId){_this.selectList(listId)}),_this.eventEmitter.subscribe("listDeselected."+_this.windowId,function(event,listId){_this.deselectList(listId)})},bindEvents:function(){var _this=this;this.element.find(".annotationListItem").on("click",function(event){var listClicked=jQuery(this).data("id");_this.localState().selectedList===listClicked?_this.eventEmitter.publish("listDeselected."+_this.windowId,listClicked):_this.eventEmitter.publish("listSelected."+_this.windowId,listClicked)})},render:function(state){var templateData={annotationSources:state.annotationLists};this.element&&jQuery(this.appendTo).find(".annotationsPanel").remove(),this.element=jQuery(this.template(templateData)).appendTo(this.appendTo),this.bindEvents(),state.visible?this.element.show():this.element.hide()},template:$.Handlebars.compile(['
      ','
        ',"{{#each annotationSources}}",'
      • ',"{{this.annotationSource}}","
      • ","{{/each}}","
      ","
      "].join(""))}}(Mirador),function($){$.BookView=function(options){jQuery.extend(this,{currentImg:null,windowId:null,currentImgIndex:0,stitchList:[],canvasID:null,imagesList:[],imagesListRtl:[],element:null,focusImages:[],manifest:null,viewingDirection:"left-to-right",viewingHint:"paged",osd:null,osdCls:"mirador-osd",osdOptions:{osdBounds:null,zoomLevel:null},stitchTileMargin:10,eventEmitter:null},options),this.init()},$.BookView.prototype={init:function(){"rtl"==this.vDirectionStatus&&(this.imagesList=this.imagesListRtl.concat()),null!==this.canvasID&&(this.currentImgIndex=$.getImageIndexById(this.imagesList,this.canvasID)),this.osdOptions||(this.osdOptions={osdBounds:null,zoomLevel:null}),this.currentImg=this.imagesList[this.currentImgIndex],this.element=jQuery(this.template()).appendTo(this.appendTo),this.hud=new $.Hud({appendTo:this.element,bottomPanelAvailable:this.bottomPanelAvailable,windowId:this.windowId,annotationLayerAvailable:!1,showNextPrev:1!==this.imagesList.length,eventEmitter:this.eventEmitter,showAnno:!1,showImageControls:!1}),this.manifest.jsonLd.sequences[0].viewingDirection&&(this.viewingDirection=this.manifest.jsonLd.sequences[0].viewingDirection.toLowerCase()),this.manifest.jsonLd.sequences[0].viewingHint&&(this.viewingHint=this.manifest.jsonLd.sequences[0].viewingHint.toLowerCase()),this.stitchList=this.getStitchList(),this.createOpenSeadragonInstance(),this.bindEvents(),this.listenForActions(),void 0===this.bottomPanelAvailable||this.bottomPanelAvailable?this.eventEmitter.publish("SET_BOTTOM_PANEL_VISIBILITY."+this.windowId,null):this.eventEmitter.publish("SET_BOTTOM_PANEL_VISIBILITY."+this.windowId,!1)},template:$.Handlebars.compile(['
      ',"
      "].join("")),listenForActions:function(){var _this=this,firstCanvasId=_this.imagesList[0]["@id"],lastCanvasId=_this.imagesList[_this.imagesList.length-1]["@id"];_this.eventEmitter.subscribe("bottomPanelSet."+_this.windowId,function(event,visible){var dodgers=_this.element.find(".mirador-osd-toggle-bottom-panel, .mirador-pan-zoom-controls"),arrows=_this.element.find(".mirador-osd-next, .mirador-osd-previous");!0===visible?(dodgers.addClass("bottom-panel-open"),arrows.addClass("bottom-panel-open")):(dodgers.removeClass("bottom-panel-open"),arrows.removeClass("bottom-panel-open"))}),_this.eventEmitter.subscribe("fitBounds."+_this.windowId,function(event,bounds){var rect=_this.osd.viewport.imageToViewportRectangle(Number(bounds.x),Number(bounds.y),Number(bounds.width),Number(bounds.height));_this.osd.viewport.fitBoundsWithConstraints(rect,!1)}),_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,function(event,canvasId){canvasId===firstCanvasId?(_this.element.find(".mirador-osd-previous").hide(),_this.element.find(".mirador-osd-next").show()):(canvasId===lastCanvasId?_this.element.find(".mirador-osd-next").hide():_this.element.find(".mirador-osd-next").show(),_this.element.find(".mirador-osd-previous").show())})},bindEvents:function(){var _this=this;this.element.find(".mirador-osd-next").on("click",function(){_this.next()}),this.element.find(".mirador-osd-previous").on("click",function(){_this.previous()}),this.element.find(".mirador-osd-go-home").on("click",function(){_this.osd.viewport.goHome()}),this.element.find(".mirador-osd-up").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(0,-panBy.y)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-right").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(panBy.x,0)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-down").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(0,panBy.y)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-left").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(-panBy.x,0)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-zoom-in").on("click",function(){var osd=_this.osd;osd.viewport&&(osd.viewport.zoomBy(osd.zoomPerClick/1),osd.viewport.applyConstraints())}),this.element.find(".mirador-osd-zoom-out").on("click",function(){var osd=_this.osd;osd.viewport&&(osd.viewport.zoomBy(1/osd.zoomPerClick),osd.viewport.applyConstraints())}),this.element.find(".mirador-osd-toggle-bottom-panel").on("click",function(){_this.eventEmitter.publish("TOGGLE_BOTTOM_PANEL_VISIBILITY."+_this.windowId)})},getPanByValue:function(){var bounds=this.osd.viewport.getBounds(!0);return{x:.5*bounds.width,y:.5*bounds.height}},setBounds:function(){this.osdOptions.osdBounds=this.osd.viewport.getBounds(!0),this.eventEmitter.publish("imageBoundsUpdated",{id:this.windowId,osdBounds:{x:this.osdOptions.osdBounds.x,y:this.osdOptions.osdBounds.y,width:this.osdOptions.osdBounds.width,height:this.osdOptions.osdBounds.height}})},toggle:function(stateValue){stateValue?this.show():this.hide()},hide:function(){jQuery(this.element).hide({effect:"fade",duration:300,easing:"easeOutCubic"})},show:function(){jQuery(this.element).show({effect:"fade",duration:300,easing:"easeInCubic",complete:function(){jQuery(this).css("display","block")}})},adjustWidth:function(className,hasClass){hasClass?this.eventEmitter.publish("REMOVE_CLASS."+this.windowId,className):this.eventEmitter.publish("ADD_CLASS."+this.windowId,className)},adjustHeight:function(className,hasClass){hasClass?this.element.removeClass(className):this.element.addClass(className)},updateImage:function(canvasID){this.canvasID=canvasID,this.currentImgIndex=$.getImageIndexById(this.imagesList,this.canvasID),this.currentImg=this.imagesList[this.currentImgIndex];var newList=this.getStitchList();this.stitchList.length==newList.length&&this.stitchList.every(function(element,index){return element===newList[index]})||(this.stitchList=newList,this.osdOptions={osdBounds:null,zoomLevel:null},this.osd.close(),this.createOpenSeadragonInstance())},createOpenSeadragonInstance:function(){var elemOsd,uniqueID=$.genUUID(),osdId="mirador-osd-"+uniqueID,tileSources=[],_this=this,toolbarID="osd-toolbar-"+uniqueID,dfd=jQuery.Deferred();this.element.find("."+this.osdCls).remove(),jQuery.each(this.stitchList,function(index,image){var infoJsonUrl=$.Iiif.getImageUrl(image)+"/info.json";jQuery.getJSON(infoJsonUrl).done(function(data,status,jqXHR){tileSources.splice(index,0,data),tileSources.length===_this.stitchList.length&&dfd.resolve()})}),dfd.done(function(){var aspectRatio=tileSources[0].height/tileSources[0].width;elemOsd=jQuery("
      ").addClass(_this.osdCls).attr("id",osdId).appendTo(_this.element),_this.osd=$.OpenSeadragon({id:elemOsd.attr("id"),toolbarID:toolbarID}),_this.osd.addHandler("open",function(){_this.addLayer(tileSources.slice(1),aspectRatio);var addItemHandler=function(event){if(_this.osd.world.removeHandler("add-item",addItemHandler),_this.osdOptions.osdBounds){var rect=new OpenSeadragon.Rect(_this.osdOptions.osdBounds.x,_this.osdOptions.osdBounds.y,_this.osdOptions.osdBounds.width,_this.osdOptions.osdBounds.height);_this.osd.viewport.fitBounds(rect,!0)}else _this.osd.viewport.goHome(!0)};_this.boundsToFocusOnNextOpen&&(_this.eventEmitter.publish("fitBounds."+_this.windowId,_this.boundsToFocusOnNextOpen),_this.boundsToFocusOnNextOpen=null),_this.osd.world.addHandler("add-item",addItemHandler),_this.osd.addHandler("zoom",$.debounce(function(){_this.setBounds()},300)),_this.osd.addHandler("pan",$.debounce(function(){_this.setBounds()},300))}),_this.osd.open(tileSources[0],{opacity:1,x:0,y:0,width:1})})},addLayer:function(tileSources,aspectRatio){var _this=this;jQuery.each(tileSources,function(index,value){var newAR=value.height/value.width,options={tileSource:value,opacity:1,x:1.01,y:0,width:aspectRatio/newAR};_this.osd.addTiledImage(options)})},next:function(){var next;(next=this.currentImgIndex%2==0?this.currentImgIndex+1:this.currentImgIndex+2)border_color"),_this.addColorPicker(".fillColorPicker",{showInput:!0,showInitial:!1,showAlpha:!0,showPalette:!0,showButtons:!1,showSelectionPalette:!0,appendTo:"parent",clickoutFiresChange:!0,containerClassName:"fillColorPickerPop"+_this.windowId,preferredFormat:"rgb",hide:function(color){_this.eventEmitter.publish("changeFillColor."+_this.windowId,[color.toHexString(),color.getAlpha()]),jQuery(this).spectrum("set",color)},move:function(color){_this.eventEmitter.publish("changeFillColor."+_this.windowId,[color.toHexString(),color.getAlpha()])},show:function(color){_this.setColorPickerInCanvas(".fillColorPicker")},maxSelectionSize:4,color:colorObj,palette:[[colorObj,"black","red","green"],["white","blue","magenta","yellow"]]}),_this.container.find(".fillColorPicker").next(".sp-replacer").prepend("format_color_fill")},setColorPickerInCanvas:function(selector){var pickerContainer=this.container.find(selector).siblings(".sp-container").first(),pickerOffset=pickerContainer.offset(),windowWidth=this.state.windowsElements[this.windowId].width();pickerContainer.width()+pickerOffset.left>windowWidth&&pickerContainer.css("left",windowWidth-pickerContainer.outerWidth())},annotationShow:function(){this.annotationElement.fadeIn("150")},annotationHide:function(){this.annotationElement.fadeOut("150")},manipulationShow:function(){this.manipulationElement.fadeIn("150")},manipulationHide:function(){this.manipulationElement.fadeOut("150")},bindEvents:function(){var _this=this;this.container.find(".mirador-line-type").on("mouseenter",function(){if(jQuery(this).hasClass("hud-disabled"))return!1;_this.container.find(".type-list").stop().slideFadeToggle(300)}),this.container.find(".mirador-line-type").on("mouseleave",function(){if(jQuery(this).hasClass("hud-disabled"))return!1;_this.container.find(".type-list").stop().slideFadeToggle(300)}),this.container.find(".mirador-line-type").find("ul li").on("click",function(){if(jQuery(this).hasClass("hud-disabled"))return!1;var className=jQuery(this).find("i").attr("class").replace(/fa/,"").replace(/ /,"");_this.removeBackgroundImage(_this.container.find(".mirador-line-type .border-type-image")),_this.setBackground[className](_this.container.find(".mirador-line-type .border-type-image")),_this.eventEmitter.publish("toggleBorderType."+_this.windowId,className)})},annotationTemplate:$.Handlebars.compile(["{{#if showEdit}}",'','',"","{{#each tools}}",'','{{this.logoClass}}',"","{{/each}}","{{#if showStrokeStyle}}",'','create','','','","","{{/if}}","{{#if showStrokeColor}}",'','',"","{{/if}}","{{#if showFillColor}}",'','',"","{{/if}}","{{#if showRefresh}}",'','',"","{{/if}}","{{/if}}"].join("")),manipulationTemplate:$.Handlebars.compile(["{{#if showRotate}}",'','',"",'','',"","{{/if}}","{{#if filtersSupported}}","{{#if showBrightness}}",'','wb_sunny','','
      ',"","{{/if}}","{{#if showContrast}}",'','brightness_6','','
      ',"","{{/if}}","{{#if showSaturate}}",'','gradient','','
      ',"","{{/if}}","{{#if showGrayscale}}",'','filter_b_and_w',"","{{/if}}","{{#if showInvert}}",'','invert_colors',"","{{/if}}","{{#if showMirror}}",'','swap_horiz',"","{{/if}}",'','',"","{{/if}}"].join("")),editorTemplate:$.Handlebars.compile(['"].join(""))}}(Mirador),function($){$.Hud=function(options){jQuery.extend(this,{element:null,windowId:null,annoState:null,annoEndpointAvailable:!1,eventEmitter:null},options),this.init()},$.Hud.prototype={init:function(){this.createStateMachines();var showAnno=void 0!==this.showAnno?this.showAnno:this.canvasControls.annotations.annotationLayer,showImageControls=void 0!==this.showImageControls?this.showImageControls:this.canvasControls.imageManipulation.manipulationLayer;this.element=jQuery(this.template({showNextPrev:this.showNextPrev,showBottomPanel:void 0===this.bottomPanelAvailable||this.bottomPanelAvailable,showAnno:showAnno,showImageControls:showImageControls})).appendTo(this.appendTo),(showAnno||showImageControls)&&(this.contextControls=new $.ContextControls({element:null,container:this.element.find(".mirador-osd-context-controls"),qtipElement:this.qtipElement,mode:"displayAnnotations",windowId:this.windowId,canvasControls:this.canvasControls,annoEndpointAvailable:this.annoEndpointAvailable,availableAnnotationTools:this.availableAnnotationTools,availableAnnotationStylePickers:this.availableAnnotationStylePickers,state:this.state,eventEmitter:this.eventEmitter})),this.listenForActions(),this.bindEvents()},listenForActions:function(){var _this=this;this.eventEmitter.subscribe("DISABLE_TOOLTIPS_BY_CLASS."+this.windowId,function(event,className){_this.element.find(className).qtip("disable")}),this.eventEmitter.subscribe("ENABLE_TOOLTIPS_BY_CLASS."+this.windowId,function(event,className){_this.element.find(className).qtip("enable")}),this.eventEmitter.subscribe("SET_STATE_MACHINE_POINTER."+this.windowId,function(event){"none"===_this.annoState.current?_this.annoState.startup():"off"===_this.annoState.current?_this.annoState.displayOn():_this.annoState.choosePointer()})},bindEvents:function(){},createStateMachines:function(){var _this=this;this.annoState=StateMachine.create({events:[{name:"startup",from:"none",to:"off"},{name:"displayOn",from:"off",to:"pointer"},{name:"displayOff",from:["pointer","shape"],to:"off"},{name:"choosePointer",from:["pointer","shape"],to:"pointer"},{name:"chooseShape",from:"pointer",to:"shape"},{name:"changeShape",from:"shape",to:"shape"},{name:"refresh",from:"pointer",to:"pointer"},{name:"refresh",from:"shape",to:"shape"}],callbacks:{onstartup:function(event,from,to){_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},ondisplayOn:function(event,from,to){_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-osd-annotations-layer","selected"]),_this.annoEndpointAvailable&&_this.contextControls.annotationShow(),_this.eventEmitter.publish("modeChange."+_this.windowId,"displayAnnotations"),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-osd-pointer-mode","selected"]),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".hud-dropdown","hud-disabled"]),_this.eventEmitter.publish("DISABLE_TOOLTIPS_BY_CLASS."+_this.windowId,".hud-dropdown"),_this.eventEmitter.publish("DEFAULT_CURSOR."+_this.windowId),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},ondisplayOff:function(event,from,to){_this.annoEndpointAvailable&&(_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-edit-mode","selected"]),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-pointer-mode","selected"]),_this.eventEmitter.publish("CANCEL_ACTIVE_ANNOTATIONS."+_this.windowId),_this.contextControls.annotationHide()),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-annotations-layer","selected"]),_this.eventEmitter.publish("modeChange."+_this.windowId,"default"),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},onchoosePointer:function(event,from,to){_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-edit-mode","selected"]),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-osd-pointer-mode","selected"]),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".hud-dropdown","hud-disabled"]),_this.eventEmitter.publish("DISABLE_TOOLTIPS_BY_CLASS."+_this.windowId,".hud-dropdown"),_this.eventEmitter.publish("modeChange."+_this.windowId,"displayAnnotations"),_this.eventEmitter.publish("DEFAULT_CURSOR."+_this.windowId),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},onchooseShape:function(event,from,to,shape){_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-pointer-mode","selected"]),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-edit-mode","selected"]),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".hud-dropdown","hud-disabled"]),_this.eventEmitter.publish("ENABLE_TOOLTIPS_BY_CLASS."+_this.windowId,".hud-dropdown"),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-osd-"+shape+"-mode","selected"]),_this.eventEmitter.publish("modeChange."+_this.windowId,"creatingAnnotation"),_this.eventEmitter.publish("CROSSHAIR_CURSOR."+_this.windowId),_this.eventEmitter.publish("toggleDrawingTool."+_this.windowId,shape),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},onchangeShape:function(event,from,to,shape){_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-pointer-mode","selected"]),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-osd-edit-mode","selected"]),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".hud-dropdown","hud-disabled"]),_this.eventEmitter.publish("ENABLE_TOOLTIPS_BY_CLASS."+_this.windowId,".hud-dropdown"),_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-osd-"+shape+"-mode","selected"]),_this.eventEmitter.publish("CROSSHAIR_CURSOR."+_this.windowId),_this.eventEmitter.publish("toggleDrawingTool."+_this.windowId,shape),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,annotationState:to})},onrefresh:function(event,from,to){}}}),this.manipulationState=StateMachine.create({events:[{name:"startup",from:"none",to:"manipulationOff"},{name:"displayOn",from:"manipulationOff",to:"manipulationOn"},{name:"displayOff",from:"manipulationOn",to:"manipulationOff"}],callbacks:{onstartup:function(event,from,to){_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,manipulationState:to})},ondisplayOn:function(event,from,to){_this.eventEmitter.publish("HUD_ADD_CLASS."+_this.windowId,[".mirador-manipulation-toggle","selected"]),_this.contextControls.manipulationShow(),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,manipulationState:to})},ondisplayOff:function(event,from,to){_this.contextControls.manipulationHide(),_this.eventEmitter.publish("HUD_REMOVE_CLASS."+_this.windowId,[".mirador-manipulation-toggle","selected"]),_this.eventEmitter.publish("windowUpdated",{id:_this.windowId,manipulationState:to})}}})},template:$.Handlebars.compile(['
      ',"{{#if showNextPrev}}",'','',"","{{/if}}",'
      ',"{{#if showAnno}}",'
      ','','',"","
      ","{{/if}}","{{#if showImageControls}}",'","{{/if}}","
      ","{{#if showNextPrev}}",'','',"","{{/if}}","{{#if showBottomPanel}}",'','',"","{{/if}}",'","
      "].join(""))}}(Mirador),function($){$.ImageView=function(options){jQuery.extend(this,{currentImg:null,windowId:null,currentImgIndex:0,canvasID:null,canvases:null,imagesList:[],imagesListRtl:[],element:null,elemOsd:null,manifest:null,osd:null,osdOptions:{osdBounds:null,zoomLevel:null},osdCls:"mirador-osd",elemAnno:null,annoCls:"annotation-canvas",annotationsLayer:null,forceShowControls:!1,eventEmitter:null,vDirectionStatus:""},options),this.init()},$.ImageView.prototype={init:function(){this.horizontallyFlipped=!1,this.originalDragHandler=null,"rtl"==this.vDirectionStatus&&(this.imagesList=this.imagesListRtl.concat()),null!==this.canvasID&&(this.currentImgIndex=$.getImageIndexById(this.imagesList,this.canvasID)),this.osdOptions||(this.osdOptions={osdBounds:null,zoomLevel:null}),this.currentImg=this.imagesList[this.currentImgIndex],this.element=jQuery(this.template()).appendTo(this.appendTo),this.elemAnno=jQuery("
      ").addClass(this.annoCls).appendTo(this.element),this.eventEmitter.publish("UPDATE_FOCUS_IMAGES."+this.windowId,{array:[this.canvasID]});var allTools=$.getTools(this.state.getStateProperty("drawingToolsSettings"));this.availableAnnotationTools=[];for(var i=0;i',"
      "].join("")),listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("bottomPanelSet."+_this.windowId,function(event,visible){var dodgers=_this.element.find(".mirador-osd-toggle-bottom-panel, .mirador-pan-zoom-controls"),arrows=_this.element.find(".mirador-osd-next, .mirador-osd-previous");!0===visible?(dodgers.addClass("bottom-panel-open"),arrows.addClass("bottom-panel-open")):(dodgers.removeClass("bottom-panel-open"),arrows.removeClass("bottom-panel-open"))}),_this.eventEmitter.subscribe("fitBounds."+_this.windowId,function(event,bounds){var rect=new OpenSeadragon.Rect(bounds.x,bounds.y,bounds.width,bounds.height);_this.osd.viewport.fitBoundsWithConstraints(rect,!1)}),_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,_this.currentCanvasIDUpdated.bind(_this)),_this.eventEmitter.subscribe("image-needed"+_this.windowId,_this.loadImage.bind(_this)),_this.eventEmitter.subscribe("image-show"+_this.windowId,_this.showImage.bind(_this)),_this.eventEmitter.subscribe("image-hide"+_this.windowId,_this.hideImage.bind(_this)),_this.eventEmitter.subscribe("image-removed"+_this.windowId,_this.removeImage.bind(_this)),_this.eventEmitter.subscribe("image-opacity-updated"+_this.windowId,_this.updateImageOpacity.bind(_this)),_this.eventEmitter.subscribe("HUD_REMOVE_CLASS."+_this.windowId,function(event,elementSelector,className){_this.element.find(elementSelector).removeClass(className)}),_this.eventEmitter.subscribe("HUD_ADD_CLASS."+_this.windowId,function(event,elementSelector,className){_this.element.find(elementSelector).addClass(className)}),_this.eventEmitter.subscribe("HUD_FADE_IN."+_this.windowId,function(event,elementSelector,duration){_this.element.find(elementSelector).fadeIn(duration)}),_this.eventEmitter.subscribe("HUD_FADE_OUT."+_this.windowId,function(event,elementSelector,duration,complete){_this.element.find(elementSelector).fadeOut(duration,complete)}),_this.eventEmitter.subscribe("DEFAULT_CURSOR."+_this.windowId,function(event){jQuery(_this.osd.canvas).css("cursor","default")}),_this.eventEmitter.subscribe("CROSSHAIR_CURSOR."+_this.windowId,function(event){jQuery(_this.osd.canvas).css("cursor","crosshair")}),_this.eventEmitter.subscribe("POINTER_CURSOR."+_this.windowId,function(event){jQuery(_this.osd.canvas).css("cursor","pointer")})},bindEvents:function(){var _this=this;this.element.find(".mirador-osd-next").on("click",function(){_this.next()}),this.element.find(".mirador-osd-previous").on("click",function(){_this.previous()}),this.element.find(".mirador-osd-annotations-layer").on("click",function(){"none"===_this.hud.annoState.current&&_this.hud.annoState.startup(this),"off"===_this.hud.annoState.current?(_this.hud.annoState.displayOn(this),_this.annotationState="on"):(_this.forceShowControls=!1,_this.hud.annoState.displayOff(this),_this.annotationState="off")}),this.element.find(".mirador-manipulation-toggle").on("click",function(){"none"===_this.hud.manipulationState.current&&_this.hud.manipulationState.startup(this),"manipulationOff"===_this.hud.manipulationState.current?_this.hud.manipulationState.displayOn(this):_this.hud.manipulationState.displayOff(this)}),this.element.find(".mirador-osd-go-home").on("click",function(){_this.osd.viewport.goHome()}),this.element.find(".mirador-osd-up").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(0,-panBy.y)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-right").on("click",function(){var panBy=_this.getPanByValue();_this.horizontallyFlipped?_this.osd.viewport.panBy(new OpenSeadragon.Point(-panBy.x,0)):_this.osd.viewport.panBy(new OpenSeadragon.Point(panBy.x,0)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-down").on("click",function(){var panBy=_this.getPanByValue();_this.osd.viewport.panBy(new OpenSeadragon.Point(0,panBy.y)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-left").on("click",function(){var panBy=_this.getPanByValue();_this.horizontallyFlipped?_this.osd.viewport.panBy(new OpenSeadragon.Point(panBy.x,0)):_this.osd.viewport.panBy(new OpenSeadragon.Point(-panBy.x,0)),_this.osd.viewport.applyConstraints()}),this.element.find(".mirador-osd-zoom-in").on("click",function(){var osd=_this.osd;osd.viewport&&(osd.viewport.zoomBy(osd.zoomPerClick/1),osd.viewport.applyConstraints())}),this.element.find(".mirador-osd-zoom-out").on("click",function(){var osd=_this.osd;osd.viewport&&(osd.viewport.zoomBy(1/osd.zoomPerClick),osd.viewport.applyConstraints())}),this.element.find(".mirador-osd-toggle-bottom-panel").on("click",function(){_this.eventEmitter.publish("TOGGLE_BOTTOM_PANEL_VISIBILITY."+_this.windowId)}),this.element.find(".mirador-osd-edit-mode").on("click",function(){var shape=jQuery(this).find(".material-icons").html();"pointer"===_this.hud.annoState.current?_this.hud.annoState.chooseShape(shape):_this.hud.annoState.changeShape(shape),_this.forceShowControls=!0,_this.element.find(".hud-control").stop(!0,!0).removeClass("hidden",_this.state.getStateProperty("fadeDuration"))}),this.element.find(".mirador-osd-pointer-mode").on("click",function(){"shape"===_this.hud.annoState.current&&(_this.hud.annoState.choosePointer(),_this.forceShowControls=!1)}),this.element.find(".mirador-osd-refresh-mode").on("click",function(){_this.eventEmitter.publish("updateAnnotationList."+_this.windowId)});var filterValues={brightness:"brightness(100%)",contrast:"contrast(100%)",saturate:"saturate(100%)",grayscale:"grayscale(0%)",invert:"invert(0%)"};function setFilterCSS(){var filterCSS=jQuery.map(filterValues,function(value,key){return value}).join(" ");jQuery(_this.osd.drawer.canvas).css({filter:filterCSS,"-webkit-filter":filterCSS,"-moz-filter":filterCSS,"-o-filter":filterCSS,"-ms-filter":filterCSS})}function resetImageManipulationControls(){_this.osd&&_this.osd.viewport.setRotation(0),filterValues.brightness="brightness(100%)",_this.element.find(".mirador-osd-brightness-slider").slider("option","value",100),_this.element.find(".mirador-osd-brightness-slider").find(".percent").text("100%"),filterValues.contrast="contrast(100%)",_this.element.find(".mirador-osd-contrast-slider").slider("option","value",100),_this.element.find(".mirador-osd-contrast-slider").find(".percent").text("100%"),filterValues.saturate="saturate(100%)",_this.element.find(".mirador-osd-saturation-slider").slider("option","value",100),_this.element.find(".mirador-osd-saturation-slider").find(".percent").text("100%"),filterValues.grayscale="grayscale(0%)",_this.element.find(".mirador-osd-grayscale").removeClass("selected"),filterValues.invert="invert(0%)",_this.element.find(".mirador-osd-invert").removeClass("selected"),jQuery(_this.osd.canvas).removeClass("mirador-mirror"),_this.originalDragHandler&&(_this.osd.viewport.viewer.innerTracker.dragHandler=_this.originalDragHandler),setFilterCSS()}this.element.find(".mirador-osd-rotate-right").on("click",function(){if(_this.osd){var currentRotation=_this.osd.viewport.getRotation();_this.osd.viewport.setRotation(currentRotation+90)}}),this.element.find(".mirador-osd-rotate-left").on("click",function(){if(_this.osd){var currentRotation=_this.osd.viewport.getRotation();_this.osd.viewport.setRotation(currentRotation-90)}}),this.element.find(".mirador-osd-brightness-slider").slider({orientation:"vertical",range:"min",min:0,max:200,value:100,create:function(event,ui){var v=jQuery(this).slider("value"),span=jQuery('').text(v+"%");jQuery(this).find(".ui-slider-handle").append(span)},slide:function(event,ui){filterValues.brightness="brightness("+ui.value+"%)",setFilterCSS(),jQuery(this).find(".percent").text(ui.value+"%")}}).hide(),this.element.find(".mirador-osd-brightness").on("mouseenter",function(){_this.element.find(".mirador-osd-brightness-slider").stop(!0,!0).show()}).on("mouseleave",function(){_this.element.find(".mirador-osd-brightness-slider").stop(!0,!0).hide()}),this.element.find(".mirador-osd-contrast-slider").slider({orientation:"vertical",range:"min",min:0,max:200,value:100,create:function(event,ui){var v=jQuery(this).slider("value"),span=jQuery('').text(v+"%");jQuery(this).find(".ui-slider-handle").append(span)},slide:function(event,ui){filterValues.contrast="contrast("+ui.value+"%)",setFilterCSS(),jQuery(this).find(".percent").text(ui.value+"%")}}).hide(),this.element.find(".mirador-osd-contrast").on("mouseenter",function(){_this.element.find(".mirador-osd-contrast-slider").stop(!0,!0).show()}).on("mouseleave",function(){_this.element.find(".mirador-osd-contrast-slider").stop(!0,!0).hide()}),this.element.find(".mirador-osd-saturation-slider").slider({orientation:"vertical",range:"min",min:0,max:200,value:100,create:function(event,ui){var v=jQuery(this).slider("value"),span=jQuery('').text(v+"%");jQuery(this).find(".ui-slider-handle").append(span)},slide:function(event,ui){filterValues.saturate="saturate("+ui.value+"%)",setFilterCSS(),jQuery(this).find(".percent").text(ui.value+"%")}}).hide(),this.element.find(".mirador-osd-saturation").on("mouseenter",function(){_this.element.find(".mirador-osd-saturation-slider").stop(!0,!0).show()}).on("mouseleave",function(){_this.element.find(".mirador-osd-saturation-slider").stop(!0,!0).hide()}),this.element.find(".mirador-osd-grayscale").on("click",function(){jQuery(this).hasClass("selected")?(filterValues.grayscale="grayscale(0%)",jQuery(this).removeClass("selected")):(filterValues.grayscale="grayscale(100%)",jQuery(this).addClass("selected")),setFilterCSS()}),this.element.find(".mirador-osd-invert").on("click",function(){jQuery(this).hasClass("selected")?(filterValues.invert="invert(0%)",jQuery(this).removeClass("selected")):(filterValues.invert="invert(100%)",jQuery(this).addClass("selected")),setFilterCSS()}),this.element.find(".mirador-osd-mirror").on("click",function(){if(_this.originalDragHandler||(_this.originalDragHandler=_this.osd.viewport&&_this.osd.viewport.viewer.innerTracker.dragHandler),jQuery(this).hasClass("selected"))jQuery(_this.osd.canvas).removeClass("mirador-mirror"),jQuery(this).removeClass("selected"),_this.eventEmitter.publish("disableManipulation","mirror"),_this.osd.viewport&&(_this.osd.viewport.viewer.innerTracker.dragHandler=_this.originalDragHandler),_this.horizontallyFlipped=!1;else{if(jQuery(_this.osd.canvas).addClass("mirador-mirror"),jQuery(this).addClass("selected"),_this.eventEmitter.publish("enableManipulation","mirror"),_this.osd.viewport){var viewer=_this.osd.viewport.viewer;viewer.innerTracker.dragHandler=OpenSeadragon.delegate(viewer,function(event){event.delta.x=-event.delta.x,_this.originalDragHandler(event)})}_this.horizontallyFlipped=!0}}),this.element.find(".mirador-osd-reset").on("click",function(){resetImageManipulationControls()}),this.eventEmitter.subscribe("resetImageManipulationControls."+this.windowId,function(){resetImageManipulationControls()})},currentCanvasIDUpdated:function(event,canvasId){var firstCanvasId=this.imagesList[0]["@id"],lastCanvasId=this.imagesList[this.imagesList.length-1]["@id"];canvasId===firstCanvasId?(this.element.find(".mirador-osd-previous").hide(),this.element.find(".mirador-osd-next").show()):(canvasId===lastCanvasId?this.element.find(".mirador-osd-next").hide():this.element.find(".mirador-osd-next").show(),this.element.find(".mirador-osd-previous").show())},loadImage:function(event,imageResource){var _this=this;if("drawn"!==imageResource.status){imageResource.setStatus("requested");var bounds=imageResource.getGlobalBounds();_this.osd.addTiledImage({x:bounds.x,y:bounds.y,width:bounds.width,tileSource:imageResource.tileSource,opacity:imageResource.opacity,clip:imageResource.clipRegion,index:imageResource.zIndex,success:function(event){var tiledImage=event.item;imageResource.osdTiledImage=tiledImage,imageResource.setStatus("loaded"),_this.syncAllImageResourceProperties(imageResource);var tileDrawnHandler=function(event){event.tiledImage===tiledImage&&(imageResource.setStatus("drawn"),_this.osd.removeHandler("tile-drawn",tileDrawnHandler))};_this.osd.addHandler("tile-drawn",tileDrawnHandler)},error:function(event){imageResource.setStatus("failed")}})}},showImage:function(event,imageResource){"drawn"===imageResource.getStatus()&&this.updateImageOpacity(null,imageResource)},hideImage:function(event,imageResource){"drawn"===imageResource.getStatus()&&imageResource.osdTiledImage.setOpacity(0)},removeImage:function(){},updateImageOpacity:function(event,imageResource){imageResource.osdTiledImage&&imageResource.osdTiledImage.setOpacity(imageResource.opacity*imageResource.parent.getOpacity())},syncAllImageResourceProperties:function(imageResource){if(imageResource.osdTiledImage){var bounds=imageResource.getGlobalBounds();imageResource.osdTiledImage.setPosition({x:bounds.x,y:bounds.y},!0),imageResource.osdTiledImage.setWidth(bounds.width,!0),imageResource.osdTiledImage.setOpacity(imageResource.getOpacity()*imageResource.parent.getOpacity())}},getPanByValue:function(){var bounds=this.osd.viewport.getBounds(!0);return{x:.5*bounds.width,y:.5*bounds.height}},setBounds:function(){this.osdOptions.osdBounds=this.osd.viewport.getBounds(!0),this.eventEmitter.publish("imageBoundsUpdated",{id:this.windowId,osdBounds:{x:this.osdOptions.osdBounds.x,y:this.osdOptions.osdBounds.y,width:this.osdOptions.osdBounds.width,height:this.osdOptions.osdBounds.height}});var rectangle=this.osdOptions.osdBounds;this.eventEmitter.publish("imageRectangleUpdated",{id:this.windowId,osdBounds:{x:Math.round(rectangle.x),y:Math.round(rectangle.y),width:Math.round(rectangle.width),height:Math.round(rectangle.height)},warning:"Warning, image rectangle now based on canvas dimensions, not the constituent images."})},toggle:function(stateValue){stateValue?this.show():this.hide()},hide:function(){jQuery(this.element).hide({effect:"fade",duration:300,easing:"easeOutCubic"})},show:function(){jQuery(this.element).show({effect:"fade",duration:300,easing:"easeInCubic",complete:function(){jQuery(this).css("display","block")}})},adjustWidth:function(className,hasClass){hasClass?this.eventEmitter.publish("REMOVE_CLASS."+this.windowId,className):this.eventEmitter.publish("ADD_CLASS."+this.windowId,className)},adjustHeight:function(className,hasClass){hasClass?this.element.removeClass(className):this.element.addClass(className)},initialiseImageCanvas:function(){var _this=this,osdID="mirador-osd-"+$.genUUID(),canvasModel=_this.canvases[_this.canvasID];_this.elemOsd=jQuery("
      ").addClass(_this.osdCls).attr("id",osdID).appendTo(_this.element),_this.osd=$.OpenSeadragon({id:osdID,uniqueID:osdID,preserveViewport:!0,blendTime:.1,alwaysBlend:!1,showNavigationControl:!1});var canvasBounds=canvasModel.getBounds(),rect=new OpenSeadragon.Rect(canvasBounds.x,canvasBounds.y,canvasBounds.width,canvasBounds.height);if(_this.osd.viewport.fitBounds(rect,!0),canvasModel.show(),canvasModel.getVisibleImages().forEach(function(imageResource){_this.loadImage(null,imageResource)}),_this.osd.addHandler("zoom",$.debounce(function(){var point={x:-1e7,y:-1e7};_this.eventEmitter.publish("updateTooltips."+_this.windowId,[point,point])},30)),_this.osd.addHandler("pan",$.debounce(function(){var point={x:-1e7,y:-1e7};_this.eventEmitter.publish("updateTooltips."+_this.windowId,[point,point])},30)),_this.eventEmitter.publish("osdOpen."+_this.windowId),_this.addAnnotationsLayer(_this.elemAnno),_this.osdOptions.osdBounds){var newBounds=new OpenSeadragon.Rect(_this.osdOptions.osdBounds.x,_this.osdOptions.osdBounds.y,_this.osdOptions.osdBounds.width,_this.osdOptions.osdBounds.height);_this.osd.viewport.fitBounds(newBounds,!0)}else _this.setBounds();var originalState=_this.hud.annoState.current,selected=_this.element.find(".mirador-osd-edit-mode.selected"),shape=null;selected&&(shape=selected.find(".material-icons").html()),"none"===originalState?_this.hud.annoState.startup():"off"===originalState||"off"===_this.annotationState||_this.hud.annoState.displayOff(),"pointer"===originalState||"on"===_this.annotationState?_this.hud.annoState.displayOn():"shape"===originalState&&(_this.hud.annoState.displayOn(),_this.hud.annoState.chooseShape(shape)),_this.osd.addHandler("zoom",$.debounce(function(){_this.setBounds()},500)),_this.osd.addHandler("pan",$.debounce(function(){_this.setBounds()},500))},addAnnotationsLayer:function(element){this.annotationsLayer=new $.AnnotationsLayer({state:this.state,annotationsList:this.state.getWindowAnnotationsList(this.windowId)||[],viewer:this.osd,windowId:this.windowId,element:element,eventEmitter:this.eventEmitter})},updateImage:function(canvasID){if(this.canvasID!==canvasID){this.canvases[this.canvasID].getVisibleImages().forEach(function(imageResource){imageResource.hide()}),this.canvasID=canvasID,this.currentImgIndex=$.getImageIndexById(this.imagesList,canvasID),this.currentImg=this.imagesList[this.currentImgIndex];var newCanvas=this.canvases[this.canvasID],canvasBounds=newCanvas.getBounds(),rect=new OpenSeadragon.Rect(canvasBounds.x,canvasBounds.y,canvasBounds.width,canvasBounds.height);this.osd.viewport.fitBounds(rect,!0),newCanvas.show(),this.osdOptions={osdBounds:null,zoomLevel:null},this.eventEmitter.publish("resetImageManipulationControls."+this.windowId)}this.eventEmitter.publish("UPDATE_FOCUS_IMAGES."+this.windowId,{array:[canvasID]})},next:function(){var next=this.currentImgIndex+1;next',"

      {{imagesFor}} {{canvasTitle}}

      ","{{#if hasLayers}}",'
        ',"{{#each layers}}",'
      • ',"

        {{this.title}}

        ",'
        ','{{canvasTitle}} title=','','','',"
        ","
        ","
        ",'',"","
        ",'",'',"
        ","
      • ","{{/each}}","
      ","{{else}}","

      {{emptyTemplateMessage}}

      ","{{/if}}",'
      ',"

      {{disabledLayersTabMessage}}

      ","
      ","
      "].join(""))}}(Mirador),function($){$.MetadataView=function(options){jQuery.extend(this,{manifest:null,element:null,metadataTypes:null,metadataListingCls:"metadata-listing"},options),this.init()},$.MetadataView.prototype={init:function(){var _this=this,tplData={metadataListingCls:this.metadataListingCls};if(_this.manifest=_this.manifest.jsonLd,this.metadataTypes={},this.metadataTypes.details=_this.getMetadataDetails(_this.manifest),this.metadataTypes.rights=_this.getMetadataRights(_this.manifest),this.metadataTypes.links=_this.getMetadataLinks(_this.manifest),jQuery.each(this.metadataTypes,function(metadataKey,metadataValues){tplData[metadataKey]=[],jQuery.each(metadataValues,function(idx,itm){"object"==typeof itm.value&&(itm.value=_this.stringifyObject(itm.value)),"string"==typeof itm.value&&""!==itm.value&&tplData[metadataKey].push({identifier:itm.identifier||"",label:_this.extractLabelFromAttribute(itm.label),value:"links"===metadataKey?itm.value:_this.addLinksToUris(itm.value)})})}),_this.manifest.logo){var logo="";"string"==typeof _this.manifest.logo?logo=_this.manifest.logo:void 0!==_this.manifest.logo["@id"]&&(logo=_this.manifest.logo["@id"]),tplData.logo=logo}this.element=jQuery(this.template(tplData)).appendTo(this.appendTo),this.bindEvents()},stringifyObject:function(obj,nestingMargin){var str,_this=this,first=!0;if(obj instanceof RegExp)return"/"+obj.source+"/";if(void 0===nestingMargin&&(nestingMargin=0),obj instanceof Array)return str="[ ",jQuery.each(obj,function(i,item){str+=(0===i?"":", ")+_this.stringifyObject(item,nestingMargin+15)}),str+" ]";if("object"==typeof obj&&"sc:Collection"===obj["@type"]){var collectionUrl=obj["@id"];return''+(obj.label||collectionUrl)+""}if("object"==typeof obj){for(var i in str='
      ',obj)obj.hasOwnProperty(i)&&(str+=(first?"":"
      ")+i+": "+_this.stringifyObject(obj[i],nestingMargin+15),first=!1);return str+"
      "}return obj.toString()},stringifyRelated:function(obj){var str,next,label,format,_this=this;return obj instanceof Array?(str="",jQuery.each(obj,function(i,item){""!==(next=_this.stringifyRelated(item))&&(str+=(0===i?"":"
      ")+next)}),str):"object"==typeof obj&&"@id"in obj?(label="label"in obj?obj.label:obj["@id"],format="format"in obj&&"text/html"!==obj.format?"("+obj.format+")":"",''+label+" "+format):_this.addLinksToUris(obj.toString())},getMetadataDetails:function(jsonLd){var mdList=[{label:i18next.t("label"),value:""+($.JsonLd.getTextValue(jsonLd.label)||"")+""},{label:i18next.t("description"),value:$.JsonLd.getTextValue(jsonLd.description)||""}];return jsonLd.metadata&&(value="",label="",jQuery.each(jsonLd.metadata,function(index,item){label=$.JsonLd.getTextValue(item.label),value=$.JsonLd.getTextValue(item.value),mdList.push({label:label,value:value})})),mdList},getMetadataRights:function(jsonLd){return[{identifier:"license",label:i18next.t("license"),value:jsonLd.license||""},{identifier:"attribution",label:i18next.t("attribution"),value:$.JsonLd.getTextValue(jsonLd.attribution)||""}]},getMetadataLinks:function(jsonLd){return[{identifier:"related",label:i18next.t("related"),value:this.stringifyRelated(jsonLd.related||"")},{identifier:"seeAlso",label:i18next.t("seeAlso"),value:this.stringifyRelated(jsonLd.seeAlso||"")},{identifier:"manifest",label:i18next.t("manifest"),value:this.stringifyRelated(jsonLd["@id"]||"")},{identifier:"within",label:i18next.t("within"),value:this.getWithin(jsonLd.within||"")}]},getWithin:function(within){if("object"==typeof within&&"sc:Collection"===within["@type"]){var collectionUrl=within["@id"];return''+(within.label||collectionUrl)+""}return within instanceof Array?within.map(this.getWithin,this).join("
      "):this.stringifyObject(within)},extractLabelFromAttribute:function(attr){var label=attr;return label=(label=label.replace(/^@/,"")).replace(/\s{2,}/g," ")},bindEvents:function(){},toggle:function(stateValue){stateValue?this.show():this.hide()},show:function(){var element=jQuery(this.element);this.panel&&(element=element.parent()),element.show({effect:"slide",direction:"right",duration:300,easing:"swing"})},hide:function(){var element=jQuery(this.element);this.panel&&(element=element.parent()),element.hide({effect:"slide",direction:"right",duration:300,easing:"swing"})},addLinksToUris:function(text){var matches,parsedTextWithLinks,textWithLinks=text;return"string"==typeof text&&(-1===textWithLinks.indexOf("'+match+"")}):(parsedTextWithLinks=jQuery("
      ").append(textWithLinks),jQuery(parsedTextWithLinks[0]).find("a").attr("target","_blank"),textWithLinks=parsedTextWithLinks[0].innerHTML)),textWithLinks},template:$.Handlebars.compile(['
      {{t "details"}}:
      ','
      ',"{{#each details}}",'',"{{/each}}","
      ",'
      {{t "rights"}}:
      ',"{{#if rights}}",'
      ',"{{#each rights}}",'',"{{/each}}","{{#if logo}}",'',"{{/if}}","
      ","{{else}}",'
      ','',"
      ","{{/if}}","{{#if links}}",'
      {{t "links"}}:
      ','
      ',"{{#each links}}",'',"{{/each}}","","{{/if}}"].join(""),{noEscape:!0})}}(Mirador),function($){$.ScrollView=function(options){jQuery.extend(this,{currentImgIndex:0,canvasID:null,focusImages:[],manifest:null,element:null,imagesList:[],appendTo:null,thumbInfo:{thumbsHeight:150,listingCssCls:"listing-thumbs",thumbnailCls:"thumbnail-view"},windowId:null,panel:!1,vDirectionStatus:"",lazyLoadingFactor:1.5},options),jQuery.extend($.ScrollView.prototype,$.ThumbnailsView.prototype),this.init(),"rtl"==this.vDirectionStatus&&jQuery(this.appendTo).find(".scroll-view").addClass("v-direction-rtl")}}(Mirador),function($){$.SearchTab=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,manifest:null,visible:null,canvasID:null,windowId:null,eventEmitter:null},options),this.init()},$.SearchTab.prototype={init:function(){this.windowId=this.windowId,this.localState({id:"searchTab",visible:this.visible},!0),this.listenForActions(),this.render(this.localState()),this.loadTabComponents()},localState:function(state,initial){return arguments.length&&(this.searchTabState=state,initial||this.eventEmitter.publish("searchTabStateUpdated."+this.windowId,this.searchTabState)),this.searchTabState},loadTabComponents:function(){},tabStateUpdated:function(data){"searchTab"===data.tabs[data.selectedTabIndex].options.id?this.element.show():this.element.hide()},toggle:function(){},listenForActions:function(){var _this=this;this.eventEmitter.subscribe("tabStateUpdated."+_this.windowId,function(_,data){_this.tabStateUpdated(data)})},displaySearchWithin:function(query_params,searchUrl){""!==query_params&&(this.searchObject=new $.SearchWithinResults({manifest:this.manifest,appendTo:this.element.find(".search-results-list"),panel:!0,canvasID:this.canvasID,windowId:this.windowId,imagesList:this.imagesList,thumbInfo:{thumbsHeight:80,listingCssCls:"panel-listing-thumbs",thumbnailCls:"panel-thumbnail-view"},query_params:query_params,searchService:searchUrl,eventEmitter:this.eventEmitter}))},bindEvents:function(){var _this=this;this.element.find(".js-perform-query").on("submit",function(event){event.preventDefault();var query=_this.element.find(".js-query").val(),motivation=_this.element.find(".js-motivation").val(),date=_this.element.find(".js-date").val(),user=_this.element.find(".js-user").val(),searchUrl=_this.element.find("#search-within-selector").val();_this.displaySearchWithin({q:query,motivation:motivation,date:date,user:user},searchUrl)}),this.element.find(".js-search-expand").on("click",function(event){event.preventDefault(),_this.element.find(".js-search-expanded").slideToggle("fast"),jQuery(this).text()===i18next.t("more")?jQuery(this).text(i18next.t("less")):jQuery(this).text()===i18next.t("less")&&jQuery(this).text(i18next.t("more"))})},render:function(state){var searchService=this.manifest.getSearchWithinService(),searchServiceIdArray=searchService&&searchService.map(function(data){return{url:data["@id"],label:data.label}});templateData={searchService:searchServiceIdArray},this.element?(this.appendTo.find(".search-results").remove(),this.element=jQuery(this.template(templateData)).appendTo(this.appendTo)):(this.element=jQuery(this.template(templateData)).appendTo(this.appendTo),this.bindEvents()),state.visible?this.element.show():this.element.hide()},template:$.Handlebars.compile(['
      ',"{{#if searchService}}",'','",'
      ','','','','","
      ",'
      ',"{{else}}",'{{t "searchNotAvailable"}}',"{{/if}}","
      "].join(""))}}(Mirador),function($){$.SearchWithinResults=function(options){jQuery.extend(this,{manifest:null,element:null,metadataTypes:null,metadataListingCls:"metadata-listing",searchService:null,windowId:null,query_params:null,currentPage:1,eventEmitter:null},options),this.init()},$.SearchWithinResults.prototype={init:function(){this.registerHandlebars(),jQuery(this.appendTo).empty(),this.element=jQuery(this.template()).appendTo(this.appendTo),jQuery("

      Search results for: "+this.query_params.q+"

      ").appendTo(this.appendTo.find(".search-results-messages")),this.doSearchFromQuery(this.query_params)},doSearchFromQuery:function(query_params){for(var param in query_string="",query_params)"q"===param?query_string+=param+"="+query_params[param]:0No results

      ")}).fail(function(){jQuery(".search-results-count").html("

      No results

      ")}).always()},displayResultCounts:function(searchResults){var total=searchResults.within.total,startResultNumber=searchResults.startIndex+1,endResultNumber="";endResultNumber=searchResults.resources.constructor===Array?searchResults.startIndex+searchResults.resources.length:searchResults.startIndex+1,jQuery(".search-results-count").html("

      Showing "+startResultNumber+" - "+endResultNumber+" out of "+total+"

      ")},processResults:function(searchResults){searchResults.hits?this.tplData=this.getHits(searchResults):this.tplData=this.getSearchAnnotations(searchResults),jQuery($.Handlebars.compile("{{> resultsList }}")(this.tplData)).appendTo(jQuery(this.element.find(".search-results-container"))),this.bindEvents(),this.setPager(searchResults)},needsPager:function(results){if(!results||!results.within||!results.resources)return!1;var total=results.within.total;return Array.isArray(results.resources)?results.resources.length',nextText:'',onPageClick:function(pageNumber,event){event.preventDefault(),pager.pagination("disable"),pageNumber==_this.currentPage-1?(_this.currentPage--,_this.doSearchFromUrl(searchResults.prev)):pageNumber==_this.currentPage+1?(_this.currentPage++,_this.doSearchFromUrl(searchResults.next)):1==pageNumber?(_this.doSearchFromUrl(searchResults.within.first),_this.currentPage=1):(_this.doSearchFromUrl(searchResults.within.last),_this.currentPage=parseInt(_this.element.find(".search-results-pager li:nth-last-child(2)").text()))}}),pager.pagination("enable"))},float2int:function(num){return 0|num},parseSearchAnnotation:function(annotation){var canvasid=annotation.on;"object"==typeof canvasid&&(canvasid=annotation.on["@id"]);var canvaslabel=this.getLabel(annotation),id_parts=this.splitBaseUrlAndCoordinates(canvasid);return{canvasid:id_parts.base,coordinates:id_parts.coords,canvaslabel:canvaslabel,resulttext:annotation.resource.chars}},getSearchAnnotations:function(searchResults){var _this=this;if(tplData=[],null!==searchResults.resources)return Array.isArray(searchResults.resources)?searchResults.resources.forEach(function(annotation){tplData.push(_this.parseSearchAnnotation(annotation))}):(annotation=searchResults.resources,tplData.push(_this.parseSearchAnnotation(annotation))),tplData},getHits:function(searchResults){var _this=this;return tplData=[],searchResults.hits.forEach(function(hit){var resultObject,resultObjects=[];hit.annotations.forEach(function(annotation){var resource=_this.getHitResources(searchResults,annotation)[0],canvasLabel=_this.getLabel(resource),canvasID=resource&&resource.on;"object"==typeof canvasID&&(canvasID=resource.on["@id"]);var canvasIDParts=_this.splitBaseUrlAndCoordinates(canvasID);resultObject={canvasid:canvasIDParts.base,coordinates:canvasIDParts.coords,canvaslabel:canvasLabel,hit:hit},resultObjects.push(resultObject)}),resultObjects&&(resultObject=resultObjects[0],1','',"{{canvaslabel}}","","{{#if annotations}}","
      ","Annotations: ","{{#each annotations}}",'','',"","{{/each}}","
      ","{{/if}}",'
      ',"{{#if hit.before}}","{{hit.before}} ","{{/if}}","{{#if hit.match}}",'{{hit.match}}',"{{else}}","{{{resulttext}}}","{{/if}}","{{#if hit.after}}","{{ hit.after}}","{{/if}}","
      ","
      ","{{/each}}"].join(""))},template:$.Handlebars.compile(["
      ",'
      ','
      ','
      ','
      ',"{{> resultsList }}","
      ","
      "].join(""))}}(Mirador),function($){$.SidePanel=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,manifest:null,panelState:{},tocTabAvailable:null,annotationsTabAvailable:!1,layersTabAvailable:!1,searchTabAvailable:null,hasStructures:!1,state:null,eventEmitter:null},options),this.init()},$.SidePanel.prototype={init:function(){this.updateState({tabs:[{name:"toc",options:{available:this.tocTabAvailable,id:"tocTab",label:i18next.t("tabTitleIndex")}},{name:"search",options:{available:this.searchTabAvailable,id:"searchTab",label:i18next.t("tabTitleSearch")}},{name:"layers",options:{available:this.layersTabAvailable,id:"layersTab",label:i18next.t("tabTitleLayers")}}],width:280,open:!0},!0),this.listenForActions(),this.render(this.updateState()),this.loadSidePanelComponents()},loadSidePanelComponents:function(){new $.Tabs({windowId:this.windowId,appendTo:this.appendTo,tabs:this.panelState.tabs,hasStructures:this.hasStructures,eventEmitter:this.eventEmitter}),this.tocTabAvailable&&new $.TableOfContents({structures:this.manifest.getStructures(),appendTo:this.element.find(".tabContentArea"),windowId:this.windowId,canvasID:this.canvasID,manifestVersion:this.manifest.getVersion(),eventEmitter:this.eventEmitter}),this.annotationsTabAvailable&&new $.AnnotationsTab({manifest:this.manifest,windowId:this.windowId,appendTo:this.element.find(".tabContentArea"),state:this.state,eventEmitter:this.eventEmitter}),this.searchTabAvailable&&new $.SearchTab({manifest:this.manifest,windowId:this.windowId,appendTo:this.element.find(".tabContentArea"),state:this.state,manifestVersion:this.manifest.getVersion(),eventEmitter:this.eventEmitter}),this.layersTabAvailable&&new $.LayersTab({manifest:this.manifest,windowId:this.windowId,appendTo:this.element.find(".tabContentArea"),canvasID:this.canvasID,canvases:this.canvases,state:this.state,eventEmitter:this.eventEmitter})},update:function(name,availability){var updatedState=this.panelState;jQuery.each(updatedState.tabs,function(index,value){value.name===name&&(value.options.available=availability)}),this.updateState(updatedState)},updateState:function(newState,initial){return arguments.length&&(jQuery.extend(!0,this.panelState,newState),initial||this.eventEmitter.publish("sidePanelStateUpdated."+this.windowId,this.panelState)),this.panelState},panelToggled:function(){var currentState=this.updateState(),open=!currentState.open;currentState.open=open,this.updateState(currentState)},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("sidePanelStateUpdated."+this.windowId,function(_,data){_this.render(data)}),_this.eventEmitter.subscribe("sidePanelResized",function(){}),_this.eventEmitter.subscribe("sidePanelToggled."+this.windowId,function(){_this.panelToggled()}),_this.eventEmitter.subscribe("annotationListLoaded."+_this.windowId,function(event){var windowObject=_this.state.getWindowObjectById(_this.windowId);windowObject.annotationsAvailable[windowObject.viewType]&&0<_this.state.getWindowAnnotationsList(_this.windowId).length&&_this.update("annotations",!0)}),_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,function(event,newCanvasId){_this.canvasID=newCanvasId})},render:function(renderingData){if(!this.element)return this.element=this.appendTo,void jQuery(this.template(renderingData)).appendTo(this.appendTo)},template:$.Handlebars.compile(['
      ','
        ',"
      ","
      "].join("")),toggle:function(enableSidePanel){enableSidePanel?(jQuery(this.appendTo).show({effect:"fade",duration:300,easing:"easeInCubic"}),this.eventEmitter.publish("REMOVE_CLASS."+this.windowId,"focus-max-width"),this.eventEmitter.publish("SHOW_ICON_TOC."+this.windowId)):(jQuery(this.appendTo).hide(),this.eventEmitter.publish("ADD_CLASS."+this.windowId,"focus-max-width"),this.eventEmitter.publish("HIDE_ICON_TOC."+this.windowId))}}}(Mirador),function($){$.WidgetStatusBar=function(options){jQuery.extend(!0,this,{},$.DEFAULT_SETTINGS,options)}}(Mirador),function($){$.Tabs=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,windowId:null,tabState:{},tabs:[],eventEmitter:null},options),this.init()},$.Tabs.prototype={init:function(){this.state({tabs:this.tabs,selectedTabIndex:0},!0),this.listenForActions(),this.render(this.state()),this.bindEvents()},state:function(state,initial){return arguments.length&&(jQuery.extend(!0,this.tabState,state),initial||this.eventEmitter.publish("tabStateUpdated."+this.windowId,this.tabState)),this.tabState},tabSelected:function(index){var state=this.state();state.selectedTabIndex=index,this.state(state)},getTemplateData:function(){return{annotationsTab:this.state().annotationsTab,tocTab:this.state().tocTab,searchTab:this.state().searchTab}},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("tabStateUpdated."+this.windowId,function(_,data){_this.render(data)}),_this.eventEmitter.subscribe("tabSelected."+this.windowId,function(_,data){_this.tabSelected(data)}),_this.eventEmitter.subscribe("tabFocused.",function(){})},bindEvents:function(){var _this=this;this.element.find(".tab").on("click",function(event){_this.eventEmitter.publish("tabSelected."+_this.windowId,jQuery(this).index())})},render:function(renderingData){if(!this.element){var tabs=jQuery.grep(renderingData.tabs,function(value,index){return value.options.available});return renderingData.tabs=tabs,1===renderingData.tabs.length&&("toc"!==renderingData.tabs[0].name||this.hasStructures||this.eventEmitter.publish("sidePanelVisibilityByTab."+this.windowId,!1),renderingData.tabs=[]),void(this.element=jQuery(this.template(renderingData)).prependTo(this.appendTo))}this.element.find(".tab").removeClass("selected");var tabClass="."+renderingData.tabs[renderingData.selectedTabIndex].options.id;this.element.find(tabClass).addClass("selected")},template:$.Handlebars.compile(['
        ',"{{#each tabs}}",'
      • ',"{{this.options.label}}","
      • ","{{/each}}","
      "].join("")),toggle:function(){}}}(Mirador),function($){$.ThumbnailsView=function(options){jQuery.extend(this,{currentImgIndex:0,canvasID:null,focusImages:[],manifest:null,element:null,imagesList:[],imagesListLtr:[],vDirectionStatus:"",appendTo:null,thumbInfo:{thumbsHeight:150,listingCssCls:"listing-thumbs",thumbnailCls:"thumbnail-view"},defaultThumbHeight:150,windowId:null,panel:!1,lazyLoadingFactor:1.5,eventEmitter:null},options),this.init()},$.ThumbnailsView.prototype={init:function(){if(null!==this.canvasID&&(this.currentImgIndex=$.getImageIndexById(this.imagesList,this.canvasID)),"rtl"==this.vDirectionStatus&&(this.imagesList=this.imagesListLtr.concat()),this.loadContent(),"rtl"==this.vDirectionStatus){this.imagesList[0]["@id"];jQuery(this.appendTo).find(".panel-thumbnail-view").addClass("v-direction-rtl"),jQuery(this.appendTo).find(".thumbnail-view").find("li").each(function(){jQuery(this).addClass("thumbnail-rtl")})}this.bindEvents(),this.listenForActions()},loadContent:function(){var _this=this,tplData={defaultHeight:this.thumbInfo.thumbsHeight,listingCssCls:this.thumbInfo.listingCssCls,thumbnailCls:this.thumbInfo.thumbnailCls};tplData.thumbs=jQuery.map(this.imagesList,function(canvas,index){if(0===canvas.width)return{};var aspectRatio=canvas.height/canvas.width,width=_this.thumbInfo.thumbsHeight/aspectRatio;return{thumbUrl:$.getThumbnailForCanvas(canvas,width),title:$.JsonLd.getTextValue(canvas.label),id:canvas["@id"],width:width,highlight:_this.currentImgIndex===index?"highlight":""}}),this.element=jQuery(_this.template(tplData)).appendTo(this.appendTo)},updateImage:function(canvasId){this.currentImgIndex=$.getImageIndexById(this.imagesList,canvasId),this.element.find(".highlight").removeClass("highlight"),this.element.find("img[data-image-id='"+canvasId+"']").addClass("highlight"),this.element.find("img[data-image-id='"+canvasId+"']").parent().addClass("highlight")},updateFocusImages:function(focusList){var _this=this;this.element.find(".highlight").removeClass("highlight"),jQuery.each(focusList,function(index,canvasId){_this.element.find("img[data-image-id='"+canvasId+"']").addClass("highlight"),_this.element.find("img[data-image-id='"+canvasId+"']").parent().addClass("highlight")})},currentImageChanged:function(){var scrollPosition,target=this.element.find(".highlight"),windowObject=this.state.getWindowObjectById(this.windowId);target.position()&&(scrollPosition=windowObject&&"BookView"===windowObject.viewType?this.element.scrollLeft()+(target.position().left+(target.next().width()+target.outerWidth())/2)-this.element.width()/2:this.element.scrollLeft()+(target.position().left+target.width()/2)-this.element.width()/2),this.element.scrollTo(scrollPosition,900)},listenForActions:function(){var _this=this;_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,function(event){_this.currentImageChanged()}),_this.eventEmitter.subscribe("windowResize",$.debounce(function(){_this.loadImages()},100))},bindEvents:function(){var _this=this;_this.element.find("img").on("load",function(){jQuery(this).hide().fadeIn(750,function(){jQuery(this).css("display","block")})}),jQuery(_this.element).scroll(function(){_this.loadImages()}),_this.element.find(".thumbnail-image").on("click",function(){var canvasID=jQuery(this).attr("data-image-id");_this.eventEmitter.publish("SET_CURRENT_CANVAS_ID."+_this.windowId,canvasID)})},toggle:function(stateValue){stateValue?this.show():this.hide()},loadImages:function(){var _this=this;jQuery.each(_this.element.find("img"),function(key,value){if($.isOnScreen(value,_this.lazyLoadingFactor)&&!jQuery(value).attr("src")){var url=jQuery(value).attr("data");_this.loadImage(value,url)}})},loadImage:function(imageElement,url){$.createImagePromise(url).done(function(image){jQuery(imageElement).attr("src",image)})},reloadImages:function(newThumbHeight,triggerShow){var _this=this;this.thumbInfo.thumbsHeight=newThumbHeight,jQuery.each(this.imagesList,function(index,image){var aspectRatio=image.height/image.width,width=_this.thumbInfo.thumbsHeight/aspectRatio,newThumbURL=$.getThumbnailForCanvas(image,width),id=image["@id"];_this.element.find('img[data-image-id="'+id+'"]').attr("data",newThumbURL).attr("height",_this.thumbInfo.thumbsHeight).attr("width",width).attr("src","")}),triggerShow&&this.show()},template:$.Handlebars.compile(['
      ','
        ',"{{#thumbs}}",'
      • ','','
        {{title}}
        ',"
      • ","{{/thumbs}}","
      ","
      "].join("")),hide:function(){var element=jQuery(this.element);this.panel&&(element=element.parent()),element.hide({effect:"fade",duration:300,easing:"easeOutCubic"})},show:function(){var element=jQuery(this.element);this.panel&&(element=element.parent());var _this=this;element.show({effect:"fade",duration:300,easing:"easeInCubic",complete:function(){jQuery(this).css("display","block"),_this.loadImages()}})},adjustWidth:function(className,hasClass){hasClass?this.eventEmitter.publish("REMOVE_CLASS."+this.windowId,className):this.eventEmitter.publish("ADD_CLASS."+this.windowId,className)},adjustHeight:function(className,hasClass){hasClass?this.element.removeClass(className):this.element.addClass(className)}}}(Mirador),function($){$.TableOfContents=function(options){jQuery.extend(!0,this,{element:null,appendTo:null,windowId:null,structures:[],manifestVersion:null,previousSelectedElements:[],selectedElements:[],previousOpenElements:[],openElements:[],hoveredElement:[],selectContext:null,tocData:{},active:null,eventEmitter:null},options),this.init();var self=this;window.render=function(){self.render()}},$.TableOfContents.prototype={init:function(){this.structures&&0!==this.structures.length?(this.element=jQuery(this.template({ranges:this.getTplData()})).appendTo(this.appendTo),this.tocData=this.initTocData(),this.setSelectedElements($.getRangeIDByCanvasID(this.structures,this.canvasID)),this.element.find(".has-child ul").hide(),this.render()):this.element=jQuery(this.emptyTemplate()).appendTo(this.appendTo),this.bindEvents()},tabStateUpdated:function(data){"tocTab"===data.tabs[data.selectedTabIndex].options.id?this.element.show():this.element.hide()},getTplData:function(){var ranges;this.structures.map(function(structure){return structure.id=structure["@id"],structure});switch(this.manifestVersion){case"1":ranges=this.extractV1RangeTrees(this.structures);break;case"2":ranges=this.extractV2RangeTrees(this.structures)}return ranges.length<2&&ranges[0].children&&(ranges=ranges[0].children),ranges},initTocData:function(){var _this=this,tocData={};return _this.structures.forEach(function(structure){var attrString='[data-rangeid="'+structure["@id"]+'"]';tocData[structure["@id"]]={element:_this.element.find(attrString).closest("li")}}),tocData},extractV1RangeTrees:function(rangeList){return function unflatten(flatRanges,parent,tree){tree=void 0!==tree?tree:[],parent=void 0!==parent?parent:{"@id":"root",label:"Table of Contents"};var children=jQuery.grep(flatRanges,function(child){return child.within||(child.within="root"),child.within==parent["@id"]});return children.length&&("root"===parent["@id"]?(children.forEach(function(child){child.level=0}),tree=children):(children.forEach(function(child){child.level=parent.level+1}),parent.children=children),jQuery.each(children,function(index,child){unflatten(flatRanges,child)})),tree}(rangeList)},extractV2RangeTrees:function(rangeList){return function unflatten(flatRanges,parent,tree){tree=void 0!==tree?tree:[];var children=[];if((parent=void 0!==parent?parent:{"@id":"root",label:"Table of Contents"}).ranges)jQuery.each(parent.ranges,function(index,id){id="object"==typeof id?id["@id"]:id;var child=jQuery.grep(flatRanges,function(range,index){if(range["@id"]===id)return range})[0];child&&children.push(child)});else if("root"===parent["@id"]){var top=jQuery.grep(flatRanges,function(range,index){if(range.hasOwnProperty("viewingHint")&&"top"===range.viewingHint)return range})[0];top&&children.push(top),0===children.length&&(jQuery.each(flatRanges,function(index,range){if(range.ranges)return children.push(range),!1}),0===children.length&&children.push({ranges:flatRanges}))}return children.length&&("root"===parent["@id"]?(children.forEach(function(child){child.level=0}),tree=children):(children.forEach(function(child){child.level=parent.level+1}),parent.children=children),jQuery.each(children,function(index,child){unflatten(flatRanges,child)})),tree}(rangeList)},render:function(){var _this=this,toDeselect=_this.previousSelectedElements.map(function(rangeID){return _this.tocData[rangeID].element}),toSelect=_this.selectedElements.map(function(rangeID){return _this.tocData[rangeID].element}),toOpen=_this.openElements.filter(function(rangeID){return-1===jQuery.inArray(rangeID,_this.previousOpenElements)}).map(function(rangeID){return _this.tocData[rangeID].element}),toClose=_this.previousOpenElements.filter(function(rangeID){return-1===jQuery.inArray(rangeID,_this.openElements)}).map(function(rangeID){return _this.tocData[rangeID].element});_this.previousSelectedElements!==_this.selectedElements?(toDeselect.forEach(function(element){element.removeClass("selected")}),toSelect.forEach(function(element){element.addClass("selected")}),toClose.forEach(function(element){element.removeClass("open"),element.find("ul:first").slideFadeToggle()}),toOpen.forEach(function(element){element.addClass("open").find("ul:first").slideFadeToggle()})):(toOpen.forEach(function(element){element.addClass("open").find("ul:first").slideFadeToggle()}),toClose.forEach(function(element){element.removeClass("open").find("ul:first").slideFadeToggle()}))},bindEvents:function(){var _this=this;_this.eventEmitter.subscribe("tabStateUpdated."+_this.windowId,function(_,data){_this.tabStateUpdated(data)}),_this.eventEmitter.subscribe("currentCanvasIDUpdated."+_this.windowId,function(event,canvasID){_this.structures&&(_this.setSelectedElements($.getRangeIDByCanvasID(_this.structures,canvasID)),_this.render())}),_this.element.find(".toc-link").on("click",function(event){event.stopPropagation();var rangeID=jQuery(this).data().rangeid,canvasID=jQuery.grep(_this.structures,function(item){return item["@id"]==rangeID})[0].canvases[0];_this.eventEmitter.publish("SET_CURRENT_CANVAS_ID."+_this.windowId,canvasID)}),_this.element.find(".toc-caret").on("click",function(event){event.stopPropagation();var rangeID=jQuery(this).parent().data().rangeid;_this.setOpenItem(rangeID),_this.render()})},setActive:function(active){this.active=active},setOpenItem:function(rangeID){var _this=this,alreadyOpen=-1!==jQuery.inArray(rangeID,_this.openElements);_this.previousOpenElements=_this.openElements,_this.openElements=alreadyOpen?_this.openElements.filter(function(elementID){return elementID!==rangeID}):_this.openElements.map(function(elementID){return elementID}).concat([rangeID])},setSelectedElements:function(rangeIDs){var _this=this;_this.previousSelectedElements=_this.selectedElements,_this.selectedElements=rangeIDs,_this.previousOpenElements=_this.openElements,_this.openElements=_this.openElements.filter(function(openElementID){return-1===jQuery.inArray(openElementID,_this.previousSelectedElements)}).concat(rangeIDs).filter(function(openElementID,index,openElements){return index===openElements.indexOf(openElementID)})},emptyTemplate:$.Handlebars.compile(['
        ','
      • ','

        {{t "noIndex"}}

        ',"
      "].join("")),template:function(tplData){var previousTemplate,template=$.Handlebars.compile(['
        ',"{{#nestedRangeLevel ranges}}",'
      • ',"{{{tocLevel id label level children}}}","{{#if children}}","
          ","{{{nestedRangeLevel children}}}","
        ","{{/if}}","
      • ","{{/nestedRangeLevel}}","
      "].join(""));return $.Handlebars.registerHelper("nestedRangeLevel",function(children,options){var out="";return void 0!==options.fn&&(previousTemplate=options.fn),children.forEach(function(child){child.label=$.JsonLd.getTextValue(child.label),out+=previousTemplate(child)}),out}),$.Handlebars.registerHelper("tocLevel",function(id,label,level,children){return"'+label+""}),template(tplData)},hide:function(){jQuery(this.appendTo).hide(),this.eventEmitter.publish("ADD_CLASS."+this.windowId,"focus-max-width")},show:function(){jQuery(this.appendTo).show({effect:"fade",duration:300,easing:"easeInCubic"}),this.eventEmitter.publish("REMOVE_CLASS."+this.windowId,"focus-max-width")}}}(Mirador),function($){$.DialogBuilder=function(container){this.container=container||jQuery(".window"),bootbox.setDefaults({container:this.container})},$.DialogBuilder.prototype={confirm:function(message,callback){return this._attachEvents(bootbox.confirm(message,callback))},dialog:function(opts){this._attachEvents(bootbox.dialog(opts))},_attachEvents:function(el){var _this=this;el.init(function(){jQuery(el).css("z-index",2e4),jQuery(".modal-backdrop").prependTo(_this.container).css("z-index",2e4)}),jQuery(el).on("hidden.bs.modal",function(){jQuery(".modal-backdrop").remove()})}}}(Mirador),function($){$.EventEmitter=function(config){jQuery.extend(!0,this,{debug:$.EventEmitter.debug,trace:$.EventEmitter.trace,debugExclude:$.EventEmitter.excludePatterns},config),this.emitterId=$.EventEmitter.nextId(),this.debug&&(this.logger=new $.EventEmitter.Logger({trace:this.trace,debugExclude:this.debugExclude}))},$.EventEmitter.id=0,$.EventEmitter.nextId=function(){return $.EventEmitter.id++,$.EventEmitter.id},$.EventEmitter.debug=!1,$.EventEmitter.trace=!1,$.EventEmitter.excludePatterns=[],$.EventEmitter.Logger=function(options){this.trace=options.trace,this.debugExclude=options.debugExclude,this.scaffoldMap={}},$.EventEmitter.Logger.prototype={log:function(){this.trace?console.trace.apply(console,arguments):console.log.apply(console,arguments)},exclude:function(str){for(var patterns=this.debugExclude,i=0;i"),text+=textToAdd}),$.sanitizeHtml(text)}return $.sanitizeHtml(propertyValue["@value"])}}}(Mirador),function($){$.LocalJSONBlobAPI=function(opts){this.options={storage:window.localStorage},jQuery.extend(this.options,opts)},$.LocalJSONBlobAPI.prototype={readSync:function(blobId){return JSON.parse(this.options.storage.getItem(blobId))},save:function(blob){var d,deferred=jQuery.Deferred(),uuid=(d=(new Date).getTime(),"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(c){var r=(d+16*Math.random())%16|0;return d=Math.floor(d/16),("x"===c?r:3&r|8).toString(16)}));return this.options.storage.setItem("BM-"+uuid,JSON.stringify(blob)),deferred.resolve("BM-"+uuid),deferred.promise()}}}(Mirador),Mirador.OpenSeadragon=function(options){return OpenSeadragon(jQuery.extend({preserveViewport:!0,visibilityRatio:1,minZoomLevel:0,defaultZoomLevel:0,blendTime:.1,alwaysBlend:!1,showNavigationControl:!1},options))},function($){$.SaveController=function(config){function index(previousValue,currentValue,currentIndex){var newObj={};return newObj[currentValue]=previousValue,newObj}jQuery.extend(!0,this,{currentConfig:null,originalConfig:null,shareEndpoint:null,historySize:null,sessionID:null,slots:[],eventEmitter:null}),config.availableAnnotationDrawingTools&&(config.availableAnnotationDrawingTools=jQuery.grep(config.availableAnnotationDrawingTools,function(element,index){return 0<=jQuery.inArray(element,$.DEFAULT_SETTINGS.availableAnnotationDrawingTools)})),config.mainMenuSettings&&!config.mainMenuSettings.buttons&&(config.mainMenuSettings.buttons={}),jQuery.each(config,function(key,value){if("string"==typeof key&&-1!==key.indexOf(".")){var object=key.split(".").reverse().reduce(index,value);delete config[key],jQuery.extend(!0,config,object)}}),function iterateStringify(object){for(var property in object)object.hasOwnProperty(property)&&(object[property]instanceof Array?object[property]=JSON.stringify(object[property]):"object"==typeof object[property]&&iterateStringify(object[property]))}(config);var newConfig=jQuery.extend(!0,{},$.DEFAULT_SETTINGS,config);!function iterateParse(object){for(var property in object)object.hasOwnProperty(property)&&("string"==typeof object[property]&&"["===object[property][0]?object[property]=JSON.parse(object[property]):"object"==typeof object[property]&&iterateParse(object[property]))}(newConfig),this.init(newConfig)},$.SaveController.prototype={init:function(config){if(this.eventEmitter=config.eventEmitter,!1===config.saveSession)return this.currentConfig=config,this.bindEvents(),!1;saveModule=config.jsonStorageEndpoint.module,saveOptions=config.jsonStorageEndpoint.options,this.storageModule=new $[saveModule](saveOptions);var sessionID=window.location.hash.substring(1);if(this.sessionID=sessionID||$.genUUID(),localStorage.getItem(this.sessionID))this.currentConfig=JSON.parse(localStorage.getItem(sessionID));else{var paramURL=window.location.search.substring(1);if(paramURL){var jsonblob=paramURL.split("=")[1];this.currentConfig=this.storageModule.readSync(jsonblob)||config}else this.currentConfig=config}this.currentConfig.windowObjects=jQuery.map(this.currentConfig.windowObjects,function(value,index){return 0===Object.keys(value).length?null:value}),this.currentConfig.windowObjects&&jQuery.each(this.currentConfig.windowObjects,function(index,window){window.id||(window.id=$.genUUID())});var cleanURL=window.location.href.replace(window.location.search,"");window.location.hash?history.replaceState(this.currentConfig,"Mirador Session",cleanURL):history.replaceState(this.currentConfig,"Mirador Session",cleanURL+"#"+this.sessionID),this.bindEvents()},getWindowObjectById:function(windowId){var returnObject=null;return jQuery.each(this.currentConfig.windowObjects,function(index,window){if(window.id===windowId)return returnObject=window,!1}),returnObject},getWindowAnnotationsList:function(windowId){return this.windowsAnnotationsLists?this.windowsAnnotationsLists[windowId]:null},getSlots:function(){return this.slots},getWindowElement:function(windowId){return this.windowsElements?this.windowsElements[windowId]:null},getStateProperty:function(prop){return this.get(prop,"currentConfig")},getManifestIndex:function(manifestUri){var manifestIndex=-1;return jQuery.each(this.currentConfig.data,function(index,dataObj){if(dataObj.manifestUri===manifestUri)return manifestIndex=index,!1}),manifestIndex},get:function(prop,parent){return parent?this[parent][prop]:this[prop]},set:function(prop,value,options){options?this[options.parent][prop]=value:this[prop]=value,this.currentConfig.saveSession&&this.save(),this.eventEmitter.publish("saveControllerConfigUpdated")},bindEvents:function(){var _this=this;_this.eventEmitter.subscribe("manifestsPanelVisible.set",function(event,manifestPanelVisible){_this.set("manifestPanelVisible",manifestPanelVisible,{parent:"currentConfig"})}),_this.eventEmitter.subscribe("windowUpdated",function(event,options){var windowObjects=_this.currentConfig.windowObjects;windowObjects&&0bounds.right||viewport.bottombounds.bottom)},$.getRangeIDByCanvasID=function(structures,canvasID){var ranges=jQuery.grep(structures,function(range){return-1 0 && lists[0].nodeName === listName); - }); - }; - }; - var updateSelection = function (editor) { - return function (e) { - var listStyleType = $_1naauq85jgqkwz0h.getSelectedStyleType(editor); - e.control.items().each(function (ctrl) { - ctrl.active(ctrl.settings.data === listStyleType); - }); - }; - }; - var addSplitButton = function (editor, id, tooltip, cmd, nodeName, styles) { - editor.addButton(id, { - active: false, - type: 'splitbutton', - tooltip: tooltip, - menu: $_aeca1z86jgqkwz0i.toMenuItems(styles), - onPostRender: listState(editor, nodeName), - onshow: updateSelection(editor), - onselect: function (e) { - $_1v2scj82jgqkwz02.applyListFormat(editor, nodeName, e.control.settings.data); - }, - onclick: function () { - editor.execCommand(cmd); - } - }); - }; - var addButton = function (editor, id, tooltip, cmd, nodeName, styles) { - editor.addButton(id, { - active: false, - type: 'button', - tooltip: tooltip, - onPostRender: listState(editor, nodeName), - onclick: function () { - editor.execCommand(cmd); - } - }); - }; - var addControl = function (editor, id, tooltip, cmd, nodeName, styles) { - if (styles.length > 0) { - addSplitButton(editor, id, tooltip, cmd, nodeName, styles); - } else { - addButton(editor, id, tooltip, cmd, nodeName, styles); - } - }; - var register$1 = function (editor) { - addControl(editor, 'numlist', 'Numbered list', 'InsertOrderedList', 'OL', $_fhcb9h84jgqkwz0g.getNumberStyles(editor)); - addControl(editor, 'bullist', 'Bullet list', 'InsertUnorderedList', 'UL', $_fhcb9h84jgqkwz0g.getBulletStyles(editor)); - }; - var $_1qdmeg83jgqkwz0d = { register: register$1 }; - - global.add('advlist', function (editor) { - var hasPlugin = function (editor, plugin) { - var plugins = editor.settings.plugins ? editor.settings.plugins : ''; - return global$1.inArray(plugins.split(/[ ,]/), plugin) !== -1; - }; - if (hasPlugin(editor, 'lists')) { - $_1qdmeg83jgqkwz0d.register(editor); - $_5pnu5681jgqkwz00.register(editor); - } - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/advlist/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/advlist/plugin.min.js deleted file mode 100755 index 122cd8ff..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/advlist/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),s=function(t,e,n){var r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===n?null:{"list-style-type":n})},o=function(n){n.addCommand("ApplyUnorderedListStyle",function(t,e){s(n,"UL",e["list-style-type"])}),n.addCommand("ApplyOrderedListStyle",function(t,e){s(n,"OL",e["list-style-type"])})},e=function(t){var e=t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return e?e.split(/[ ,]/):[]},n=function(t){var e=t.getParam("advlist_bullet_styles","default,circle,disc,square");return e?e.split(/[ ,]/):[]},u=function(t){return t&&/^(TH|TD)$/.test(t.nodeName)},c=function(r){return function(t){return t&&/^(OL|UL|DL)$/.test(t.nodeName)&&(n=t,(e=r).$.contains(e.getBody(),n));var e,n}},d=function(t){var e=t.dom.getParent(t.selection.getNode(),"ol,ul");return t.dom.getStyle(e,"listStyleType")||""},p=function(t){return a.map(t,function(t){return{text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"===t?"":t}})},f=function(i,l){return function(t){var o=t.control;i.on("NodeChange",function(t){var e=function(t,e){for(var n=0;n len) { - index = len; - } - } - return index; - }; - var setStart = function (rng, container, offset) { - if (container.nodeType !== 1 || container.hasChildNodes()) { - rng.setStart(container, scopeIndex(container, offset)); - } else { - rng.setStartBefore(container); - } - }; - var setEnd = function (rng, container, offset) { - if (container.nodeType !== 1 || container.hasChildNodes()) { - rng.setEnd(container, scopeIndex(container, offset)); - } else { - rng.setEndAfter(container); - } - }; - var parseCurrentLine = function (editor, endOffset, delimiter) { - var rng, end, start, endContainer, bookmark, text, matches, prev, len, rngText; - var autoLinkPattern = $_3bi3tb8ijgqkwz1j.getAutoLinkPattern(editor); - var defaultLinkTarget = $_3bi3tb8ijgqkwz1j.getDefaultLinkTarget(editor); - if (editor.selection.getNode().tagName === 'A') { - return; - } - rng = editor.selection.getRng(true).cloneRange(); - if (rng.startOffset < 5) { - prev = rng.endContainer.previousSibling; - if (!prev) { - if (!rng.endContainer.firstChild || !rng.endContainer.firstChild.nextSibling) { - return; - } - prev = rng.endContainer.firstChild.nextSibling; - } - len = prev.length; - setStart(rng, prev, len); - setEnd(rng, prev, len); - if (rng.endOffset < 5) { - return; - } - end = rng.endOffset; - endContainer = prev; - } else { - endContainer = rng.endContainer; - if (endContainer.nodeType !== 3 && endContainer.firstChild) { - while (endContainer.nodeType !== 3 && endContainer.firstChild) { - endContainer = endContainer.firstChild; - } - if (endContainer.nodeType === 3) { - setStart(rng, endContainer, 0); - setEnd(rng, endContainer, endContainer.nodeValue.length); - } - } - if (rng.endOffset === 1) { - end = 2; - } else { - end = rng.endOffset - 1 - endOffset; - } - } - start = end; - do { - setStart(rng, endContainer, end >= 2 ? end - 2 : 0); - setEnd(rng, endContainer, end >= 1 ? end - 1 : 0); - end -= 1; - rngText = rng.toString(); - } while (rngText !== ' ' && rngText !== '' && rngText.charCodeAt(0) !== 160 && end - 2 >= 0 && rngText !== delimiter); - if (rangeEqualsDelimiterOrSpace(rng.toString(), delimiter)) { - setStart(rng, endContainer, end); - setEnd(rng, endContainer, start); - end += 1; - } else if (rng.startOffset === 0) { - setStart(rng, endContainer, 0); - setEnd(rng, endContainer, start); - } else { - setStart(rng, endContainer, end); - setEnd(rng, endContainer, start); - } - text = rng.toString(); - if (text.charAt(text.length - 1) === '.') { - setEnd(rng, endContainer, start - 1); - } - text = rng.toString().trim(); - matches = text.match(autoLinkPattern); - if (matches) { - if (matches[1] === 'www.') { - matches[1] = 'http://www.'; - } else if (/@$/.test(matches[1]) && !/^mailto:/.test(matches[1])) { - matches[1] = 'mailto:' + matches[1]; - } - bookmark = editor.selection.getBookmark(); - editor.selection.setRng(rng); - editor.execCommand('createlink', false, matches[1] + matches[2]); - if (defaultLinkTarget) { - editor.dom.setAttrib(editor.selection.getNode(), 'target', defaultLinkTarget); - } - editor.selection.moveToBookmark(bookmark); - editor.nodeChanged(); - } - }; - var setup = function (editor) { - var autoUrlDetectState; - editor.on('keydown', function (e) { - if (e.keyCode === 13) { - return handleEnter(editor); - } - }); - if (global$1.ie) { - editor.on('focus', function () { - if (!autoUrlDetectState) { - autoUrlDetectState = true; - try { - editor.execCommand('AutoUrlDetect', false, true); - } catch (ex) { - } - } - }); - return; - } - editor.on('keypress', function (e) { - if (e.keyCode === 41) { - return handleEclipse(editor); - } - }); - editor.on('keyup', function (e) { - if (e.keyCode === 32) { - return handleSpacebar(editor); - } - }); - }; - var $_54s8gy8gjgqkwz1f = { setup: setup }; - - global.add('autolink', function (editor) { - $_54s8gy8gjgqkwz1f.setup(editor); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/autolink/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/autolink/plugin.min.js deleted file mode 100755 index 1238a1d2..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/autolink/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.Env"),m=function(e){return e.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},y=function(e){return e.getParam("default_link_target","")},o=function(e,t){if(t<0&&(t=0),3===e.nodeType){var n=e.data.length;n $_8v9kpr8qjgqkwz30.getAutoResizeMinHeight(editor)) { - resizeHeight = myHeight; - } - var maxHeight = $_8v9kpr8qjgqkwz30.getAutoResizeMaxHeight(editor); - if (maxHeight && myHeight > maxHeight) { - resizeHeight = maxHeight; - toggleScrolling(editor, true); - } else { - toggleScrolling(editor, false); - } - if (resizeHeight !== oldSize.get()) { - deltaSize = resizeHeight - oldSize.get(); - dom.setStyle(editor.iframeElement, 'height', resizeHeight + 'px'); - oldSize.set(resizeHeight); - if (global$1.webkit && deltaSize < 0) { - resize(editor, oldSize); - } - } - }; - var setup = function (editor, oldSize) { - editor.on('init', function () { - var overflowPadding, bottomMargin; - var dom = editor.dom; - overflowPadding = $_8v9kpr8qjgqkwz30.getAutoResizeOverflowPadding(editor); - bottomMargin = $_8v9kpr8qjgqkwz30.getAutoResizeBottomMargin(editor); - if (overflowPadding !== false) { - dom.setStyles(editor.getBody(), { - paddingLeft: overflowPadding, - paddingRight: overflowPadding - }); - } - if (bottomMargin !== false) { - dom.setStyles(editor.getBody(), { paddingBottom: bottomMargin }); - } - }); - editor.on('nodechange setcontent keyup FullscreenStateChanged', function (e) { - resize(editor, oldSize); - }); - if ($_8v9kpr8qjgqkwz30.shouldAutoResizeOnInit(editor)) { - editor.on('init', function () { - wait(editor, oldSize, 20, 100, function () { - wait(editor, oldSize, 5, 1000); - }); - }); - } - }; - var $_4cqwty8njgqkwz24 = { - setup: setup, - resize: resize - }; - - var register = function (editor, oldSize) { - editor.addCommand('mceAutoResize', function () { - $_4cqwty8njgqkwz24.resize(editor, oldSize); - }); - }; - var $_bumeim8mjgqkwz23 = { register: register }; - - global.add('autoresize', function (editor) { - if (!editor.inline) { - var oldSize = Cell(0); - $_bumeim8mjgqkwz23.register(editor, oldSize); - $_4cqwty8njgqkwz24.setup(editor, oldSize); - } - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/autoresize/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/autoresize/plugin.min.js deleted file mode 100755 index f6394567..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/autoresize/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var i=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return i(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),y=tinymce.util.Tools.resolve("tinymce.Env"),r=tinymce.util.Tools.resolve("tinymce.util.Delay"),h=function(t){return parseInt(t.getParam("autoresize_min_height",t.getElement().offsetHeight),10)},v=function(t){return parseInt(t.getParam("autoresize_max_height",0),10)},o=function(t){return t.getParam("autoresize_overflow_padding",1)},a=function(t){return t.getParam("autoresize_bottom_margin",50)},n=function(t){return t.getParam("autoresize_on_init",!0)},u=function(t,e,n,i,o){r.setEditorTimeout(t,function(){_(t,e),n--?u(t,e,n,i,o):o&&o()},i)},S=function(t,e){var n=t.getBody();n&&(n.style.overflowY=e?"":"hidden",e||(n.scrollTop=0))},_=function(t,e){var n,i,o,r,a,u,s,l,g,c,f,d=t.dom;if(i=t.getDoc())if((m=t).plugins.fullscreen&&m.plugins.fullscreen.isFullscreen())S(t,!0);else{var m;o=i.body,r=h(t),u=d.getStyle(o,"margin-top",!0),s=d.getStyle(o,"margin-bottom",!0),l=d.getStyle(o,"padding-top",!0),g=d.getStyle(o,"padding-bottom",!0),c=d.getStyle(o,"border-top-width",!0),f=d.getStyle(o,"border-bottom-width",!0),a=o.offsetHeight+parseInt(u,10)+parseInt(s,10)+parseInt(l,10)+parseInt(g,10)+parseInt(c,10)+parseInt(f,10),(isNaN(a)||a<=0)&&(a=y.ie?o.scrollHeight:y.webkit&&0===o.clientHeight?0:o.offsetHeight),a>h(t)&&(r=a);var p=v(t);p&&p]*>((\xA0| |[ \t]|]*>)+?|)|
      $', 'i').test(html); - }; - var hasDraft = function (editor) { - var time = parseInt(global$1.getItem($_bmc41q8zjgqkwz3n.getAutoSavePrefix(editor) + 'time'), 10) || 0; - if (new Date().getTime() - time > $_bmc41q8zjgqkwz3n.getAutoSaveRetention(editor)) { - removeDraft(editor, false); - return false; - } - return true; - }; - var removeDraft = function (editor, fire) { - var prefix = $_bmc41q8zjgqkwz3n.getAutoSavePrefix(editor); - global$1.removeItem(prefix + 'draft'); - global$1.removeItem(prefix + 'time'); - if (fire !== false) { - $_5u0zvw8yjgqkwz3m.fireRemoveDraft(editor); - } - }; - var storeDraft = function (editor) { - var prefix = $_bmc41q8zjgqkwz3n.getAutoSavePrefix(editor); - if (!isEmpty(editor) && editor.isDirty()) { - global$1.setItem(prefix + 'draft', editor.getContent({ - format: 'raw', - no_events: true - })); - global$1.setItem(prefix + 'time', new Date().getTime().toString()); - $_5u0zvw8yjgqkwz3m.fireStoreDraft(editor); - } - }; - var restoreDraft = function (editor) { - var prefix = $_bmc41q8zjgqkwz3n.getAutoSavePrefix(editor); - if (hasDraft(editor)) { - editor.setContent(global$1.getItem(prefix + 'draft'), { format: 'raw' }); - $_5u0zvw8yjgqkwz3m.fireRestoreDraft(editor); - } - }; - var startStoreDraft = function (editor, started) { - var interval = $_bmc41q8zjgqkwz3n.getAutoSaveInterval(editor); - if (!started.get()) { - setInterval(function () { - if (!editor.removed) { - storeDraft(editor); - } - }, interval); - started.set(true); - } - }; - var restoreLastDraft = function (editor) { - editor.undoManager.transact(function () { - restoreDraft(editor); - removeDraft(editor); - }); - editor.focus(); - }; - var $_6dv4hf8vjgqkwz3i = { - isEmpty: isEmpty, - hasDraft: hasDraft, - removeDraft: removeDraft, - storeDraft: storeDraft, - restoreDraft: restoreDraft, - startStoreDraft: startStoreDraft, - restoreLastDraft: restoreLastDraft - }; - - var curry = function (f, editor) { - return function () { - var args = Array.prototype.slice.call(arguments); - return f.apply(null, [editor].concat(args)); - }; - }; - var get = function (editor) { - return { - hasDraft: curry($_6dv4hf8vjgqkwz3i.hasDraft, editor), - storeDraft: curry($_6dv4hf8vjgqkwz3i.storeDraft, editor), - restoreDraft: curry($_6dv4hf8vjgqkwz3i.restoreDraft, editor), - removeDraft: curry($_6dv4hf8vjgqkwz3i.removeDraft, editor), - isEmpty: curry($_6dv4hf8vjgqkwz3i.isEmpty, editor) - }; - }; - var $_fv013l8ujgqkwz3h = { get: get }; - - var global$3 = tinymce.util.Tools.resolve('tinymce.EditorManager'); - - global$3._beforeUnloadHandler = function () { - var msg; - global$2.each(global$3.get(), function (editor) { - if (editor.plugins.autosave) { - editor.plugins.autosave.storeDraft(); - } - if (!msg && editor.isDirty() && $_bmc41q8zjgqkwz3n.shouldAskBeforeUnload(editor)) { - msg = editor.translate('You have unsaved changes are you sure you want to navigate away?'); - } - }); - return msg; - }; - var setup = function (editor) { - window.onbeforeunload = global$3._beforeUnloadHandler; - }; - var $_8qpkk491jgqkwz3p = { setup: setup }; - - var postRender = function (editor, started) { - return function (e) { - var ctrl = e.control; - ctrl.disabled(!$_6dv4hf8vjgqkwz3i.hasDraft(editor)); - editor.on('StoreDraft RestoreDraft RemoveDraft', function () { - ctrl.disabled(!$_6dv4hf8vjgqkwz3i.hasDraft(editor)); - }); - $_6dv4hf8vjgqkwz3i.startStoreDraft(editor, started); - }; - }; - var register = function (editor, started) { - editor.addButton('restoredraft', { - title: 'Restore last draft', - onclick: function () { - $_6dv4hf8vjgqkwz3i.restoreLastDraft(editor); - }, - onPostRender: postRender(editor, started) - }); - editor.addMenuItem('restoredraft', { - text: 'Restore last draft', - onclick: function () { - $_6dv4hf8vjgqkwz3i.restoreLastDraft(editor); - }, - onPostRender: postRender(editor, started), - context: 'file' - }); - }; - var $_4s5vom93jgqkwz3r = { register: register }; - - global.add('autosave', function (editor) { - var started = Cell(false); - $_8qpkk491jgqkwz3p.setup(editor); - $_4s5vom93jgqkwz3r.register(editor, started); - return $_fv013l8ujgqkwz3h.get(editor); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/autosave/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/autosave/plugin.min.js deleted file mode 100755 index 0d05edb3..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/autosave/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var n=function(t){var e=t,r=function(){return e};return{get:r,set:function(t){e=t},clone:function(){return n(r())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),r=function(t){return t.fire("RestoreDraft")},i=function(t){return t.fire("StoreDraft")},s=function(t){return t.fire("RemoveDraft")},e=function(t,e){return((t=/^(\d+)([ms]?)$/.exec(""+(t||e)))[2]?{s:1e3,m:6e4}[t[2]]:1)*parseInt(t,10)},u=function(t){return t.getParam("autosave_ask_before_unload",!0)},f=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,document.location.pathname)).replace(/\{query\}/g,document.location.search)).replace(/\{hash\}/g,document.location.hash)).replace(/\{id\}/g,t.id)},c=function(t){return e(t.settings.autosave_interval,"30s")},l=function(t){return e(t.settings.autosave_retention,"20m")},m=function(t,e){var r=t.settings.forced_root_block;return""===(e=o.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+r+"[^>]*>((\xa0| |[ \t]|]*>)+?|)|
      $","i").test(e)},v=function(t){var e=parseInt(a.getItem(f(t)+"time"),10)||0;return!((new Date).getTime()-e>l(t)&&(d(t,!1),1))},d=function(t,e){var r=f(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&s(t)},D=function(t){var e=f(t);!m(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),i(t))},g=function(t){var e=f(t);v(t)&&(t.setContent(a.getItem(e+"draft"),{format:"raw"}),r(t))},y={isEmpty:m,hasDraft:v,removeDraft:d,storeDraft:D,restoreDraft:g,startStoreDraft:function(t,e){var r=c(t);e.get()||(setInterval(function(){t.removed||D(t)},r),e.set(!0))},restoreLastDraft:function(t){t.undoManager.transact(function(){g(t),d(t)}),t.focus()}},p=function(e,r){return function(){var t=Array.prototype.slice.call(arguments);return e.apply(null,[r].concat(t))}},h=function(t){return{hasDraft:p(y.hasDraft,t),storeDraft:p(y.storeDraft,t),restoreDraft:p(y.restoreDraft,t),removeDraft:p(y.removeDraft,t),isEmpty:p(y.isEmpty,t)}},_=tinymce.util.Tools.resolve("tinymce.EditorManager");_._beforeUnloadHandler=function(){var e;return o.each(_.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e};var b=function(t){window.onbeforeunload=_._beforeUnloadHandler},I=function(r,n){return function(t){var e=t.control;e.disabled(!y.hasDraft(r)),r.on("StoreDraft RestoreDraft RemoveDraft",function(){e.disabled(!y.hasDraft(r))}),y.startStoreDraft(r,n)}},w=function(t,e){t.addButton("restoredraft",{title:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e)}),t.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e),context:"file"})};t.add("autosave",function(t){var e=n(!1);return b(t),w(t,e),h(t)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/index.js deleted file mode 100755 index 2dd534e6..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "bbcode" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/bbcode') -// ES2015: -// import 'tinymce/plugins/bbcode' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.js deleted file mode 100755 index 10bb7cb9..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.js +++ /dev/null @@ -1,101 +0,0 @@ -(function () { -var bbcode = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); - - var html2bbcode = function (s) { - s = global$1.trim(s); - var rep = function (re, str) { - s = s.replace(re, str); - }; - rep(/(.*?)<\/a>/gi, '[url=$1]$2[/url]'); - rep(/(.*?)<\/font>/gi, '[code][color=$1]$2[/color][/code]'); - rep(/(.*?)<\/font>/gi, '[quote][color=$1]$2[/color][/quote]'); - rep(/(.*?)<\/font>/gi, '[code][color=$1]$2[/color][/code]'); - rep(/(.*?)<\/font>/gi, '[quote][color=$1]$2[/color][/quote]'); - rep(/(.*?)<\/span>/gi, '[color=$1]$2[/color]'); - rep(/(.*?)<\/font>/gi, '[color=$1]$2[/color]'); - rep(/(.*?)<\/span>/gi, '[size=$1]$2[/size]'); - rep(/(.*?)<\/font>/gi, '$1'); - rep(//gi, '[img]$1[/img]'); - rep(/(.*?)<\/span>/gi, '[code]$1[/code]'); - rep(/(.*?)<\/span>/gi, '[quote]$1[/quote]'); - rep(/(.*?)<\/strong>/gi, '[code][b]$1[/b][/code]'); - rep(/(.*?)<\/strong>/gi, '[quote][b]$1[/b][/quote]'); - rep(/(.*?)<\/em>/gi, '[code][i]$1[/i][/code]'); - rep(/(.*?)<\/em>/gi, '[quote][i]$1[/i][/quote]'); - rep(/(.*?)<\/u>/gi, '[code][u]$1[/u][/code]'); - rep(/(.*?)<\/u>/gi, '[quote][u]$1[/u][/quote]'); - rep(/<\/(strong|b)>/gi, '[/b]'); - rep(/<(strong|b)>/gi, '[b]'); - rep(/<\/(em|i)>/gi, '[/i]'); - rep(/<(em|i)>/gi, '[i]'); - rep(/<\/u>/gi, '[/u]'); - rep(/(.*?)<\/span>/gi, '[u]$1[/u]'); - rep(//gi, '[u]'); - rep(/]*>/gi, '[quote]'); - rep(/<\/blockquote>/gi, '[/quote]'); - rep(/
      /gi, '\n'); - rep(//gi, '\n'); - rep(/
      /gi, '\n'); - rep(/

      /gi, ''); - rep(/<\/p>/gi, '\n'); - rep(/ |\u00a0/gi, ' '); - rep(/"/gi, '"'); - rep(/</gi, '<'); - rep(/>/gi, '>'); - rep(/&/gi, '&'); - return s; - }; - var bbcode2html = function (s) { - s = global$1.trim(s); - var rep = function (re, str) { - s = s.replace(re, str); - }; - rep(/\n/gi, '
      '); - rep(/\[b\]/gi, ''); - rep(/\[\/b\]/gi, ''); - rep(/\[i\]/gi, ''); - rep(/\[\/i\]/gi, ''); - rep(/\[u\]/gi, ''); - rep(/\[\/u\]/gi, ''); - rep(/\[url=([^\]]+)\](.*?)\[\/url\]/gi, '$2'); - rep(/\[url\](.*?)\[\/url\]/gi, '$1'); - rep(/\[img\](.*?)\[\/img\]/gi, ''); - rep(/\[color=(.*?)\](.*?)\[\/color\]/gi, '$2'); - rep(/\[code\](.*?)\[\/code\]/gi, '$1 '); - rep(/\[quote.*?\](.*?)\[\/quote\]/gi, '$1 '); - return s; - }; - var $_36akuw96jgqkwz4e = { - html2bbcode: html2bbcode, - bbcode2html: bbcode2html - }; - - global.add('bbcode', function () { - return { - init: function (editor) { - editor.on('beforeSetContent', function (e) { - e.content = $_36akuw96jgqkwz4e.bbcode2html(e.content); - }); - editor.on('postProcess', function (e) { - if (e.set) { - e.content = $_36akuw96jgqkwz4e.bbcode2html(e.content); - } - if (e.get) { - e.content = $_36akuw96jgqkwz4e.html2bbcode(e.content); - } - }); - } - }; - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.min.js deleted file mode 100755 index b2b9d701..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/bbcode/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/(.*?)<\/a>/gi,"[url=$1]$2[/url]"),o(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/(.*?)<\/span>/gi,"[color=$1]$2[/color]"),o(/(.*?)<\/font>/gi,"[color=$1]$2[/color]"),o(/(.*?)<\/span>/gi,"[size=$1]$2[/size]"),o(/(.*?)<\/font>/gi,"$1"),o(//gi,"[img]$1[/img]"),o(/(.*?)<\/span>/gi,"[code]$1[/code]"),o(/(.*?)<\/span>/gi,"[quote]$1[/quote]"),o(/(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),o(/(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),o(/(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),o(/(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),o(/(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),o(/(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),o(/<\/(strong|b)>/gi,"[/b]"),o(/<(strong|b)>/gi,"[b]"),o(/<\/(em|i)>/gi,"[/i]"),o(/<(em|i)>/gi,"[i]"),o(/<\/u>/gi,"[/u]"),o(/(.*?)<\/span>/gi,"[u]$1[/u]"),o(//gi,"[u]"),o(/]*>/gi,"[quote]"),o(/<\/blockquote>/gi,"[/quote]"),o(/
      /gi,"\n"),o(//gi,"\n"),o(/
      /gi,"\n"),o(/

      /gi,""),o(/<\/p>/gi,"\n"),o(/ |\u00a0/gi," "),o(/"/gi,'"'),o(/</gi,"<"),o(/>/gi,">"),o(/&/gi,"&"),e},i=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/\n/gi,"
      "),o(/\[b\]/gi,""),o(/\[\/b\]/gi,""),o(/\[i\]/gi,""),o(/\[\/i\]/gi,""),o(/\[u\]/gi,""),o(/\[\/u\]/gi,""),o(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'$2'),o(/\[url\](.*?)\[\/url\]/gi,'$1'),o(/\[img\](.*?)\[\/img\]/gi,''),o(/\[color=(.*?)\](.*?)\[\/color\]/gi,'$2'),o(/\[code\](.*?)\[\/code\]/gi,'$1 '),o(/\[quote.*?\](.*?)\[\/quote\]/gi,'$1 '),e};o.add("bbcode",function(){return{init:function(o){o.on("beforeSetContent",function(o){o.content=i(o.content)}),o.on("postProcess",function(o){o.set&&(o.content=i(o.content)),o.get&&(o.content=e(o.content))})}}})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/charmap/index.js deleted file mode 100755 index 13a16738..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "charmap" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/charmap') -// ES2015: -// import 'tinymce/plugins/charmap' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.js deleted file mode 100755 index fbae879c..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.js +++ /dev/null @@ -1,1275 +0,0 @@ -(function () { -var charmap = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var fireInsertCustomChar = function (editor, chr) { - return editor.fire('insertCustomChar', { chr: chr }); - }; - var $_3jb69g9cjgqkwz4t = { fireInsertCustomChar: fireInsertCustomChar }; - - var insertChar = function (editor, chr) { - var evtChr = $_3jb69g9cjgqkwz4t.fireInsertCustomChar(editor, chr).chr; - editor.execCommand('mceInsertContent', false, evtChr); - }; - var $_c23nsv9bjgqkwz4s = { insertChar: insertChar }; - - var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); - - var getCharMap = function (editor) { - return editor.settings.charmap; - }; - var getCharMapAppend = function (editor) { - return editor.settings.charmap_append; - }; - var $_7syvy9fjgqkwz56 = { - getCharMap: getCharMap, - getCharMapAppend: getCharMapAppend - }; - - var isArray = global$1.isArray; - var getDefaultCharMap = function () { - return [ - [ - '160', - 'no-break space' - ], - [ - '173', - 'soft hyphen' - ], - [ - '34', - 'quotation mark' - ], - [ - '162', - 'cent sign' - ], - [ - '8364', - 'euro sign' - ], - [ - '163', - 'pound sign' - ], - [ - '165', - 'yen sign' - ], - [ - '169', - 'copyright sign' - ], - [ - '174', - 'registered sign' - ], - [ - '8482', - 'trade mark sign' - ], - [ - '8240', - 'per mille sign' - ], - [ - '181', - 'micro sign' - ], - [ - '183', - 'middle dot' - ], - [ - '8226', - 'bullet' - ], - [ - '8230', - 'three dot leader' - ], - [ - '8242', - 'minutes / feet' - ], - [ - '8243', - 'seconds / inches' - ], - [ - '167', - 'section sign' - ], - [ - '182', - 'paragraph sign' - ], - [ - '223', - 'sharp s / ess-zed' - ], - [ - '8249', - 'single left-pointing angle quotation mark' - ], - [ - '8250', - 'single right-pointing angle quotation mark' - ], - [ - '171', - 'left pointing guillemet' - ], - [ - '187', - 'right pointing guillemet' - ], - [ - '8216', - 'left single quotation mark' - ], - [ - '8217', - 'right single quotation mark' - ], - [ - '8220', - 'left double quotation mark' - ], - [ - '8221', - 'right double quotation mark' - ], - [ - '8218', - 'single low-9 quotation mark' - ], - [ - '8222', - 'double low-9 quotation mark' - ], - [ - '60', - 'less-than sign' - ], - [ - '62', - 'greater-than sign' - ], - [ - '8804', - 'less-than or equal to' - ], - [ - '8805', - 'greater-than or equal to' - ], - [ - '8211', - 'en dash' - ], - [ - '8212', - 'em dash' - ], - [ - '175', - 'macron' - ], - [ - '8254', - 'overline' - ], - [ - '164', - 'currency sign' - ], - [ - '166', - 'broken bar' - ], - [ - '168', - 'diaeresis' - ], - [ - '161', - 'inverted exclamation mark' - ], - [ - '191', - 'turned question mark' - ], - [ - '710', - 'circumflex accent' - ], - [ - '732', - 'small tilde' - ], - [ - '176', - 'degree sign' - ], - [ - '8722', - 'minus sign' - ], - [ - '177', - 'plus-minus sign' - ], - [ - '247', - 'division sign' - ], - [ - '8260', - 'fraction slash' - ], - [ - '215', - 'multiplication sign' - ], - [ - '185', - 'superscript one' - ], - [ - '178', - 'superscript two' - ], - [ - '179', - 'superscript three' - ], - [ - '188', - 'fraction one quarter' - ], - [ - '189', - 'fraction one half' - ], - [ - '190', - 'fraction three quarters' - ], - [ - '402', - 'function / florin' - ], - [ - '8747', - 'integral' - ], - [ - '8721', - 'n-ary sumation' - ], - [ - '8734', - 'infinity' - ], - [ - '8730', - 'square root' - ], - [ - '8764', - 'similar to' - ], - [ - '8773', - 'approximately equal to' - ], - [ - '8776', - 'almost equal to' - ], - [ - '8800', - 'not equal to' - ], - [ - '8801', - 'identical to' - ], - [ - '8712', - 'element of' - ], - [ - '8713', - 'not an element of' - ], - [ - '8715', - 'contains as member' - ], - [ - '8719', - 'n-ary product' - ], - [ - '8743', - 'logical and' - ], - [ - '8744', - 'logical or' - ], - [ - '172', - 'not sign' - ], - [ - '8745', - 'intersection' - ], - [ - '8746', - 'union' - ], - [ - '8706', - 'partial differential' - ], - [ - '8704', - 'for all' - ], - [ - '8707', - 'there exists' - ], - [ - '8709', - 'diameter' - ], - [ - '8711', - 'backward difference' - ], - [ - '8727', - 'asterisk operator' - ], - [ - '8733', - 'proportional to' - ], - [ - '8736', - 'angle' - ], - [ - '180', - 'acute accent' - ], - [ - '184', - 'cedilla' - ], - [ - '170', - 'feminine ordinal indicator' - ], - [ - '186', - 'masculine ordinal indicator' - ], - [ - '8224', - 'dagger' - ], - [ - '8225', - 'double dagger' - ], - [ - '192', - 'A - grave' - ], - [ - '193', - 'A - acute' - ], - [ - '194', - 'A - circumflex' - ], - [ - '195', - 'A - tilde' - ], - [ - '196', - 'A - diaeresis' - ], - [ - '197', - 'A - ring above' - ], - [ - '256', - 'A - macron' - ], - [ - '198', - 'ligature AE' - ], - [ - '199', - 'C - cedilla' - ], - [ - '200', - 'E - grave' - ], - [ - '201', - 'E - acute' - ], - [ - '202', - 'E - circumflex' - ], - [ - '203', - 'E - diaeresis' - ], - [ - '274', - 'E - macron' - ], - [ - '204', - 'I - grave' - ], - [ - '205', - 'I - acute' - ], - [ - '206', - 'I - circumflex' - ], - [ - '207', - 'I - diaeresis' - ], - [ - '298', - 'I - macron' - ], - [ - '208', - 'ETH' - ], - [ - '209', - 'N - tilde' - ], - [ - '210', - 'O - grave' - ], - [ - '211', - 'O - acute' - ], - [ - '212', - 'O - circumflex' - ], - [ - '213', - 'O - tilde' - ], - [ - '214', - 'O - diaeresis' - ], - [ - '216', - 'O - slash' - ], - [ - '332', - 'O - macron' - ], - [ - '338', - 'ligature OE' - ], - [ - '352', - 'S - caron' - ], - [ - '217', - 'U - grave' - ], - [ - '218', - 'U - acute' - ], - [ - '219', - 'U - circumflex' - ], - [ - '220', - 'U - diaeresis' - ], - [ - '362', - 'U - macron' - ], - [ - '221', - 'Y - acute' - ], - [ - '376', - 'Y - diaeresis' - ], - [ - '562', - 'Y - macron' - ], - [ - '222', - 'THORN' - ], - [ - '224', - 'a - grave' - ], - [ - '225', - 'a - acute' - ], - [ - '226', - 'a - circumflex' - ], - [ - '227', - 'a - tilde' - ], - [ - '228', - 'a - diaeresis' - ], - [ - '229', - 'a - ring above' - ], - [ - '257', - 'a - macron' - ], - [ - '230', - 'ligature ae' - ], - [ - '231', - 'c - cedilla' - ], - [ - '232', - 'e - grave' - ], - [ - '233', - 'e - acute' - ], - [ - '234', - 'e - circumflex' - ], - [ - '235', - 'e - diaeresis' - ], - [ - '275', - 'e - macron' - ], - [ - '236', - 'i - grave' - ], - [ - '237', - 'i - acute' - ], - [ - '238', - 'i - circumflex' - ], - [ - '239', - 'i - diaeresis' - ], - [ - '299', - 'i - macron' - ], - [ - '240', - 'eth' - ], - [ - '241', - 'n - tilde' - ], - [ - '242', - 'o - grave' - ], - [ - '243', - 'o - acute' - ], - [ - '244', - 'o - circumflex' - ], - [ - '245', - 'o - tilde' - ], - [ - '246', - 'o - diaeresis' - ], - [ - '248', - 'o slash' - ], - [ - '333', - 'o macron' - ], - [ - '339', - 'ligature oe' - ], - [ - '353', - 's - caron' - ], - [ - '249', - 'u - grave' - ], - [ - '250', - 'u - acute' - ], - [ - '251', - 'u - circumflex' - ], - [ - '252', - 'u - diaeresis' - ], - [ - '363', - 'u - macron' - ], - [ - '253', - 'y - acute' - ], - [ - '254', - 'thorn' - ], - [ - '255', - 'y - diaeresis' - ], - [ - '563', - 'y - macron' - ], - [ - '913', - 'Alpha' - ], - [ - '914', - 'Beta' - ], - [ - '915', - 'Gamma' - ], - [ - '916', - 'Delta' - ], - [ - '917', - 'Epsilon' - ], - [ - '918', - 'Zeta' - ], - [ - '919', - 'Eta' - ], - [ - '920', - 'Theta' - ], - [ - '921', - 'Iota' - ], - [ - '922', - 'Kappa' - ], - [ - '923', - 'Lambda' - ], - [ - '924', - 'Mu' - ], - [ - '925', - 'Nu' - ], - [ - '926', - 'Xi' - ], - [ - '927', - 'Omicron' - ], - [ - '928', - 'Pi' - ], - [ - '929', - 'Rho' - ], - [ - '931', - 'Sigma' - ], - [ - '932', - 'Tau' - ], - [ - '933', - 'Upsilon' - ], - [ - '934', - 'Phi' - ], - [ - '935', - 'Chi' - ], - [ - '936', - 'Psi' - ], - [ - '937', - 'Omega' - ], - [ - '945', - 'alpha' - ], - [ - '946', - 'beta' - ], - [ - '947', - 'gamma' - ], - [ - '948', - 'delta' - ], - [ - '949', - 'epsilon' - ], - [ - '950', - 'zeta' - ], - [ - '951', - 'eta' - ], - [ - '952', - 'theta' - ], - [ - '953', - 'iota' - ], - [ - '954', - 'kappa' - ], - [ - '955', - 'lambda' - ], - [ - '956', - 'mu' - ], - [ - '957', - 'nu' - ], - [ - '958', - 'xi' - ], - [ - '959', - 'omicron' - ], - [ - '960', - 'pi' - ], - [ - '961', - 'rho' - ], - [ - '962', - 'final sigma' - ], - [ - '963', - 'sigma' - ], - [ - '964', - 'tau' - ], - [ - '965', - 'upsilon' - ], - [ - '966', - 'phi' - ], - [ - '967', - 'chi' - ], - [ - '968', - 'psi' - ], - [ - '969', - 'omega' - ], - [ - '8501', - 'alef symbol' - ], - [ - '982', - 'pi symbol' - ], - [ - '8476', - 'real part symbol' - ], - [ - '978', - 'upsilon - hook symbol' - ], - [ - '8472', - 'Weierstrass p' - ], - [ - '8465', - 'imaginary part' - ], - [ - '8592', - 'leftwards arrow' - ], - [ - '8593', - 'upwards arrow' - ], - [ - '8594', - 'rightwards arrow' - ], - [ - '8595', - 'downwards arrow' - ], - [ - '8596', - 'left right arrow' - ], - [ - '8629', - 'carriage return' - ], - [ - '8656', - 'leftwards double arrow' - ], - [ - '8657', - 'upwards double arrow' - ], - [ - '8658', - 'rightwards double arrow' - ], - [ - '8659', - 'downwards double arrow' - ], - [ - '8660', - 'left right double arrow' - ], - [ - '8756', - 'therefore' - ], - [ - '8834', - 'subset of' - ], - [ - '8835', - 'superset of' - ], - [ - '8836', - 'not a subset of' - ], - [ - '8838', - 'subset of or equal to' - ], - [ - '8839', - 'superset of or equal to' - ], - [ - '8853', - 'circled plus' - ], - [ - '8855', - 'circled times' - ], - [ - '8869', - 'perpendicular' - ], - [ - '8901', - 'dot operator' - ], - [ - '8968', - 'left ceiling' - ], - [ - '8969', - 'right ceiling' - ], - [ - '8970', - 'left floor' - ], - [ - '8971', - 'right floor' - ], - [ - '9001', - 'left-pointing angle bracket' - ], - [ - '9002', - 'right-pointing angle bracket' - ], - [ - '9674', - 'lozenge' - ], - [ - '9824', - 'black spade suit' - ], - [ - '9827', - 'black club suit' - ], - [ - '9829', - 'black heart suit' - ], - [ - '9830', - 'black diamond suit' - ], - [ - '8194', - 'en space' - ], - [ - '8195', - 'em space' - ], - [ - '8201', - 'thin space' - ], - [ - '8204', - 'zero width non-joiner' - ], - [ - '8205', - 'zero width joiner' - ], - [ - '8206', - 'left-to-right mark' - ], - [ - '8207', - 'right-to-left mark' - ] - ]; - }; - var charmapFilter = function (charmap) { - return global$1.grep(charmap, function (item) { - return isArray(item) && item.length === 2; - }); - }; - var getCharsFromSetting = function (settingValue) { - if (isArray(settingValue)) { - return [].concat(charmapFilter(settingValue)); - } - if (typeof settingValue === 'function') { - return settingValue(); - } - return []; - }; - var extendCharMap = function (editor, charmap) { - var userCharMap = $_7syvy9fjgqkwz56.getCharMap(editor); - if (userCharMap) { - charmap = getCharsFromSetting(userCharMap); - } - var userCharMapAppend = $_7syvy9fjgqkwz56.getCharMapAppend(editor); - if (userCharMapAppend) { - return [].concat(charmap).concat(getCharsFromSetting(userCharMapAppend)); - } - return charmap; - }; - var getCharMap$1 = function (editor) { - return extendCharMap(editor, getDefaultCharMap()); - }; - var $_7u7jut9djgqkwz4u = { getCharMap: getCharMap$1 }; - - var get = function (editor) { - var getCharMap = function () { - return $_7u7jut9djgqkwz4u.getCharMap(editor); - }; - var insertChar = function (chr) { - $_c23nsv9bjgqkwz4s.insertChar(editor, chr); - }; - return { - getCharMap: getCharMap, - insertChar: insertChar - }; - }; - var $_790q3f9ajgqkwz4r = { get: get }; - - var getHtml = function (charmap) { - var gridHtml, x, y; - var width = Math.min(charmap.length, 25); - var height = Math.ceil(charmap.length / width); - gridHtml = ''; - for (y = 0; y < height; y++) { - gridHtml += ''; - for (x = 0; x < width; x++) { - var index = y * width + x; - if (index < charmap.length) { - var chr = charmap[index]; - var charCode = parseInt(chr[0], 10); - var chrText = chr ? String.fromCharCode(charCode) : ' '; - gridHtml += ''; - } else { - gridHtml += ''; - } - gridHtml += ''; - return gridHtml; - }; - var $_3mm9qn9ijgqkwz5b = { getHtml: getHtml }; - - var getParentTd = function (elm) { - while (elm) { - if (elm.nodeName === 'TD') { - return elm; - } - elm = elm.parentNode; - } - }; - var open = function (editor) { - var win; - var charMapPanel = { - type: 'container', - html: $_3mm9qn9ijgqkwz5b.getHtml($_7u7jut9djgqkwz4u.getCharMap(editor)), - onclick: function (e) { - var target = e.target; - if (/^(TD|DIV)$/.test(target.nodeName)) { - var charDiv = getParentTd(target).firstChild; - if (charDiv && charDiv.hasAttribute('data-chr')) { - var charCodeString = charDiv.getAttribute('data-chr'); - var charCode = parseInt(charCodeString, 10); - if (!isNaN(charCode)) { - $_c23nsv9bjgqkwz4s.insertChar(editor, String.fromCharCode(charCode)); - } - if (!e.ctrlKey) { - win.close(); - } - } - } - }, - onmouseover: function (e) { - var td = getParentTd(e.target); - if (td && td.firstChild) { - win.find('#preview').text(td.firstChild.firstChild.data); - win.find('#previewTitle').text(td.title); - } else { - win.find('#preview').text(' '); - win.find('#previewTitle').text(' '); - } - } - }; - win = editor.windowManager.open({ - title: 'Special character', - spacing: 10, - padding: 10, - items: [ - charMapPanel, - { - type: 'container', - layout: 'flex', - direction: 'column', - align: 'center', - spacing: 5, - minWidth: 160, - minHeight: 160, - items: [ - { - type: 'label', - name: 'preview', - text: ' ', - style: 'font-size: 40px; text-align: center', - border: 1, - minWidth: 140, - minHeight: 80 - }, - { - type: 'spacer', - minHeight: 20 - }, - { - type: 'label', - name: 'previewTitle', - text: ' ', - style: 'white-space: pre-wrap;', - border: 1, - minWidth: 140 - } - ] - } - ], - buttons: [{ - text: 'Close', - onclick: function () { - win.close(); - } - }] - }); - }; - var $_14pi0r9hjgqkwz59 = { open: open }; - - var register = function (editor) { - editor.addCommand('mceShowCharmap', function () { - $_14pi0r9hjgqkwz59.open(editor); - }); - }; - var $_ecwcva9gjgqkwz57 = { register: register }; - - var register$1 = function (editor) { - editor.addButton('charmap', { - icon: 'charmap', - tooltip: 'Special character', - cmd: 'mceShowCharmap' - }); - editor.addMenuItem('charmap', { - icon: 'charmap', - text: 'Special character', - cmd: 'mceShowCharmap', - context: 'insert' - }); - }; - var $_2yrlu59jjgqkwz5c = { register: register$1 }; - - global.add('charmap', function (editor) { - $_ecwcva9gjgqkwz57.register(editor); - $_2yrlu59jjgqkwz5c.register(editor); - return $_790q3f9ajgqkwz4r.get(editor); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.min.js deleted file mode 100755 index 9ea3f757..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/charmap/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(e,t){return e.fire("insertCustomChar",{chr:t})},l=function(e,t){var a=i(e,t).chr;e.execCommand("mceInsertContent",!1,a)},a=tinymce.util.Tools.resolve("tinymce.util.Tools"),r=function(e){return e.settings.charmap},n=function(e){return e.settings.charmap_append},o=a.isArray,c=function(e){return o(e)?[].concat((t=e,a.grep(t,function(e){return o(e)&&2===e.length}))):"function"==typeof e?e():[];var t},s=function(e){return function(e,t){var a=r(e);a&&(t=c(a));var i=n(e);return i?[].concat(t).concat(c(i)):t}(e,[["160","no-break space"],["173","soft hyphen"],["34","quotation mark"],["162","cent sign"],["8364","euro sign"],["163","pound sign"],["165","yen sign"],["169","copyright sign"],["174","registered sign"],["8482","trade mark sign"],["8240","per mille sign"],["181","micro sign"],["183","middle dot"],["8226","bullet"],["8230","three dot leader"],["8242","minutes / feet"],["8243","seconds / inches"],["167","section sign"],["182","paragraph sign"],["223","sharp s / ess-zed"],["8249","single left-pointing angle quotation mark"],["8250","single right-pointing angle quotation mark"],["171","left pointing guillemet"],["187","right pointing guillemet"],["8216","left single quotation mark"],["8217","right single quotation mark"],["8220","left double quotation mark"],["8221","right double quotation mark"],["8218","single low-9 quotation mark"],["8222","double low-9 quotation mark"],["60","less-than sign"],["62","greater-than sign"],["8804","less-than or equal to"],["8805","greater-than or equal to"],["8211","en dash"],["8212","em dash"],["175","macron"],["8254","overline"],["164","currency sign"],["166","broken bar"],["168","diaeresis"],["161","inverted exclamation mark"],["191","turned question mark"],["710","circumflex accent"],["732","small tilde"],["176","degree sign"],["8722","minus sign"],["177","plus-minus sign"],["247","division sign"],["8260","fraction slash"],["215","multiplication sign"],["185","superscript one"],["178","superscript two"],["179","superscript three"],["188","fraction one quarter"],["189","fraction one half"],["190","fraction three quarters"],["402","function / florin"],["8747","integral"],["8721","n-ary sumation"],["8734","infinity"],["8730","square root"],["8764","similar to"],["8773","approximately equal to"],["8776","almost equal to"],["8800","not equal to"],["8801","identical to"],["8712","element of"],["8713","not an element of"],["8715","contains as member"],["8719","n-ary product"],["8743","logical and"],["8744","logical or"],["172","not sign"],["8745","intersection"],["8746","union"],["8706","partial differential"],["8704","for all"],["8707","there exists"],["8709","diameter"],["8711","backward difference"],["8727","asterisk operator"],["8733","proportional to"],["8736","angle"],["180","acute accent"],["184","cedilla"],["170","feminine ordinal indicator"],["186","masculine ordinal indicator"],["8224","dagger"],["8225","double dagger"],["192","A - grave"],["193","A - acute"],["194","A - circumflex"],["195","A - tilde"],["196","A - diaeresis"],["197","A - ring above"],["256","A - macron"],["198","ligature AE"],["199","C - cedilla"],["200","E - grave"],["201","E - acute"],["202","E - circumflex"],["203","E - diaeresis"],["274","E - macron"],["204","I - grave"],["205","I - acute"],["206","I - circumflex"],["207","I - diaeresis"],["298","I - macron"],["208","ETH"],["209","N - tilde"],["210","O - grave"],["211","O - acute"],["212","O - circumflex"],["213","O - tilde"],["214","O - diaeresis"],["216","O - slash"],["332","O - macron"],["338","ligature OE"],["352","S - caron"],["217","U - grave"],["218","U - acute"],["219","U - circumflex"],["220","U - diaeresis"],["362","U - macron"],["221","Y - acute"],["376","Y - diaeresis"],["562","Y - macron"],["222","THORN"],["224","a - grave"],["225","a - acute"],["226","a - circumflex"],["227","a - tilde"],["228","a - diaeresis"],["229","a - ring above"],["257","a - macron"],["230","ligature ae"],["231","c - cedilla"],["232","e - grave"],["233","e - acute"],["234","e - circumflex"],["235","e - diaeresis"],["275","e - macron"],["236","i - grave"],["237","i - acute"],["238","i - circumflex"],["239","i - diaeresis"],["299","i - macron"],["240","eth"],["241","n - tilde"],["242","o - grave"],["243","o - acute"],["244","o - circumflex"],["245","o - tilde"],["246","o - diaeresis"],["248","o slash"],["333","o macron"],["339","ligature oe"],["353","s - caron"],["249","u - grave"],["250","u - acute"],["251","u - circumflex"],["252","u - diaeresis"],["363","u - macron"],["253","y - acute"],["254","thorn"],["255","y - diaeresis"],["563","y - macron"],["913","Alpha"],["914","Beta"],["915","Gamma"],["916","Delta"],["917","Epsilon"],["918","Zeta"],["919","Eta"],["920","Theta"],["921","Iota"],["922","Kappa"],["923","Lambda"],["924","Mu"],["925","Nu"],["926","Xi"],["927","Omicron"],["928","Pi"],["929","Rho"],["931","Sigma"],["932","Tau"],["933","Upsilon"],["934","Phi"],["935","Chi"],["936","Psi"],["937","Omega"],["945","alpha"],["946","beta"],["947","gamma"],["948","delta"],["949","epsilon"],["950","zeta"],["951","eta"],["952","theta"],["953","iota"],["954","kappa"],["955","lambda"],["956","mu"],["957","nu"],["958","xi"],["959","omicron"],["960","pi"],["961","rho"],["962","final sigma"],["963","sigma"],["964","tau"],["965","upsilon"],["966","phi"],["967","chi"],["968","psi"],["969","omega"],["8501","alef symbol"],["982","pi symbol"],["8476","real part symbol"],["978","upsilon - hook symbol"],["8472","Weierstrass p"],["8465","imaginary part"],["8592","leftwards arrow"],["8593","upwards arrow"],["8594","rightwards arrow"],["8595","downwards arrow"],["8596","left right arrow"],["8629","carriage return"],["8656","leftwards double arrow"],["8657","upwards double arrow"],["8658","rightwards double arrow"],["8659","downwards double arrow"],["8660","left right double arrow"],["8756","therefore"],["8834","subset of"],["8835","superset of"],["8836","not a subset of"],["8838","subset of or equal to"],["8839","superset of or equal to"],["8853","circled plus"],["8855","circled times"],["8869","perpendicular"],["8901","dot operator"],["8968","left ceiling"],["8969","right ceiling"],["8970","left floor"],["8971","right floor"],["9001","left-pointing angle bracket"],["9002","right-pointing angle bracket"],["9674","lozenge"],["9824","black spade suit"],["9827","black club suit"],["9829","black heart suit"],["9830","black diamond suit"],["8194","en space"],["8195","em space"],["8201","thin space"],["8204","zero width non-joiner"],["8205","zero width joiner"],["8206","left-to-right mark"],["8207","right-to-left mark"]])},t=function(t){return{getCharMap:function(){return s(t)},insertChar:function(e){l(t,e)}}},u=function(e){var t,a,i,r=Math.min(e.length,25),n=Math.ceil(e.length/r);for(t='',i=0;i",a=0;a
      '+s+"
      "}else t+="
      "}return t+=""},d=function(e){for(;e;){if("TD"===e.nodeName)return e;e=e.parentNode}},m=function(n){var o,e={type:"container",html:u(s(n)),onclick:function(e){var t=e.target;if(/^(TD|DIV)$/.test(t.nodeName)){var a=d(t).firstChild;if(a&&a.hasAttribute("data-chr")){var i=a.getAttribute("data-chr"),r=parseInt(i,10);isNaN(r)||l(n,String.fromCharCode(r)),e.ctrlKey||o.close()}}},onmouseover:function(e){var t=d(e.target);t&&t.firstChild?(o.find("#preview").text(t.firstChild.firstChild.data),o.find("#previewTitle").text(t.title)):(o.find("#preview").text(" "),o.find("#previewTitle").text(" "))}};o=n.windowManager.open({title:"Special character",spacing:10,padding:10,items:[e,{type:"container",layout:"flex",direction:"column",align:"center",spacing:5,minWidth:160,minHeight:160,items:[{type:"label",name:"preview",text:" ",style:"font-size: 40px; text-align: center",border:1,minWidth:140,minHeight:80},{type:"spacer",minHeight:20},{type:"label",name:"previewTitle",text:" ",style:"white-space: pre-wrap;",border:1,minWidth:140}]}],buttons:[{text:"Close",onclick:function(){o.close()}}]})},g=function(e){e.addCommand("mceShowCharmap",function(){m(e)})},p=function(e){e.addButton("charmap",{icon:"charmap",tooltip:"Special character",cmd:"mceShowCharmap"}),e.addMenuItem("charmap",{icon:"charmap",text:"Special character",cmd:"mceShowCharmap",context:"insert"})};e.add("charmap",function(e){return g(e),p(e),t(e)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/code/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/code/index.js deleted file mode 100755 index 1e412f35..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/code/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "code" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/code') -// ES2015: -// import 'tinymce/plugins/code' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.js deleted file mode 100755 index 2c67b09e..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.js +++ /dev/null @@ -1,94 +0,0 @@ -(function () { -var code = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var getMinWidth = function (editor) { - return editor.getParam('code_dialog_width', 600); - }; - var getMinHeight = function (editor) { - return editor.getParam('code_dialog_height', Math.min(global$1.DOM.getViewPort().h - 200, 500)); - }; - var $_99yz6i9ojgqkwz63 = { - getMinWidth: getMinWidth, - getMinHeight: getMinHeight - }; - - var setContent = function (editor, html) { - editor.focus(); - editor.undoManager.transact(function () { - editor.setContent(html); - }); - editor.selection.setCursorLocation(); - editor.nodeChanged(); - }; - var getContent = function (editor) { - return editor.getContent({ source_view: true }); - }; - var $_7hapjz9qjgqkwz65 = { - setContent: setContent, - getContent: getContent - }; - - var open = function (editor) { - var minWidth = $_99yz6i9ojgqkwz63.getMinWidth(editor); - var minHeight = $_99yz6i9ojgqkwz63.getMinHeight(editor); - var win = editor.windowManager.open({ - title: 'Source code', - body: { - type: 'textbox', - name: 'code', - multiline: true, - minWidth: minWidth, - minHeight: minHeight, - spellcheck: false, - style: 'direction: ltr; text-align: left' - }, - onSubmit: function (e) { - $_7hapjz9qjgqkwz65.setContent(editor, e.data.code); - } - }); - win.find('#code').value($_7hapjz9qjgqkwz65.getContent(editor)); - }; - var $_7upvi69njgqkwz62 = { open: open }; - - var register = function (editor) { - editor.addCommand('mceCodeEditor', function () { - $_7upvi69njgqkwz62.open(editor); - }); - }; - var $_9r22vf9mjgqkwz61 = { register: register }; - - var register$1 = function (editor) { - editor.addButton('code', { - icon: 'code', - tooltip: 'Source code', - onclick: function () { - $_7upvi69njgqkwz62.open(editor); - } - }); - editor.addMenuItem('code', { - icon: 'code', - text: 'Source code', - onclick: function () { - $_7upvi69njgqkwz62.open(editor); - } - }); - }; - var $_cjj7u09rjgqkwz66 = { register: register$1 }; - - global.add('code', function (editor) { - $_9r22vf9mjgqkwz61.register(editor); - $_cjj7u09rjgqkwz66.register(editor); - return {}; - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.min.js deleted file mode 100755 index 7afcca64..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/code/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),o=function(t){return t.getParam("code_dialog_width",600)},i=function(t){return t.getParam("code_dialog_height",Math.min(n.DOM.getViewPort().h-200,500))},c=function(t,n){t.focus(),t.undoManager.transact(function(){t.setContent(n)}),t.selection.setCursorLocation(),t.nodeChanged()},d=function(t){return t.getContent({source_view:!0})},e=function(n){var t=o(n),e=i(n);n.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:t,minHeight:e,spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(t){c(n,t.data.code)}}).find("#code").value(d(n))},u=function(t){t.addCommand("mceCodeEditor",function(){e(t)})},a=function(t){t.addButton("code",{icon:"code",tooltip:"Source code",onclick:function(){e(t)}}),t.addMenuItem("code",{icon:"code",text:"Source code",onclick:function(){e(t)}})};t.add("code",function(t){return u(t),a(t),{}})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/css/prism.css b/iiif-5-day-workshop/day-three/mirador/plugins/codesample/css/prism.css deleted file mode 100755 index 128237fb..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/css/prism.css +++ /dev/null @@ -1,138 +0,0 @@ -/* http://prismjs.com/download.html?themes=prism&languages=markup+css+clike+javascript */ -/** - * prism.js default theme for JavaScript, CSS and HTML - * Based on dabblet (http://dabblet.com) - * @author Lea Verou - */ - -code[class*="language-"], -pre[class*="language-"] { - color: black; - text-shadow: 0 1px white; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - direction: ltr; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; -} - -pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, -code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { - text-shadow: none; - background: #b3d4fc; -} - -pre[class*="language-"]::selection, pre[class*="language-"] ::selection, -code[class*="language-"]::selection, code[class*="language-"] ::selection { - text-shadow: none; - background: #b3d4fc; -} - -@media print { - code[class*="language-"], - pre[class*="language-"] { - text-shadow: none; - } -} - -/* Code blocks */ -pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; -} - -:not(pre) > code[class*="language-"], -pre[class*="language-"] { - background: #f5f2f0; -} - -/* Inline code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #999; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol, -.token.deleted { - color: #905; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin, -.token.inserted { - color: #690; -} - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #a67f59; - background: hsla(0, 0%, 100%, .5); -} - -.token.atrule, -.token.attr-value, -.token.keyword { - color: #07a; -} - -.token.function { - color: #DD4A68; -} - -.token.regex, -.token.important, -.token.variable { - color: #e90; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} - diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/codesample/index.js deleted file mode 100755 index c400ec3d..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "codesample" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/codesample') -// ES2015: -// import 'tinymce/plugins/codesample' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.js deleted file mode 100755 index d5d8f9ff..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.js +++ /dev/null @@ -1,967 +0,0 @@ -(function () { -var codesample = (function () { - 'use strict'; - - var Cell = function (initial) { - var value = initial; - var get = function () { - return value; - }; - var set = function (v) { - value = v; - }; - var clone = function () { - return Cell(get()); - }; - return { - get: get, - set: set, - clone: clone - }; - }; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var getContentCss = function (editor) { - return editor.settings.codesample_content_css; - }; - var getLanguages = function (editor) { - return editor.settings.codesample_languages; - }; - var getDialogMinWidth = function (editor) { - return Math.min(global$1.DOM.getViewPort().w, editor.getParam('codesample_dialog_width', 800)); - }; - var getDialogMinHeight = function (editor) { - return Math.min(global$1.DOM.getViewPort().w, editor.getParam('codesample_dialog_height', 650)); - }; - var $_69surt9xjgqkwz6t = { - getContentCss: getContentCss, - getLanguages: getLanguages, - getDialogMinWidth: getDialogMinWidth, - getDialogMinHeight: getDialogMinHeight - }; - - var window = {}; - var global$2 = window; - var _self = typeof window !== 'undefined' ? window : typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope ? self : {}; - var Prism = function () { - var lang = /\blang(?:uage)?-(?!\*)(\w+)\b/i; - var _ = _self.Prism = { - util: { - encode: function (tokens) { - if (tokens instanceof Token) { - return new Token(tokens.type, _.util.encode(tokens.content), tokens.alias); - } else if (_.util.type(tokens) === 'Array') { - return tokens.map(_.util.encode); - } else { - return tokens.replace(/&/g, '&').replace(/ text.length) { - break tokenloop; - } - if (str instanceof Token) { - continue; - } - pattern.lastIndex = 0; - var match = pattern.exec(str); - if (match) { - if (lookbehind) { - lookbehindLength = match[1].length; - } - var from = match.index - 1 + lookbehindLength; - match = match[0].slice(lookbehindLength); - var len = match.length, to = from + len, before = str.slice(0, from + 1), after = str.slice(to + 1); - var args = [ - i, - 1 - ]; - if (before) { - args.push(before); - } - var wrapped = new Token(token, inside ? _.tokenize(match, inside) : match, alias); - args.push(wrapped); - if (after) { - args.push(after); - } - Array.prototype.splice.apply(strarr, args); - } - } - } - } - return strarr; - }, - hooks: { - all: {}, - add: function (name, callback) { - var hooks = _.hooks.all; - hooks[name] = hooks[name] || []; - hooks[name].push(callback); - }, - run: function (name, env) { - var callbacks = _.hooks.all[name]; - if (!callbacks || !callbacks.length) { - return; - } - for (var i = 0, callback = void 0; callback = callbacks[i++];) { - callback(env); - } - } - } - }; - var Token = _.Token = function (type, content, alias) { - this.type = type; - this.content = content; - this.alias = alias; - }; - Token.stringify = function (o, language, parent) { - if (typeof o === 'string') { - return o; - } - if (_.util.type(o) === 'Array') { - return o.map(function (element) { - return Token.stringify(element, language, o); - }).join(''); - } - var env = { - type: o.type, - content: Token.stringify(o.content, language, parent), - tag: 'span', - classes: [ - 'token', - o.type - ], - attributes: {}, - language: language, - parent: parent - }; - if (env.type === 'comment') { - env.attributes.spellcheck = 'true'; - } - if (o.alias) { - var aliases = _.util.type(o.alias) === 'Array' ? o.alias : [o.alias]; - Array.prototype.push.apply(env.classes, aliases); - } - _.hooks.run('wrap', env); - var attributes = ''; - for (var name_1 in env.attributes) { - attributes += (attributes ? ' ' : '') + name_1 + '="' + (env.attributes[name_1] || '') + '"'; - } - return '<' + env.tag + ' class="' + env.classes.join(' ') + '" ' + attributes + '>' + env.content + ''; - }; - if (!_self.document) { - if (!_self.addEventListener) { - return _self.Prism; - } - _self.addEventListener('message', function (evt) { - var message = JSON.parse(evt.data), lang = message.language, code = message.code, immediateClose = message.immediateClose; - _self.postMessage(_.highlight(code, _.languages[lang], lang)); - if (immediateClose) { - _self.close(); - } - }, false); - return _self.Prism; - } - }(); - if (typeof global$2 !== 'undefined') { - global$2.Prism = Prism; - } - Prism.languages.markup = { - comment: //, - prolog: /<\?[\w\W]+?\?>/, - doctype: //, - cdata: //i, - tag: { - pattern: /<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i, - inside: { - 'tag': { - pattern: /^<\/?[^\s>\/]+/i, - inside: { - punctuation: /^<\/?/, - namespace: /^[^\s>\/:]+:/ - } - }, - 'attr-value': { - pattern: /=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i, - inside: { punctuation: /[=>"']/ } - }, - 'punctuation': /\/?>/, - 'attr-name': { - pattern: /[^\s>\/]+/, - inside: { namespace: /^[^\s>\/:]+:/ } - } - } - }, - entity: /&#?[\da-z]{1,8};/i - }; - Prism.hooks.add('wrap', function (env) { - if (env.type === 'entity') { - env.attributes.title = env.content.replace(/&/, '&'); - } - }); - Prism.languages.xml = Prism.languages.markup; - Prism.languages.html = Prism.languages.markup; - Prism.languages.mathml = Prism.languages.markup; - Prism.languages.svg = Prism.languages.markup; - Prism.languages.css = { - comment: /\/\*[\w\W]*?\*\//, - atrule: { - pattern: /@[\w-]+?.*?(;|(?=\s*\{))/i, - inside: { rule: /@[\w-]+/ } - }, - url: /url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i, - selector: /[^\{\}\s][^\{\};]*?(?=\s*\{)/, - string: /("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/, - property: /(\b|\B)[\w-]+(?=\s*:)/i, - important: /\B!important\b/i, - function: /[-a-z0-9]+(?=\()/i, - punctuation: /[(){};:]/ - }; - Prism.languages.css.atrule.inside.rest = Prism.util.clone(Prism.languages.css); - if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - style: { - pattern: /[\w\W]*?<\/style>/i, - inside: { - tag: { - pattern: /|<\/style>/i, - inside: Prism.languages.markup.tag.inside - }, - rest: Prism.languages.css - }, - alias: 'language-css' - } - }); - Prism.languages.insertBefore('inside', 'attr-value', { - 'style-attr': { - pattern: /\s*style=("|').*?\1/i, - inside: { - 'attr-name': { - pattern: /^\s*style/i, - inside: Prism.languages.markup.tag.inside - }, - 'punctuation': /^\s*=\s*['"]|['"]\s*$/, - 'attr-value': { - pattern: /.+/i, - inside: Prism.languages.css - } - }, - alias: 'language-css' - } - }, Prism.languages.markup.tag); - } - Prism.languages.clike = { - 'comment': [ - { - pattern: /(^|[^\\])\/\*[\w\W]*?\*\//, - lookbehind: true - }, - { - pattern: /(^|[^\\:])\/\/.*/, - lookbehind: true - } - ], - 'string': /(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - 'class-name': { - pattern: /((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i, - lookbehind: true, - inside: { punctuation: /(\.|\\)/ } - }, - 'keyword': /\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, - 'boolean': /\b(true|false)\b/, - 'function': /[a-z0-9_]+(?=\()/i, - 'number': /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i, - 'operator': /--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/, - 'punctuation': /[{}[\];(),.:]/ - }; - Prism.languages.javascript = Prism.languages.extend('clike', { - keyword: /\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/, - number: /\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/, - function: /[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i - }); - Prism.languages.insertBefore('javascript', 'keyword', { - regex: { - pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/, - lookbehind: true - } - }); - Prism.languages.insertBefore('javascript', 'class-name', { - 'template-string': { - pattern: /`(?:\\`|\\?[^`])*`/, - inside: { - interpolation: { - pattern: /\$\{[^}]+\}/, - inside: { - 'interpolation-punctuation': { - pattern: /^\$\{|\}$/, - alias: 'punctuation' - }, - 'rest': Prism.languages.javascript - } - }, - string: /[\s\S]+/ - } - } - }); - if (Prism.languages.markup) { - Prism.languages.insertBefore('markup', 'tag', { - script: { - pattern: /[\w\W]*?<\/script>/i, - inside: { - tag: { - pattern: /|<\/script>/i, - inside: Prism.languages.markup.tag.inside - }, - rest: Prism.languages.javascript - }, - alias: 'language-javascript' - } - }); - } - Prism.languages.js = Prism.languages.javascript; - Prism.languages.c = Prism.languages.extend('clike', { - keyword: /\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/, - operator: /\-[>-]?|\+\+?|!=?|<>?=?|==?|&&?|\|?\||[~^%?*\/]/, - number: /\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i - }); - Prism.languages.insertBefore('c', 'string', { - macro: { - pattern: /(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im, - lookbehind: true, - alias: 'property', - inside: { - string: { - pattern: /(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/, - lookbehind: true - } - } - } - }); - delete Prism.languages.c['class-name']; - delete Prism.languages.c.boolean; - Prism.languages.csharp = Prism.languages.extend('clike', { - keyword: /\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/, - string: [ - /@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/, - /("|')(\\?.)*?\1/ - ], - number: /\b-?(0x[\da-f]+|\d*\.?\d+)\b/i - }); - Prism.languages.insertBefore('csharp', 'keyword', { - preprocessor: { - pattern: /(^\s*)#.*/m, - lookbehind: true - } - }); - Prism.languages.cpp = Prism.languages.extend('c', { - keyword: /\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/, - boolean: /\b(true|false)\b/, - operator: /[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/ - }); - Prism.languages.insertBefore('cpp', 'keyword', { - 'class-name': { - pattern: /(class\s+)[a-z0-9_]+/i, - lookbehind: true - } - }); - Prism.languages.java = Prism.languages.extend('clike', { - keyword: /\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/, - number: /\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i, - operator: { - pattern: /(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m, - lookbehind: true - } - }); - Prism.languages.php = Prism.languages.extend('clike', { - keyword: /\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i, - constant: /\b[A-Z0-9_]{2,}\b/, - comment: { - pattern: /(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/, - lookbehind: true - } - }); - Prism.languages.insertBefore('php', 'class-name', { - 'shell-comment': { - pattern: /(^|[^\\])#.*/, - lookbehind: true, - alias: 'comment' - } - }); - Prism.languages.insertBefore('php', 'keyword', { - delimiter: /\?>|<\?(?:php)?/i, - variable: /\$\w+\b/i, - package: { - pattern: /(\\|namespace\s+|use\s+)[\w\\]+/, - lookbehind: true, - inside: { punctuation: /\\/ } - } - }); - Prism.languages.insertBefore('php', 'operator', { - property: { - pattern: /(->)[\w]+/, - lookbehind: true - } - }); - if (Prism.languages.markup) { - Prism.hooks.add('before-highlight', function (env) { - if (env.language !== 'php') { - return; - } - env.tokenStack = []; - env.backupCode = env.code; - env.code = env.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/ig, function (match) { - env.tokenStack.push(match); - return '{{{PHP' + env.tokenStack.length + '}}}'; - }); - }); - Prism.hooks.add('before-insert', function (env) { - if (env.language === 'php') { - env.code = env.backupCode; - delete env.backupCode; - } - }); - Prism.hooks.add('after-highlight', function (env) { - if (env.language !== 'php') { - return; - } - for (var i = 0, t = void 0; t = env.tokenStack[i]; i++) { - env.highlightedCode = env.highlightedCode.replace('{{{PHP' + (i + 1) + '}}}', Prism.highlight(t, env.grammar, 'php').replace(/\$/g, '$$$$')); - } - env.element.innerHTML = env.highlightedCode; - }); - Prism.hooks.add('wrap', function (env) { - if (env.language === 'php' && env.type === 'markup') { - env.content = env.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g, '$1'); - } - }); - Prism.languages.insertBefore('php', 'comment', { - markup: { - pattern: /<[^?]\/?(.*?)>/, - inside: Prism.languages.markup - }, - php: /\{\{\{PHP[0-9]+\}\}\}/ - }); - } - Prism.languages.python = { - 'comment': { - pattern: /(^|[^\\])#.*/, - lookbehind: true - }, - 'string': /"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/, - 'function': { - pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g, - lookbehind: true - }, - 'class-name': { - pattern: /(\bclass\s+)[a-z0-9_]+/i, - lookbehind: true - }, - 'keyword': /\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/, - 'boolean': /\b(?:True|False)\b/, - 'number': /\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i, - 'operator': /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/, - 'punctuation': /[{}[\];(),.:]/ - }; - (function (Prism) { - Prism.languages.ruby = Prism.languages.extend('clike', { - comment: /#(?!\{[^\r\n]*?\}).*/, - keyword: /\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/ - }); - var interpolation = { - pattern: /#\{[^}]+\}/, - inside: { - delimiter: { - pattern: /^#\{|\}$/, - alias: 'tag' - }, - rest: Prism.util.clone(Prism.languages.ruby) - } - }; - Prism.languages.insertBefore('ruby', 'keyword', { - regex: [ - { - pattern: /%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/, - inside: { interpolation: interpolation } - }, - { - pattern: /%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/, - inside: { interpolation: interpolation } - }, - { - pattern: /%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/, - inside: { interpolation: interpolation } - }, - { - pattern: /%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/, - inside: { interpolation: interpolation } - }, - { - pattern: /%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/, - inside: { interpolation: interpolation } - }, - { - pattern: /(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/, - lookbehind: true - } - ], - variable: /[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/, - symbol: /:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/ - }); - Prism.languages.insertBefore('ruby', 'number', { - builtin: /\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/, - constant: /\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/ - }); - Prism.languages.ruby.string = [ - { - pattern: /%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/, - inside: { interpolation: interpolation } - }, - { - pattern: /%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/, - inside: { interpolation: interpolation } - }, - { - pattern: /%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/, - inside: { interpolation: interpolation } - }, - { - pattern: /%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/, - inside: { interpolation: interpolation } - }, - { - pattern: /%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/, - inside: { interpolation: interpolation } - }, - { - pattern: /("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/, - inside: { interpolation: interpolation } - } - ]; - }(Prism)); - - function isCodeSample(elm) { - return elm && elm.nodeName === 'PRE' && elm.className.indexOf('language-') !== -1; - } - function trimArg(predicateFn) { - return function (arg1, arg2) { - return predicateFn(arg2); - }; - } - var $_702j1va1jgqkwz85 = { - isCodeSample: isCodeSample, - trimArg: trimArg - }; - - var getSelectedCodeSample = function (editor) { - var node = editor.selection.getNode(); - if ($_702j1va1jgqkwz85.isCodeSample(node)) { - return node; - } - return null; - }; - var insertCodeSample = function (editor, language, code) { - editor.undoManager.transact(function () { - var node = getSelectedCodeSample(editor); - code = global$1.DOM.encode(code); - if (node) { - editor.dom.setAttrib(node, 'class', 'language-' + language); - node.innerHTML = code; - Prism.highlightElement(node); - editor.selection.select(node); - } else { - editor.insertContent('

      ' + code + '
      '); - editor.selection.select(editor.$('#__new').removeAttr('id')[0]); - } - }); - }; - var getCurrentCode = function (editor) { - var node = getSelectedCodeSample(editor); - if (node) { - return node.textContent; - } - return ''; - }; - var $_fm5tws9zjgqkwz6v = { - getSelectedCodeSample: getSelectedCodeSample, - insertCodeSample: insertCodeSample, - getCurrentCode: getCurrentCode - }; - - var getLanguages$1 = function (editor) { - var defaultLanguages = [ - { - text: 'HTML/XML', - value: 'markup' - }, - { - text: 'JavaScript', - value: 'javascript' - }, - { - text: 'CSS', - value: 'css' - }, - { - text: 'PHP', - value: 'php' - }, - { - text: 'Ruby', - value: 'ruby' - }, - { - text: 'Python', - value: 'python' - }, - { - text: 'Java', - value: 'java' - }, - { - text: 'C', - value: 'c' - }, - { - text: 'C#', - value: 'csharp' - }, - { - text: 'C++', - value: 'cpp' - } - ]; - var customLanguages = $_69surt9xjgqkwz6t.getLanguages(editor); - return customLanguages ? customLanguages : defaultLanguages; - }; - var getCurrentLanguage = function (editor) { - var matches; - var node = $_fm5tws9zjgqkwz6v.getSelectedCodeSample(editor); - if (node) { - matches = node.className.match(/language-(\w+)/); - return matches ? matches[1] : ''; - } - return ''; - }; - var $_9sryn3a2jgqkwz87 = { - getLanguages: getLanguages$1, - getCurrentLanguage: getCurrentLanguage - }; - - var $_3pq2y29wjgqkwz6s = { - open: function (editor) { - var minWidth = $_69surt9xjgqkwz6t.getDialogMinWidth(editor); - var minHeight = $_69surt9xjgqkwz6t.getDialogMinHeight(editor); - var currentLanguage = $_9sryn3a2jgqkwz87.getCurrentLanguage(editor); - var currentLanguages = $_9sryn3a2jgqkwz87.getLanguages(editor); - var currentCode = $_fm5tws9zjgqkwz6v.getCurrentCode(editor); - editor.windowManager.open({ - title: 'Insert/Edit code sample', - minWidth: minWidth, - minHeight: minHeight, - layout: 'flex', - direction: 'column', - align: 'stretch', - body: [ - { - type: 'listbox', - name: 'language', - label: 'Language', - maxWidth: 200, - value: currentLanguage, - values: currentLanguages - }, - { - type: 'textbox', - name: 'code', - multiline: true, - spellcheck: false, - ariaLabel: 'Code view', - flex: 1, - style: 'direction: ltr; text-align: left', - classes: 'monospace', - value: currentCode, - autofocus: true - } - ], - onSubmit: function (e) { - $_fm5tws9zjgqkwz6v.insertCodeSample(editor, e.data.language, e.data.code); - } - }); - } - }; - - var register = function (editor) { - editor.addCommand('codesample', function () { - var node = editor.selection.getNode(); - if (editor.selection.isCollapsed() || $_702j1va1jgqkwz85.isCodeSample(node)) { - $_3pq2y29wjgqkwz6s.open(editor); - } else { - editor.formatter.toggle('code'); - } - }); - }; - var $_bceq359vjgqkwz6r = { register: register }; - - var setup = function (editor) { - var $ = editor.$; - editor.on('PreProcess', function (e) { - $('pre[contenteditable=false]', e.node).filter($_702j1va1jgqkwz85.trimArg($_702j1va1jgqkwz85.isCodeSample)).each(function (idx, elm) { - var $elm = $(elm), code = elm.textContent; - $elm.attr('class', $.trim($elm.attr('class'))); - $elm.removeAttr('contentEditable'); - $elm.empty().append($('').each(function () { - this.textContent = code; - })); - }); - }); - editor.on('SetContent', function () { - var unprocessedCodeSamples = $('pre').filter($_702j1va1jgqkwz85.trimArg($_702j1va1jgqkwz85.isCodeSample)).filter(function (idx, elm) { - return elm.contentEditable !== 'false'; - }); - if (unprocessedCodeSamples.length) { - editor.undoManager.transact(function () { - unprocessedCodeSamples.each(function (idx, elm) { - $(elm).find('br').each(function (idx, elm) { - elm.parentNode.replaceChild(editor.getDoc().createTextNode('\n'), elm); - }); - elm.contentEditable = false; - elm.innerHTML = editor.dom.encode(elm.textContent); - Prism.highlightElement(elm); - elm.className = $.trim(elm.className); - }); - }); - } - }); - }; - var $_6gnxdka3jgqkwz89 = { setup: setup }; - - var loadCss = function (editor, pluginUrl, addedInlineCss, addedCss) { - var linkElm; - var contentCss = $_69surt9xjgqkwz6t.getContentCss(editor); - if (editor.inline && addedInlineCss.get()) { - return; - } - if (!editor.inline && addedCss.get()) { - return; - } - if (editor.inline) { - addedInlineCss.set(true); - } else { - addedCss.set(true); - } - if (contentCss !== false) { - linkElm = editor.dom.create('link', { - rel: 'stylesheet', - href: contentCss ? contentCss : pluginUrl + '/css/prism.css' - }); - editor.getDoc().getElementsByTagName('head')[0].appendChild(linkElm); - } - }; - var $_2pdho6a4jgqkwz8b = { loadCss: loadCss }; - - var register$1 = function (editor) { - editor.addButton('codesample', { - cmd: 'codesample', - title: 'Insert/Edit code sample' - }); - editor.addMenuItem('codesample', { - cmd: 'codesample', - text: 'Code sample', - icon: 'codesample' - }); - }; - var $_4qotqva5jgqkwz8c = { register: register$1 }; - - var addedInlineCss = Cell(false); - global.add('codesample', function (editor, pluginUrl) { - var addedCss = Cell(false); - $_6gnxdka3jgqkwz89.setup(editor); - $_4qotqva5jgqkwz8c.register(editor); - $_bceq359vjgqkwz6r.register(editor); - editor.on('init', function () { - $_2pdho6a4jgqkwz8b.loadCss(editor, pluginUrl, addedInlineCss, addedCss); - }); - editor.on('dblclick', function (ev) { - if ($_702j1va1jgqkwz85.isCodeSample(ev.target)) { - $_3pq2y29wjgqkwz6s.open(editor); - } - }); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.min.js deleted file mode 100755 index 8f7373cc..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/codesample/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var n=function(e){var t=e,a=function(){return t};return{get:a,set:function(e){t=e},clone:function(){return n(a())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),s=function(e){return e.settings.codesample_content_css},a=function(e){return e.settings.codesample_languages},o=function(e){return Math.min(i.DOM.getViewPort().w,e.getParam("codesample_dialog_width",800))},l=function(e){return Math.min(i.DOM.getViewPort().w,e.getParam("codesample_dialog_height",650))},t={},r=t,u=void 0!==t?t:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},c=function(){var c=/\blang(?:uage)?-(?!\*)(\w+)\b/i,S=u.Prism={util:{encode:function(e){return e instanceof o?new o(e.type,S.util.encode(e.content),e.alias):"Array"===S.util.type(e)?e.map(S.util.encode):e.replace(/&/g,"&").replace(/e.length)break e;if(!(h instanceof n)){c.lastIndex=0;var m=c.exec(h);if(m){g&&(d=m[1].length);var b=m.index-1+d,y=b+(m=m[0].slice(d)).length,v=h.slice(0,b+1),k=h.slice(y+1),w=[f,1];v&&w.push(v);var x=new n(s,u?S.tokenize(m,u):m,p);w.push(x),k&&w.push(k),Array.prototype.splice.apply(i,w)}}}}}return i},hooks:{all:{},add:function(e,t){var a=S.hooks.all;a[e]=a[e]||[],a[e].push(t)},run:function(e,t){var a=S.hooks.all[e];if(a&&a.length)for(var n=0,i=void 0;i=a[n++];)i(t)}}},o=S.Token=function(e,t,a){this.type=e,this.content=t,this.alias=a};if(o.stringify=function(t,a,e){if("string"==typeof t)return t;if("Array"===S.util.type(t))return t.map(function(e){return o.stringify(e,a,t)}).join("");var n={type:t.type,content:o.stringify(t.content,a,e),tag:"span",classes:["token",t.type],attributes:{},language:a,parent:e};if("comment"===n.type&&(n.attributes.spellcheck="true"),t.alias){var i="Array"===S.util.type(t.alias)?t.alias:[t.alias];Array.prototype.push.apply(n.classes,i)}S.hooks.run("wrap",n);var r="";for(var s in n.attributes)r+=(r?" ":"")+s+'="'+(n.attributes[s]||"")+'"';return"<"+n.tag+' class="'+n.classes.join(" ")+'" '+r+">"+n.content+""},!u.document)return u.addEventListener&&u.addEventListener("message",function(e){var t=JSON.parse(e.data),a=t.language,n=t.code,i=t.immediateClose;u.postMessage(S.highlight(n,S.languages[a],a)),i&&u.close()},!1),u.Prism}();void 0!==r&&(r.Prism=c),c.languages.markup={comment://,prolog:/<\?[\w\W]+?\?>/,doctype://,cdata://i,tag:{pattern:/<\/?[^\s>\/=.]+(?:\s+[^\s>\/=]+(?:=(?:("|')(?:\\\1|\\?(?!\1)[\w\W])*\1|[^\s'">=]+))?)*\s*\/?>/i,inside:{tag:{pattern:/^<\/?[^\s>\/]+/i,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/i,inside:{punctuation:/[=>"']/}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:/&#?[\da-z]{1,8};/i},c.hooks.add("wrap",function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))}),c.languages.xml=c.languages.markup,c.languages.html=c.languages.markup,c.languages.mathml=c.languages.markup,c.languages.svg=c.languages.markup,c.languages.css={comment:/\/\*[\w\W]*?\*\//,atrule:{pattern:/@[\w-]+?.*?(;|(?=\s*\{))/i,inside:{rule:/@[\w-]+/}},url:/url\((?:(["'])(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1|.*?)\)/i,selector:/[^\{\}\s][^\{\};]*?(?=\s*\{)/,string:/("|')(\\(?:\r\n|[\w\W])|(?!\1)[^\\\r\n])*\1/,property:/(\b|\B)[\w-]+(?=\s*:)/i,important:/\B!important\b/i,"function":/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:]/},c.languages.css.atrule.inside.rest=c.util.clone(c.languages.css),c.languages.markup&&(c.languages.insertBefore("markup","tag",{style:{pattern:/[\w\W]*?<\/style>/i,inside:{tag:{pattern:/|<\/style>/i,inside:c.languages.markup.tag.inside},rest:c.languages.css},alias:"language-css"}}),c.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/\s*style=("|').*?\1/i,inside:{"attr-name":{pattern:/^\s*style/i,inside:c.languages.markup.tag.inside},punctuation:/^\s*=\s*['"]|['"]\s*$/,"attr-value":{pattern:/.+/i,inside:c.languages.css}},alias:"language-css"}},c.languages.markup.tag)),c.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\w\W]*?\*\//,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0}],string:/(["'])(\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,"class-name":{pattern:/((?:\b(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/i,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,"boolean":/\b(true|false)\b/,"function":/[a-z0-9_]+(?=\()/i,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)\b/i,operator:/--?|\+\+?|!=?=?|<=?|>=?|==?=?|&&?|\|\|?|\?|\*|\/|~|\^|%/,punctuation:/[{}[\];(),.:]/},c.languages.javascript=c.languages.extend("clike",{keyword:/\b(as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/,number:/\b-?(0x[\dA-Fa-f]+|0b[01]+|0o[0-7]+|\d*\.?\d+([Ee][+-]?\d+)?|NaN|Infinity)\b/,"function":/[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*(?=\()/i}),c.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\\\r\n])+\/[gimyu]{0,5}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}}),c.languages.insertBefore("javascript","class-name",{"template-string":{pattern:/`(?:\\`|\\?[^`])*`/,inside:{interpolation:{pattern:/\$\{[^}]+\}/,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:c.languages.javascript}},string:/[\s\S]+/}}}),c.languages.markup&&c.languages.insertBefore("markup","tag",{script:{pattern:/[\w\W]*?<\/script>/i,inside:{tag:{pattern:/|<\/script>/i,inside:c.languages.markup.tag.inside},rest:c.languages.javascript},alias:"language-javascript"}}),c.languages.js=c.languages.javascript,c.languages.c=c.languages.extend("clike",{keyword:/\b(asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,operator:/\-[>-]?|\+\+?|!=?|<>?=?|==?|&&?|\|?\||[~^%?*\/]/,number:/\b-?(?:0x[\da-f]+|\d*\.?\d+(?:e[+-]?\d+)?)[ful]*\b/i}),c.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+([^\r\n\\]|\\.|\\(?:\r\n?|\n))*/im,lookbehind:!0,alias:"property",inside:{string:{pattern:/(#\s*include\s*)(<.+?>|("|')(\\?.)+?\3)/,lookbehind:!0}}}}),delete c.languages.c["class-name"],delete c.languages.c["boolean"],c.languages.csharp=c.languages.extend("clike",{keyword:/\b(abstract|as|async|await|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|add|alias|ascending|async|await|descending|dynamic|from|get|global|group|into|join|let|orderby|partial|remove|select|set|value|var|where|yield)\b/,string:[/@("|')(\1\1|\\\1|\\?(?!\1)[\s\S])*\1/,/("|')(\\?.)*?\1/],number:/\b-?(0x[\da-f]+|\d*\.?\d+)\b/i}),c.languages.insertBefore("csharp","keyword",{preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0}}),c.languages.cpp=c.languages.extend("c",{keyword:/\b(alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|class|compl|const|constexpr|const_cast|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,"boolean":/\b(true|false)\b/,operator:/[-+]{1,2}|!=?|<{1,2}=?|>{1,2}=?|\->|:{1,2}|={1,2}|\^|~|%|&{1,2}|\|?\||\?|\*|\/|\b(and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/}),c.languages.insertBefore("cpp","keyword",{"class-name":{pattern:/(class\s+)[a-z0-9_]+/i,lookbehind:!0}}),c.languages.java=c.languages.extend("clike",{keyword:/\b(abstract|continue|for|new|switch|assert|default|goto|package|synchronized|boolean|do|if|private|this|break|double|implements|protected|throw|byte|else|import|public|throws|case|enum|instanceof|return|transient|catch|extends|int|short|try|char|final|interface|static|void|class|finally|long|strictfp|volatile|const|float|native|super|while)\b/,number:/\b0b[01]+\b|\b0x[\da-f]*\.?[\da-fp\-]+\b|\b\d*\.?\d+(?:e[+-]?\d+)?[df]?\b/i,operator:{pattern:/(^|[^.])(?:\+[+=]?|-[-=]?|!=?|<>?>?=?|==?|&[&=]?|\|[|=]?|\*=?|\/=?|%=?|\^=?|[?:~])/m,lookbehind:!0}}),c.languages.php=c.languages.extend("clike",{keyword:/\b(and|or|xor|array|as|break|case|cfunction|class|const|continue|declare|default|die|do|else|elseif|enddeclare|endfor|endforeach|endif|endswitch|endwhile|extends|for|foreach|function|include|include_once|global|if|new|return|static|switch|use|require|require_once|var|while|abstract|interface|public|implements|private|protected|parent|throw|null|echo|print|trait|namespace|final|yield|goto|instanceof|finally|try|catch)\b/i,constant:/\b[A-Z0-9_]{2,}\b/,comment:{pattern:/(^|[^\\])(?:\/\*[\w\W]*?\*\/|\/\/.*)/,lookbehind:!0}}),c.languages.insertBefore("php","class-name",{"shell-comment":{pattern:/(^|[^\\])#.*/,lookbehind:!0,alias:"comment"}}),c.languages.insertBefore("php","keyword",{delimiter:/\?>|<\?(?:php)?/i,variable:/\$\w+\b/i,"package":{pattern:/(\\|namespace\s+|use\s+)[\w\\]+/,lookbehind:!0,inside:{punctuation:/\\/}}}),c.languages.insertBefore("php","operator",{property:{pattern:/(->)[\w]+/,lookbehind:!0}}),c.languages.markup&&(c.hooks.add("before-highlight",function(t){"php"===t.language&&(t.tokenStack=[],t.backupCode=t.code,t.code=t.code.replace(/(?:<\?php|<\?)[\w\W]*?(?:\?>)/gi,function(e){return t.tokenStack.push(e),"{{{PHP"+t.tokenStack.length+"}}}"}))}),c.hooks.add("before-insert",function(e){"php"===e.language&&(e.code=e.backupCode,delete e.backupCode)}),c.hooks.add("after-highlight",function(e){if("php"===e.language){for(var t=0,a=void 0;a=e.tokenStack[t];t++)e.highlightedCode=e.highlightedCode.replace("{{{PHP"+(t+1)+"}}}",c.highlight(a,e.grammar,"php").replace(/\$/g,"$$$$"));e.element.innerHTML=e.highlightedCode}}),c.hooks.add("wrap",function(e){"php"===e.language&&"markup"===e.type&&(e.content=e.content.replace(/(\{\{\{PHP[0-9]+\}\}\})/g,'$1'))}),c.languages.insertBefore("php","comment",{markup:{pattern:/<[^?]\/?(.*?)>/,inside:c.languages.markup},php:/\{\{\{PHP[0-9]+\}\}\}/})),c.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},string:/"""[\s\S]+?"""|'''[\s\S]+?'''|("|')(?:\\?.)*?\1/,"function":{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)[a-z0-9_]+/i,lookbehind:!0},keyword:/\b(?:as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|pass|print|raise|return|try|while|with|yield)\b/,"boolean":/\b(?:True|False)\b/,number:/\b-?(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]|\b(?:or|and|not)\b/,punctuation:/[{}[\];(),.:]/},function(e){e.languages.ruby=e.languages.extend("clike",{comment:/#(?!\{[^\r\n]*?\}).*/,keyword:/\b(alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|false|for|if|in|module|new|next|nil|not|or|raise|redo|require|rescue|retry|return|self|super|then|throw|true|undef|unless|until|when|while|yield)\b/});var t={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.util.clone(e.languages.ruby)}};e.languages.insertBefore("ruby","keyword",{regex:[{pattern:/%r([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\((?:[^()\\]|\\[\s\S])*\)[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}[gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r\[(?:[^\[\]\\]|\\[\s\S])*\][gim]{0,3}/,inside:{interpolation:t}},{pattern:/%r<(?:[^<>\\]|\\[\s\S])*>[gim]{0,3}/,inside:{interpolation:t}},{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/,lookbehind:!0}],variable:/[@$]+[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/,symbol:/:[a-zA-Z_][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.insertBefore("ruby","number",{builtin:/\b(Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|File|Fixnum|Fload|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z][a-zA-Z_0-9]*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:/%[qQiIwWxs]?([^a-zA-Z0-9\s\{\(\[<])(?:[^\\]|\\[\s\S])*?\1/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\((?:[^()\\]|\\[\s\S])*\)/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\{(?:[^#{}\\]|#(?:\{[^}]+\})?|\\[\s\S])*\}/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?\[(?:[^\[\]\\]|\\[\s\S])*\]/,inside:{interpolation:t}},{pattern:/%[qQiIwWxs]?<(?:[^<>\\]|\\[\s\S])*>/,inside:{interpolation:t}},{pattern:/("|')(#\{[^}]+\}|\\(?:\r?\n|\r)|\\?.)*?\1/,inside:{interpolation:t}}]}(c);var g={isCodeSample:function(e){return e&&"PRE"===e.nodeName&&-1!==e.className.indexOf("language-")},trimArg:function(a){return function(e,t){return a(t)}}},d=function(e){var t=e.selection.getNode();return g.isCodeSample(t)?t:null},p=d,f=function(t,a,n){t.undoManager.transact(function(){var e=d(t);n=i.DOM.encode(n),e?(t.dom.setAttrib(e,"class","language-"+a),e.innerHTML=n,c.highlightElement(e),t.selection.select(e)):(t.insertContent('
      '+n+"
      "),t.selection.select(t.$("#__new").removeAttr("id")[0]))})},h=function(e){var t=d(e);return t?t.textContent:""},m=function(e){var t=a(e);return t||[{text:"HTML/XML",value:"markup"},{text:"JavaScript",value:"javascript"},{text:"CSS",value:"css"},{text:"PHP",value:"php"},{text:"Ruby",value:"ruby"},{text:"Python",value:"python"},{text:"Java",value:"java"},{text:"C",value:"c"},{text:"C#",value:"csharp"},{text:"C++",value:"cpp"}]},b=function(e){var t,a=p(e);return a&&(t=a.className.match(/language-(\w+)/))?t[1]:""},y=function(t){var e=o(t),a=l(t),n=b(t),i=m(t),r=h(t);t.windowManager.open({title:"Insert/Edit code sample",minWidth:e,minHeight:a,layout:"flex",direction:"column",align:"stretch",body:[{type:"listbox",name:"language",label:"Language",maxWidth:200,value:n,values:i},{type:"textbox",name:"code",multiline:!0,spellcheck:!1,ariaLabel:"Code view",flex:1,style:"direction: ltr; text-align: left",classes:"monospace",value:r,autofocus:!0}],onSubmit:function(e){f(t,e.data.language,e.data.code)}})},v=function(t){t.addCommand("codesample",function(){var e=t.selection.getNode();t.selection.isCollapsed()||g.isCodeSample(e)?y(t):t.formatter.toggle("code")})},k=function(a){var i=a.$;a.on("PreProcess",function(e){i("pre[contenteditable=false]",e.node).filter(g.trimArg(g.isCodeSample)).each(function(e,t){var a=i(t),n=t.textContent;a.attr("class",i.trim(a.attr("class"))),a.removeAttr("contentEditable"),a.empty().append(i("").each(function(){this.textContent=n}))})}),a.on("SetContent",function(){var e=i("pre").filter(g.trimArg(g.isCodeSample)).filter(function(e,t){return"false"!==t.contentEditable});e.length&&a.undoManager.transact(function(){e.each(function(e,t){i(t).find("br").each(function(e,t){t.parentNode.replaceChild(a.getDoc().createTextNode("\n"),t)}),t.contentEditable=!1,t.innerHTML=a.dom.encode(t.textContent),c.highlightElement(t),t.className=i.trim(t.className)})})})},w=function(e,t,a,n){var i,r=s(e);e.inline&&a.get()||!e.inline&&n.get()||(e.inline?a.set(!0):n.set(!0),!1!==r&&(i=e.dom.create("link",{rel:"stylesheet",href:r||t+"/css/prism.css"}),e.getDoc().getElementsByTagName("head")[0].appendChild(i)))},x=function(e){e.addButton("codesample",{cmd:"codesample",title:"Insert/Edit code sample"}),e.addMenuItem("codesample",{cmd:"codesample",text:"Code sample",icon:"codesample"})},S=n(!1);e.add("codesample",function(t,e){var a=n(!1);k(t),x(t),v(t),t.on("init",function(){w(t,e,S,a)}),t.on("dblclick",function(e){g.isCodeSample(e.target)&&y(t)})})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/index.js deleted file mode 100755 index 1af1ae63..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "colorpicker" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/colorpicker') -// ES2015: -// import 'tinymce/plugins/colorpicker' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.js deleted file mode 100755 index 268f8316..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.js +++ /dev/null @@ -1,126 +0,0 @@ -(function () { -var colorpicker = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var global$1 = tinymce.util.Tools.resolve('tinymce.util.Color'); - - var showPreview = function (win, hexColor) { - win.find('#preview')[0].getEl().style.background = hexColor; - }; - var setColor = function (win, value) { - var color = global$1(value), rgb = color.toRgb(); - win.fromJSON({ - r: rgb.r, - g: rgb.g, - b: rgb.b, - hex: color.toHex().substr(1) - }); - showPreview(win, color.toHex()); - }; - var open = function (editor, callback, value) { - var win = editor.windowManager.open({ - title: 'Color', - items: { - type: 'container', - layout: 'flex', - direction: 'row', - align: 'stretch', - padding: 5, - spacing: 10, - items: [ - { - type: 'colorpicker', - value: value, - onchange: function () { - var rgb = this.rgb(); - if (win) { - win.find('#r').value(rgb.r); - win.find('#g').value(rgb.g); - win.find('#b').value(rgb.b); - win.find('#hex').value(this.value().substr(1)); - showPreview(win, this.value()); - } - } - }, - { - type: 'form', - padding: 0, - labelGap: 5, - defaults: { - type: 'textbox', - size: 7, - value: '0', - flex: 1, - spellcheck: false, - onchange: function () { - var colorPickerCtrl = win.find('colorpicker')[0]; - var name, value; - name = this.name(); - value = this.value(); - if (name === 'hex') { - value = '#' + value; - setColor(win, value); - colorPickerCtrl.value(value); - return; - } - value = { - r: win.find('#r').value(), - g: win.find('#g').value(), - b: win.find('#b').value() - }; - colorPickerCtrl.value(value); - setColor(win, value); - } - }, - items: [ - { - name: 'r', - label: 'R', - autofocus: 1 - }, - { - name: 'g', - label: 'G' - }, - { - name: 'b', - label: 'B' - }, - { - name: 'hex', - label: '#', - value: '000000' - }, - { - name: 'preview', - type: 'container', - border: 1 - } - ] - } - ] - }, - onSubmit: function () { - callback('#' + win.toJSON().hex); - } - }); - setColor(win, value); - }; - var $_7bhhxqa8jgqkwz9r = { open: open }; - - global.add('colorpicker', function (editor) { - if (!editor.settings.color_picker_callback) { - editor.settings.color_picker_callback = function (callback, value) { - $_7bhhxqa8jgqkwz9r.open(editor, callback, value); - }; - } - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.min.js deleted file mode 100755 index 10317a5f..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/colorpicker/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),l=tinymce.util.Tools.resolve("tinymce.util.Color"),a=function(e,n){e.find("#preview")[0].getEl().style.background=n},o=function(e,n){var i=l(n),t=i.toRgb();e.fromJSON({r:t.r,g:t.g,b:t.b,hex:i.toHex().substr(1)}),a(e,i.toHex())},t=function(e,n,i){var t=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:i,onchange:function(){var e=this.rgb();t&&(t.find("#r").value(e.r),t.find("#g").value(e.g),t.find("#b").value(e.b),t.find("#hex").value(this.value().substr(1)),a(t,this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,i=t.find("colorpicker")[0];if(e=this.name(),n=this.value(),"hex"===e)return o(t,n="#"+n),void i.value(n);n={r:t.find("#r").value(),g:t.find("#g").value(),b:t.find("#b").value()},i.value(n),o(t,n)}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+t.toJSON().hex)}});o(t,i)};e.add("colorpicker",function(i){i.settings.color_picker_callback||(i.settings.color_picker_callback=function(e,n){t(i,e,n)})})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/index.js deleted file mode 100755 index ae837e24..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "contextmenu" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/contextmenu') -// ES2015: -// import 'tinymce/plugins/contextmenu' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.js deleted file mode 100755 index 8c7bb292..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.js +++ /dev/null @@ -1,168 +0,0 @@ -(function () { -var contextmenu = (function () { - 'use strict'; - - var Cell = function (initial) { - var value = initial; - var get = function () { - return value; - }; - var set = function (v) { - value = v; - }; - var clone = function () { - return Cell(get()); - }; - return { - get: get, - set: set, - clone: clone - }; - }; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var get = function (visibleState) { - var isContextMenuVisible = function () { - return visibleState.get(); - }; - return { isContextMenuVisible: isContextMenuVisible }; - }; - var $_cv44lcadjgqkwza6 = { get: get }; - - var shouldNeverUseNative = function (editor) { - return editor.settings.contextmenu_never_use_native; - }; - var getContextMenu = function (editor) { - return editor.getParam('contextmenu', 'link openlink image inserttable | cell row column deletetable'); - }; - var $_d5n2szafjgqkwza9 = { - shouldNeverUseNative: shouldNeverUseNative, - getContextMenu: getContextMenu - }; - - var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var getUiContainer = function (editor) { - return global$1.DOM.select(editor.settings.ui_container)[0]; - }; - - var nu = function (x, y) { - return { - x: x, - y: y - }; - }; - var transpose = function (pos, dx, dy) { - return nu(pos.x + dx, pos.y + dy); - }; - var fromPageXY = function (e) { - return nu(e.pageX, e.pageY); - }; - var fromClientXY = function (e) { - return nu(e.clientX, e.clientY); - }; - var transposeUiContainer = function (element, pos) { - if (element && global$1.DOM.getStyle(element, 'position', true) !== 'static') { - var containerPos = global$1.DOM.getPos(element); - var dx = containerPos.x - element.scrollLeft; - var dy = containerPos.y - element.scrollTop; - return transpose(pos, -dx, -dy); - } else { - return transpose(pos, 0, 0); - } - }; - var transposeContentAreaContainer = function (element, pos) { - var containerPos = global$1.DOM.getPos(element); - return transpose(pos, containerPos.x, containerPos.y); - }; - var getPos = function (editor, e) { - if (editor.inline) { - return transposeUiContainer(getUiContainer(editor), fromPageXY(e)); - } else { - var iframePos = transposeContentAreaContainer(editor.getContentAreaContainer(), fromClientXY(e)); - return transposeUiContainer(getUiContainer(editor), iframePos); - } - }; - var $_s0illagjgqkwzaa = { getPos: getPos }; - - var global$2 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); - - var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools'); - - var renderMenu = function (editor, visibleState) { - var menu, contextmenu; - var items = []; - contextmenu = $_d5n2szafjgqkwza9.getContextMenu(editor); - global$3.each(contextmenu.split(/[ ,]/), function (name) { - var item = editor.menuItems[name]; - if (name === '|') { - item = { text: name }; - } - if (item) { - item.shortcut = ''; - items.push(item); - } - }); - for (var i = 0; i < items.length; i++) { - if (items[i].text === '|') { - if (i === 0 || i === items.length - 1) { - items.splice(i, 1); - } - } - } - menu = global$2.create('menu', { - items: items, - context: 'contextmenu', - classes: 'contextmenu' - }); - menu.uiContainer = getUiContainer(editor); - menu.renderTo(getUiContainer(editor)); - menu.on('hide', function (e) { - if (e.control === this) { - visibleState.set(false); - } - }); - editor.on('remove', function () { - menu.remove(); - menu = null; - }); - return menu; - }; - var show = function (editor, pos, visibleState, menu) { - if (menu.get() === null) { - menu.set(renderMenu(editor, visibleState)); - } else { - menu.get().show(); - } - menu.get().moveTo(pos.x, pos.y); - visibleState.set(true); - }; - var $_8gzlukajjgqkwzad = { show: show }; - - var isNativeOverrideKeyEvent = function (editor, e) { - return e.ctrlKey && !$_d5n2szafjgqkwza9.shouldNeverUseNative(editor); - }; - var setup = function (editor, visibleState, menu) { - editor.on('contextmenu', function (e) { - if (isNativeOverrideKeyEvent(editor, e)) { - return; - } - e.preventDefault(); - $_8gzlukajjgqkwzad.show(editor, $_s0illagjgqkwzaa.getPos(editor, e), visibleState, menu); - }); - }; - var $_cxl5y3aejgqkwza7 = { setup: setup }; - - global.add('contextmenu', function (editor) { - var menu = Cell(null), visibleState = Cell(false); - $_cxl5y3aejgqkwza7.setup(editor, visibleState, menu); - return $_cv44lcadjgqkwza6.get(visibleState); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.min.js deleted file mode 100755 index a2e2c754..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/contextmenu/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var o=function(t){var n=t,e=function(){return n};return{get:e,set:function(t){n=t},clone:function(){return o(e())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(t){return{isContextMenuVisible:function(){return t.get()}}},r=function(t){return t.settings.contextmenu_never_use_native},u=function(t){return t.getParam("contextmenu","link openlink image inserttable | cell row column deletetable")},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),s=function(t){return l.DOM.select(t.settings.ui_container)[0]},a=function(t,n){return{x:t,y:n}},f=function(t,n,e){return a(t.x+n,t.y+e)},m=function(t,n){if(t&&"static"!==l.DOM.getStyle(t,"position",!0)){var e=l.DOM.getPos(t),o=e.x-t.scrollLeft,i=e.y-t.scrollTop;return f(n,-o,-i)}return f(n,0,0)},c=function(t,n){if(t.inline)return m(s(t),a((u=n).pageX,u.pageY));var e,o,i,r,u,c=(e=t.getContentAreaContainer(),o=a((r=n).clientX,r.clientY),i=l.DOM.getPos(e),f(o,i.x,i.y));return m(s(t),c)},g=tinymce.util.Tools.resolve("tinymce.ui.Factory"),v=tinymce.util.Tools.resolve("tinymce.util.Tools"),y=function(t,n,e,o){null===o.get()?o.set(function(e,n){var t,o,i=[];o=u(e),v.each(o.split(/[ ,]/),function(t){var n=e.menuItems[t];"|"===t&&(n={text:t}),n&&(n.shortcut="",i.push(n))});for(var r=0;r'; - }); - emoticonsHtml += ''; - }); - emoticonsHtml += ''; - return emoticonsHtml; - }; - var $_3j6v8davjgqkwzbj = { getHtml: getHtml }; - - var insertEmoticon = function (editor, src, alt) { - editor.insertContent(editor.dom.createHTML('img', { - src: src, - alt: alt - })); - }; - var register = function (editor, pluginUrl) { - var panelHtml = $_3j6v8davjgqkwzbj.getHtml(pluginUrl); - editor.addButton('emoticons', { - type: 'panelbutton', - panel: { - role: 'application', - autohide: true, - html: panelHtml, - onclick: function (e) { - var linkElm = editor.dom.getParent(e.target, 'a'); - if (linkElm) { - insertEmoticon(editor, linkElm.getAttribute('data-mce-url'), linkElm.getAttribute('data-mce-alt')); - this.hide(); - } - } - }, - tooltip: 'Emoticons' - }); - }; - var $_3yx3cmaujgqkwzbh = { register: register }; - - global.add('emoticons', function (editor, pluginUrl) { - $_3yx3cmaujgqkwzbh.register(editor, pluginUrl); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/emoticons/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/emoticons/plugin.min.js deleted file mode 100755 index 4e3cd251..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/emoticons/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),n=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]],i=function(i){var o;return o='',e.each(n,function(t){o+="",e.each(t,function(t){var e=i+"/img/smiley-"+t+".gif";o+=''}),o+=""}),o+="
      "},o=function(a,t){var e=i(t);a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:e,onclick:function(t){var e,i,o,n=a.dom.getParent(t.target,"a");n&&(e=a,i=n.getAttribute("data-mce-url"),o=n.getAttribute("data-mce-alt"),e.insertContent(e.dom.createHTML("img",{src:i,alt:o})),this.hide())}},tooltip:"Emoticons"})};t.add("emoticons",function(t,e){o(t,e)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/index.js deleted file mode 100755 index c327d6a0..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "fullpage" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/fullpage') -// ES2015: -// import 'tinymce/plugins/fullpage' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.js deleted file mode 100755 index a5143dc0..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.js +++ /dev/null @@ -1,519 +0,0 @@ -(function () { -var fullpage = (function () { - 'use strict'; - - var Cell = function (initial) { - var value = initial; - var get = function () { - return value; - }; - var set = function (v) { - value = v; - }; - var clone = function () { - return Cell(get()); - }; - return { - get: get, - set: set, - clone: clone - }; - }; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var global$1 = tinymce.util.Tools.resolve('tinymce.util.Tools'); - - var global$2 = tinymce.util.Tools.resolve('tinymce.html.DomParser'); - - var global$3 = tinymce.util.Tools.resolve('tinymce.html.Node'); - - var global$4 = tinymce.util.Tools.resolve('tinymce.html.Serializer'); - - var shouldHideInSourceView = function (editor) { - return editor.getParam('fullpage_hide_in_source_view'); - }; - var getDefaultXmlPi = function (editor) { - return editor.getParam('fullpage_default_xml_pi'); - }; - var getDefaultEncoding = function (editor) { - return editor.getParam('fullpage_default_encoding'); - }; - var getDefaultFontFamily = function (editor) { - return editor.getParam('fullpage_default_font_family'); - }; - var getDefaultFontSize = function (editor) { - return editor.getParam('fullpage_default_font_size'); - }; - var getDefaultTextColor = function (editor) { - return editor.getParam('fullpage_default_text_color'); - }; - var getDefaultTitle = function (editor) { - return editor.getParam('fullpage_default_title'); - }; - var getDefaultDocType = function (editor) { - return editor.getParam('fullpage_default_doctype', ''); - }; - var $_ad0r8lbsjgqkwzfn = { - shouldHideInSourceView: shouldHideInSourceView, - getDefaultXmlPi: getDefaultXmlPi, - getDefaultEncoding: getDefaultEncoding, - getDefaultFontFamily: getDefaultFontFamily, - getDefaultFontSize: getDefaultFontSize, - getDefaultTextColor: getDefaultTextColor, - getDefaultTitle: getDefaultTitle, - getDefaultDocType: getDefaultDocType - }; - - var parseHeader = function (head) { - return global$2({ - validate: false, - root_name: '#document' - }).parse(head); - }; - var htmlToData = function (editor, head) { - var headerFragment = parseHeader(head); - var data = {}; - var elm, matches; - function getAttr(elm, name) { - var value = elm.attr(name); - return value || ''; - } - data.fontface = $_ad0r8lbsjgqkwzfn.getDefaultFontFamily(editor); - data.fontsize = $_ad0r8lbsjgqkwzfn.getDefaultFontSize(editor); - elm = headerFragment.firstChild; - if (elm.type === 7) { - data.xml_pi = true; - matches = /encoding="([^"]+)"/.exec(elm.value); - if (matches) { - data.docencoding = matches[1]; - } - } - elm = headerFragment.getAll('#doctype')[0]; - if (elm) { - data.doctype = ''; - } - elm = headerFragment.getAll('title')[0]; - if (elm && elm.firstChild) { - data.title = elm.firstChild.value; - } - global$1.each(headerFragment.getAll('meta'), function (meta) { - var name = meta.attr('name'); - var httpEquiv = meta.attr('http-equiv'); - var matches; - if (name) { - data[name.toLowerCase()] = meta.attr('content'); - } else if (httpEquiv === 'Content-Type') { - matches = /charset\s*=\s*(.*)\s*/gi.exec(meta.attr('content')); - if (matches) { - data.docencoding = matches[1]; - } - } - }); - elm = headerFragment.getAll('html')[0]; - if (elm) { - data.langcode = getAttr(elm, 'lang') || getAttr(elm, 'xml:lang'); - } - data.stylesheets = []; - global$1.each(headerFragment.getAll('link'), function (link) { - if (link.attr('rel') === 'stylesheet') { - data.stylesheets.push(link.attr('href')); - } - }); - elm = headerFragment.getAll('body')[0]; - if (elm) { - data.langdir = getAttr(elm, 'dir'); - data.style = getAttr(elm, 'style'); - data.visited_color = getAttr(elm, 'vlink'); - data.link_color = getAttr(elm, 'link'); - data.active_color = getAttr(elm, 'alink'); - } - return data; - }; - var dataToHtml = function (editor, data, head) { - var headerFragment, headElement, html, elm, value; - var dom = editor.dom; - function setAttr(elm, name, value) { - elm.attr(name, value ? value : undefined); - } - function addHeadNode(node) { - if (headElement.firstChild) { - headElement.insert(node, headElement.firstChild); - } else { - headElement.append(node); - } - } - headerFragment = parseHeader(head); - headElement = headerFragment.getAll('head')[0]; - if (!headElement) { - elm = headerFragment.getAll('html')[0]; - headElement = new global$3('head', 1); - if (elm.firstChild) { - elm.insert(headElement, elm.firstChild, true); - } else { - elm.append(headElement); - } - } - elm = headerFragment.firstChild; - if (data.xml_pi) { - value = 'version="1.0"'; - if (data.docencoding) { - value += ' encoding="' + data.docencoding + '"'; - } - if (elm.type !== 7) { - elm = new global$3('xml', 7); - headerFragment.insert(elm, headerFragment.firstChild, true); - } - elm.value = value; - } else if (elm && elm.type === 7) { - elm.remove(); - } - elm = headerFragment.getAll('#doctype')[0]; - if (data.doctype) { - if (!elm) { - elm = new global$3('#doctype', 10); - if (data.xml_pi) { - headerFragment.insert(elm, headerFragment.firstChild); - } else { - addHeadNode(elm); - } - } - elm.value = data.doctype.substring(9, data.doctype.length - 1); - } else if (elm) { - elm.remove(); - } - elm = null; - global$1.each(headerFragment.getAll('meta'), function (meta) { - if (meta.attr('http-equiv') === 'Content-Type') { - elm = meta; - } - }); - if (data.docencoding) { - if (!elm) { - elm = new global$3('meta', 1); - elm.attr('http-equiv', 'Content-Type'); - elm.shortEnded = true; - addHeadNode(elm); - } - elm.attr('content', 'text/html; charset=' + data.docencoding); - } else if (elm) { - elm.remove(); - } - elm = headerFragment.getAll('title')[0]; - if (data.title) { - if (!elm) { - elm = new global$3('title', 1); - addHeadNode(elm); - } else { - elm.empty(); - } - elm.append(new global$3('#text', 3)).value = data.title; - } else if (elm) { - elm.remove(); - } - global$1.each('keywords,description,author,copyright,robots'.split(','), function (name) { - var nodes = headerFragment.getAll('meta'); - var i, meta; - var value = data[name]; - for (i = 0; i < nodes.length; i++) { - meta = nodes[i]; - if (meta.attr('name') === name) { - if (value) { - meta.attr('content', value); - } else { - meta.remove(); - } - return; - } - } - if (value) { - elm = new global$3('meta', 1); - elm.attr('name', name); - elm.attr('content', value); - elm.shortEnded = true; - addHeadNode(elm); - } - }); - var currentStyleSheetsMap = {}; - global$1.each(headerFragment.getAll('link'), function (stylesheet) { - if (stylesheet.attr('rel') === 'stylesheet') { - currentStyleSheetsMap[stylesheet.attr('href')] = stylesheet; - } - }); - global$1.each(data.stylesheets, function (stylesheet) { - if (!currentStyleSheetsMap[stylesheet]) { - elm = new global$3('link', 1); - elm.attr({ - rel: 'stylesheet', - text: 'text/css', - href: stylesheet - }); - elm.shortEnded = true; - addHeadNode(elm); - } - delete currentStyleSheetsMap[stylesheet]; - }); - global$1.each(currentStyleSheetsMap, function (stylesheet) { - stylesheet.remove(); - }); - elm = headerFragment.getAll('body')[0]; - if (elm) { - setAttr(elm, 'dir', data.langdir); - setAttr(elm, 'style', data.style); - setAttr(elm, 'vlink', data.visited_color); - setAttr(elm, 'link', data.link_color); - setAttr(elm, 'alink', data.active_color); - dom.setAttribs(editor.getBody(), { - style: data.style, - dir: data.dir, - vLink: data.visited_color, - link: data.link_color, - aLink: data.active_color - }); - } - elm = headerFragment.getAll('html')[0]; - if (elm) { - setAttr(elm, 'lang', data.langcode); - setAttr(elm, 'xml:lang', data.langcode); - } - if (!headElement.firstChild) { - headElement.remove(); - } - html = global$4({ - validate: false, - indent: true, - apply_source_formatting: true, - indent_before: 'head,html,body,meta,title,script,link,style', - indent_after: 'head,html,body,meta,title,script,link,style' - }).serialize(headerFragment); - return html.substring(0, html.indexOf('')); - }; - var $_f845etbojgqkwzfg = { - parseHeader: parseHeader, - htmlToData: htmlToData, - dataToHtml: dataToHtml - }; - - var open = function (editor, headState) { - var data = $_f845etbojgqkwzfg.htmlToData(editor, headState.get()); - editor.windowManager.open({ - title: 'Document properties', - data: data, - defaults: { - type: 'textbox', - size: 40 - }, - body: [ - { - name: 'title', - label: 'Title' - }, - { - name: 'keywords', - label: 'Keywords' - }, - { - name: 'description', - label: 'Description' - }, - { - name: 'robots', - label: 'Robots' - }, - { - name: 'author', - label: 'Author' - }, - { - name: 'docencoding', - label: 'Encoding' - } - ], - onSubmit: function (e) { - var headHtml = $_f845etbojgqkwzfg.dataToHtml(editor, global$1.extend(data, e.data), headState.get()); - headState.set(headHtml); - } - }); - }; - var $_b3jcc9bmjgqkwzfc = { open: open }; - - var register = function (editor, headState) { - editor.addCommand('mceFullPageProperties', function () { - $_b3jcc9bmjgqkwzfc.open(editor, headState); - }); - }; - var $_3416p9bljgqkwzfb = { register: register }; - - var protectHtml = function (protect, html) { - global$1.each(protect, function (pattern) { - html = html.replace(pattern, function (str) { - return ''; - }); - }); - return html; - }; - var unprotectHtml = function (html) { - return html.replace(//g, function (a, m) { - return unescape(m); - }); - }; - var $_2b2dvjbujgqkwzfu = { - protectHtml: protectHtml, - unprotectHtml: unprotectHtml - }; - - var each = global$1.each; - var low = function (s) { - return s.replace(/<\/?[A-Z]+/g, function (a) { - return a.toLowerCase(); - }); - }; - var handleSetContent = function (editor, headState, footState, evt) { - var startPos, endPos, content, headerFragment, styles = ''; - var dom = editor.dom; - var elm; - if (evt.selection) { - return; - } - content = $_2b2dvjbujgqkwzfu.protectHtml(editor.settings.protect, evt.content); - if (evt.format === 'raw' && headState.get()) { - return; - } - if (evt.source_view && $_ad0r8lbsjgqkwzfn.shouldHideInSourceView(editor)) { - return; - } - if (content.length === 0 && !evt.source_view) { - content = global$1.trim(headState.get()) + '\n' + global$1.trim(content) + '\n' + global$1.trim(footState.get()); - } - content = content.replace(/<(\/?)BODY/gi, '<$1body'); - startPos = content.indexOf('', startPos); - headState.set(low(content.substring(0, startPos + 1))); - endPos = content.indexOf('\n'); - } - headerFragment = $_f845etbojgqkwzfg.parseHeader(headState.get()); - each(headerFragment.getAll('style'), function (node) { - if (node.firstChild) { - styles += node.firstChild.value; - } - }); - elm = headerFragment.getAll('body')[0]; - if (elm) { - dom.setAttribs(editor.getBody(), { - style: elm.attr('style') || '', - dir: elm.attr('dir') || '', - vLink: elm.attr('vlink') || '', - link: elm.attr('link') || '', - aLink: elm.attr('alink') || '' - }); - } - dom.remove('fullpage_styles'); - var headElm = editor.getDoc().getElementsByTagName('head')[0]; - if (styles) { - dom.add(headElm, 'style', { id: 'fullpage_styles' }, styles); - elm = dom.get('fullpage_styles'); - if (elm.styleSheet) { - elm.styleSheet.cssText = styles; - } - } - var currentStyleSheetsMap = {}; - global$1.each(headElm.getElementsByTagName('link'), function (stylesheet) { - if (stylesheet.rel === 'stylesheet' && stylesheet.getAttribute('data-mce-fullpage')) { - currentStyleSheetsMap[stylesheet.href] = stylesheet; - } - }); - global$1.each(headerFragment.getAll('link'), function (stylesheet) { - var href = stylesheet.attr('href'); - if (!href) { - return true; - } - if (!currentStyleSheetsMap[href] && stylesheet.attr('rel') === 'stylesheet') { - dom.add(headElm, 'link', { - 'rel': 'stylesheet', - 'text': 'text/css', - 'href': href, - 'data-mce-fullpage': '1' - }); - } - delete currentStyleSheetsMap[href]; - }); - global$1.each(currentStyleSheetsMap, function (stylesheet) { - stylesheet.parentNode.removeChild(stylesheet); - }); - }; - var getDefaultHeader = function (editor) { - var header = '', value, styles = ''; - if ($_ad0r8lbsjgqkwzfn.getDefaultXmlPi(editor)) { - var piEncoding = $_ad0r8lbsjgqkwzfn.getDefaultEncoding(editor); - header += '\n'; - } - header += $_ad0r8lbsjgqkwzfn.getDefaultDocType(editor); - header += '\n\n\n'; - if (value = $_ad0r8lbsjgqkwzfn.getDefaultTitle(editor)) { - header += '' + value + '\n'; - } - if (value = $_ad0r8lbsjgqkwzfn.getDefaultEncoding(editor)) { - header += '\n'; - } - if (value = $_ad0r8lbsjgqkwzfn.getDefaultFontFamily(editor)) { - styles += 'font-family: ' + value + ';'; - } - if (value = $_ad0r8lbsjgqkwzfn.getDefaultFontSize(editor)) { - styles += 'font-size: ' + value + ';'; - } - if (value = $_ad0r8lbsjgqkwzfn.getDefaultTextColor(editor)) { - styles += 'color: ' + value + ';'; - } - header += '\n\n'; - return header; - }; - var handleGetContent = function (editor, head, foot, evt) { - if (!evt.selection && (!evt.source_view || !$_ad0r8lbsjgqkwzfn.shouldHideInSourceView(editor))) { - evt.content = $_2b2dvjbujgqkwzfu.unprotectHtml(global$1.trim(head) + '\n' + global$1.trim(evt.content) + '\n' + global$1.trim(foot)); - } - }; - var setup = function (editor, headState, footState) { - editor.on('BeforeSetContent', function (evt) { - handleSetContent(editor, headState, footState, evt); - }); - editor.on('GetContent', function (evt) { - handleGetContent(editor, headState.get(), footState.get(), evt); - }); - }; - var $_7ayih0btjgqkwzfq = { setup: setup }; - - var register$1 = function (editor) { - editor.addButton('fullpage', { - title: 'Document properties', - cmd: 'mceFullPageProperties' - }); - editor.addMenuItem('fullpage', { - text: 'Document properties', - cmd: 'mceFullPageProperties', - context: 'file' - }); - }; - var $_7os420bvjgqkwzfv = { register: register$1 }; - - global.add('fullpage', function (editor) { - var headState = Cell(''), footState = Cell(''); - $_3416p9bljgqkwzfb.register(editor, headState); - $_7os420bvjgqkwzfv.register(editor); - $_7ayih0btjgqkwzfq.setup(editor, headState, footState); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.min.js deleted file mode 100755 index de5221a8..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullpage/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var l=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return l(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),g=tinymce.util.Tools.resolve("tinymce.util.Tools"),t=tinymce.util.Tools.resolve("tinymce.html.DomParser"),f=tinymce.util.Tools.resolve("tinymce.html.Node"),m=tinymce.util.Tools.resolve("tinymce.html.Serializer"),h=function(e){return e.getParam("fullpage_hide_in_source_view")},r=function(e){return e.getParam("fullpage_default_xml_pi")},o=function(e){return e.getParam("fullpage_default_encoding")},a=function(e){return e.getParam("fullpage_default_font_family")},c=function(e){return e.getParam("fullpage_default_font_size")},s=function(e){return e.getParam("fullpage_default_text_color")},u=function(e){return e.getParam("fullpage_default_title")},d=function(e){return e.getParam("fullpage_default_doctype","")},p=function(e){return t({validate:!1,root_name:"#document"}).parse(e)},y=p,v=function(e,t){var n,l,i=p(t),r={};function o(e,t){return e.attr(t)||""}return r.fontface=a(e),r.fontsize=c(e),7===(n=i.firstChild).type&&(r.xml_pi=!0,(l=/encoding="([^"]+)"/.exec(n.value))&&(r.docencoding=l[1])),(n=i.getAll("#doctype")[0])&&(r.doctype=""),(n=i.getAll("title")[0])&&n.firstChild&&(r.title=n.firstChild.value),g.each(i.getAll("meta"),function(e){var t,n=e.attr("name"),l=e.attr("http-equiv");n?r[n.toLowerCase()]=e.attr("content"):"Content-Type"===l&&(t=/charset\s*=\s*(.*)\s*/gi.exec(e.attr("content")))&&(r.docencoding=t[1])}),(n=i.getAll("html")[0])&&(r.langcode=o(n,"lang")||o(n,"xml:lang")),r.stylesheets=[],g.each(i.getAll("link"),function(e){"stylesheet"===e.attr("rel")&&r.stylesheets.push(e.attr("href"))}),(n=i.getAll("body")[0])&&(r.langdir=o(n,"dir"),r.style=o(n,"style"),r.visited_color=o(n,"vlink"),r.link_color=o(n,"link"),r.active_color=o(n,"alink")),r},_=function(e,r,t){var o,n,l,a,i,c=e.dom;function s(e,t,n){e.attr(t,n||undefined)}function u(e){n.firstChild?n.insert(e,n.firstChild):n.append(e)}o=p(t),(n=o.getAll("head")[0])||(a=o.getAll("html")[0],n=new f("head",1),a.firstChild?a.insert(n,a.firstChild,!0):a.append(n)),a=o.firstChild,r.xml_pi?(i='version="1.0"',r.docencoding&&(i+=' encoding="'+r.docencoding+'"'),7!==a.type&&(a=new f("xml",7),o.insert(a,o.firstChild,!0)),a.value=i):a&&7===a.type&&a.remove(),a=o.getAll("#doctype")[0],r.doctype?(a||(a=new f("#doctype",10),r.xml_pi?o.insert(a,o.firstChild):u(a)),a.value=r.doctype.substring(9,r.doctype.length-1)):a&&a.remove(),a=null,g.each(o.getAll("meta"),function(e){"Content-Type"===e.attr("http-equiv")&&(a=e)}),r.docencoding?(a||((a=new f("meta",1)).attr("http-equiv","Content-Type"),a.shortEnded=!0,u(a)),a.attr("content","text/html; charset="+r.docencoding)):a&&a.remove(),a=o.getAll("title")[0],r.title?(a?a.empty():u(a=new f("title",1)),a.append(new f("#text",3)).value=r.title):a&&a.remove(),g.each("keywords,description,author,copyright,robots".split(","),function(e){var t,n,l=o.getAll("meta"),i=r[e];for(t=0;t"))},n=function(n,l){var i=v(n,l.get());n.windowManager.open({title:"Document properties",data:i,defaults:{type:"textbox",size:40},body:[{name:"title",label:"Title"},{name:"keywords",label:"Keywords"},{name:"description",label:"Description"},{name:"robots",label:"Robots"},{name:"author",label:"Author"},{name:"docencoding",label:"Encoding"}],onSubmit:function(e){var t=_(n,g.extend(i,e.data),l.get());l.set(t)}})},i=function(e,t){e.addCommand("mceFullPageProperties",function(){n(e,t)})},b=function(e,t){return g.each(e,function(e){t=t.replace(e,function(e){return"\x3c!--mce:protected "+escape(e)+"--\x3e"})}),t},x=function(e){return e.replace(//g,function(e,t){return unescape(t)})},k=g.each,C=function(e){return e.replace(/<\/?[A-Z]+/g,function(e){return e.toLowerCase()})},A=function(e){var t,n="",l="";if(r(e)){var i=o(e);n+='\n'}return n+=d(e),n+="\n\n\n",(t=u(e))&&(n+=""+t+"\n"),(t=o(e))&&(n+='\n'),(t=a(e))&&(l+="font-family: "+t+";"),(t=c(e))&&(l+="font-size: "+t+";"),(t=s(e))&&(l+="color: "+t+";"),n+="\n\n"},w=function(r,o,a){r.on("BeforeSetContent",function(e){!function(e,t,n,l){var i,r,o,a,c,s="",u=e.dom;if(!(l.selection||(o=b(e.settings.protect,l.content),"raw"===l.format&&t.get()||l.source_view&&h(e)))){0!==o.length||l.source_view||(o=g.trim(t.get())+"\n"+g.trim(o)+"\n"+g.trim(n.get())),-1!==(i=(o=o.replace(/<(\/?)BODY/gi,"<$1body")).indexOf("",i),t.set(C(o.substring(0,i+1))),-1===(r=o.indexOf("\n")),a=y(t.get()),k(a.getAll("style"),function(e){e.firstChild&&(s+=e.firstChild.value)}),(c=a.getAll("body")[0])&&u.setAttribs(e.getBody(),{style:c.attr("style")||"",dir:c.attr("dir")||"",vLink:c.attr("vlink")||"",link:c.attr("link")||"",aLink:c.attr("alink")||""}),u.remove("fullpage_styles");var d=e.getDoc().getElementsByTagName("head")[0];s&&(u.add(d,"style",{id:"fullpage_styles"},s),(c=u.get("fullpage_styles")).styleSheet&&(c.styleSheet.cssText=s));var f={};g.each(d.getElementsByTagName("link"),function(e){"stylesheet"===e.rel&&e.getAttribute("data-mce-fullpage")&&(f[e.href]=e)}),g.each(a.getAll("link"),function(e){var t=e.attr("href");if(!t)return!0;f[t]||"stylesheet"!==e.attr("rel")||u.add(d,"link",{rel:"stylesheet",text:"text/css",href:t,"data-mce-fullpage":"1"}),delete f[t]}),g.each(f,function(e){e.parentNode.removeChild(e)})}}(r,o,a,e)}),r.on("GetContent",function(e){var t,n,l,i;t=r,n=o.get(),l=a.get(),(i=e).selection||i.source_view&&h(t)||(i.content=x(g.trim(n)+"\n"+g.trim(i.content)+"\n"+g.trim(l)))})},P=function(e){e.addButton("fullpage",{title:"Document properties",cmd:"mceFullPageProperties"}),e.addMenuItem("fullpage",{text:"Document properties",cmd:"mceFullPageProperties",context:"file"})};e.add("fullpage",function(e){var t=l(""),n=l("");i(e,t),P(e),w(e,t,n)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/index.js deleted file mode 100755 index 6b4e2632..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "fullscreen" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/fullscreen') -// ES2015: -// import 'tinymce/plugins/fullscreen' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.js deleted file mode 100755 index d4f33eed..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.js +++ /dev/null @@ -1,177 +0,0 @@ -(function () { -var fullscreen = (function () { - 'use strict'; - - var Cell = function (initial) { - var value = initial; - var get = function () { - return value; - }; - var set = function (v) { - value = v; - }; - var clone = function () { - return Cell(get()); - }; - return { - get: get, - set: set, - clone: clone - }; - }; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var get = function (fullscreenState) { - return { - isFullscreen: function () { - return fullscreenState.get() !== null; - } - }; - }; - var $_fj9gw3bzjgqkwzgu = { get: get }; - - var global$1 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var fireFullscreenStateChanged = function (editor, state) { - editor.fire('FullscreenStateChanged', { state: state }); - }; - var $_704do3c3jgqkwzgz = { fireFullscreenStateChanged: fireFullscreenStateChanged }; - - var DOM = global$1.DOM; - var getWindowSize = function () { - var w; - var h; - var win = window; - var doc = document; - var body = doc.body; - if (body.offsetWidth) { - w = body.offsetWidth; - h = body.offsetHeight; - } - if (win.innerWidth && win.innerHeight) { - w = win.innerWidth; - h = win.innerHeight; - } - return { - w: w, - h: h - }; - }; - var getScrollPos = function () { - var vp = DOM.getViewPort(); - return { - x: vp.x, - y: vp.y - }; - }; - var setScrollPos = function (pos) { - window.scrollTo(pos.x, pos.y); - }; - var toggleFullscreen = function (editor, fullscreenState) { - var body = document.body; - var documentElement = document.documentElement; - var editorContainerStyle; - var editorContainer, iframe, iframeStyle; - var fullscreenInfo = fullscreenState.get(); - var resize = function () { - DOM.setStyle(iframe, 'height', getWindowSize().h - (editorContainer.clientHeight - iframe.clientHeight)); - }; - var removeResize = function () { - DOM.unbind(window, 'resize', resize); - }; - editorContainer = editor.getContainer(); - editorContainerStyle = editorContainer.style; - iframe = editor.getContentAreaContainer().firstChild; - iframeStyle = iframe.style; - if (!fullscreenInfo) { - var newFullScreenInfo = { - scrollPos: getScrollPos(), - containerWidth: editorContainerStyle.width, - containerHeight: editorContainerStyle.height, - iframeWidth: iframeStyle.width, - iframeHeight: iframeStyle.height, - resizeHandler: resize, - removeHandler: removeResize - }; - iframeStyle.width = iframeStyle.height = '100%'; - editorContainerStyle.width = editorContainerStyle.height = ''; - DOM.addClass(body, 'mce-fullscreen'); - DOM.addClass(documentElement, 'mce-fullscreen'); - DOM.addClass(editorContainer, 'mce-fullscreen'); - DOM.bind(window, 'resize', resize); - editor.on('remove', removeResize); - resize(); - fullscreenState.set(newFullScreenInfo); - $_704do3c3jgqkwzgz.fireFullscreenStateChanged(editor, true); - } else { - iframeStyle.width = fullscreenInfo.iframeWidth; - iframeStyle.height = fullscreenInfo.iframeHeight; - if (fullscreenInfo.containerWidth) { - editorContainerStyle.width = fullscreenInfo.containerWidth; - } - if (fullscreenInfo.containerHeight) { - editorContainerStyle.height = fullscreenInfo.containerHeight; - } - DOM.removeClass(body, 'mce-fullscreen'); - DOM.removeClass(documentElement, 'mce-fullscreen'); - DOM.removeClass(editorContainer, 'mce-fullscreen'); - setScrollPos(fullscreenInfo.scrollPos); - DOM.unbind(window, 'resize', fullscreenInfo.resizeHandler); - editor.off('remove', fullscreenInfo.removeHandler); - fullscreenState.set(null); - $_704do3c3jgqkwzgz.fireFullscreenStateChanged(editor, false); - } - }; - var $_4x4grc1jgqkwzgw = { toggleFullscreen: toggleFullscreen }; - - var register = function (editor, fullscreenState) { - editor.addCommand('mceFullScreen', function () { - $_4x4grc1jgqkwzgw.toggleFullscreen(editor, fullscreenState); - }); - }; - var $_6831zyc0jgqkwzgv = { register: register }; - - var postRender = function (editor) { - return function (e) { - var ctrl = e.control; - editor.on('FullscreenStateChanged', function (e) { - ctrl.active(e.state); - }); - }; - }; - var register$1 = function (editor) { - editor.addMenuItem('fullscreen', { - text: 'Fullscreen', - shortcut: 'Ctrl+Shift+F', - selectable: true, - cmd: 'mceFullScreen', - onPostRender: postRender(editor), - context: 'view' - }); - editor.addButton('fullscreen', { - active: false, - tooltip: 'Fullscreen', - cmd: 'mceFullScreen', - onPostRender: postRender(editor) - }); - }; - var $_7ta5tgc4jgqkwzh0 = { register: register$1 }; - - global.add('fullscreen', function (editor) { - var fullscreenState = Cell(null); - if (editor.settings.inline) { - return $_fj9gw3bzjgqkwzgu.get(fullscreenState); - } - $_6831zyc0jgqkwzgv.register(editor, fullscreenState); - $_7ta5tgc4jgqkwzh0.register(editor); - editor.addShortcut('Ctrl+Shift+F', '', 'mceFullScreen'); - return $_fj9gw3bzjgqkwzgu.get(fullscreenState); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.min.js deleted file mode 100755 index cd4eb5ed..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/fullscreen/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var i=function(e){var n=e,t=function(){return n};return{get:t,set:function(e){n=e},clone:function(){return i(t())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return{isFullscreen:function(){return null!==e.get()}}},n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),m=function(e,n){e.fire("FullscreenStateChanged",{state:n})},g=n.DOM,r=function(e,n){var t,r,l,i,o,c,s=document.body,u=document.documentElement,d=n.get(),a=function(){var e,n,t,i;g.setStyle(l,"height",(t=window,i=document.body,i.offsetWidth&&(e=i.offsetWidth,n=i.offsetHeight),t.innerWidth&&t.innerHeight&&(e=t.innerWidth,n=t.innerHeight),{w:e,h:n}).h-(r.clientHeight-l.clientHeight))},h=function(){g.unbind(window,"resize",a)};if(t=(r=e.getContainer()).style,i=(l=e.getContentAreaContainer().firstChild).style,d)i.width=d.iframeWidth,i.height=d.iframeHeight,d.containerWidth&&(t.width=d.containerWidth),d.containerHeight&&(t.height=d.containerHeight),g.removeClass(s,"mce-fullscreen"),g.removeClass(u,"mce-fullscreen"),g.removeClass(r,"mce-fullscreen"),o=d.scrollPos,window.scrollTo(o.x,o.y),g.unbind(window,"resize",d.resizeHandler),e.off("remove",d.removeHandler),n.set(null),m(e,!1);else{var f={scrollPos:(c=g.getViewPort(),{x:c.x,y:c.y}),containerWidth:t.width,containerHeight:t.height,iframeWidth:i.width,iframeHeight:i.height,resizeHandler:a,removeHandler:h};i.width=i.height="100%",t.width=t.height="",g.addClass(s,"mce-fullscreen"),g.addClass(u,"mce-fullscreen"),g.addClass(r,"mce-fullscreen"),g.bind(window,"resize",a),e.on("remove",h),a(),n.set(f),m(e,!0)}},l=function(e,n){e.addCommand("mceFullScreen",function(){r(e,n)})},o=function(t){return function(e){var n=e.control;t.on("FullscreenStateChanged",function(e){n.active(e.state)})}},c=function(e){e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Shift+F",selectable:!0,cmd:"mceFullScreen",onPostRender:o(e),context:"view"}),e.addButton("fullscreen",{active:!1,tooltip:"Fullscreen",cmd:"mceFullScreen",onPostRender:o(e)})};e.add("fullscreen",function(e){var n=i(null);return e.settings.inline||(l(e,n),c(e),e.addShortcut("Ctrl+Shift+F","","mceFullScreen")),t(n)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/help/img/logo.png b/iiif-5-day-workshop/day-three/mirador/plugins/help/img/logo.png deleted file mode 100755 index ebd7eb14..00000000 Binary files a/iiif-5-day-workshop/day-three/mirador/plugins/help/img/logo.png and /dev/null differ diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/help/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/help/index.js deleted file mode 100755 index 7f4bfe02..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/help/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "help" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/help') -// ES2015: -// import 'tinymce/plugins/help' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.js deleted file mode 100755 index 2bc5bf04..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.js +++ /dev/null @@ -1,1111 +0,0 @@ -(function () { -var help = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var noop = function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - }; - var noarg = function (f) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return f(); - }; - }; - var compose = function (fa, fb) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return fa(fb.apply(null, arguments)); - }; - }; - var constant = function (value) { - return function () { - return value; - }; - }; - var identity = function (x) { - return x; - }; - var tripleEquals = function (a, b) { - return a === b; - }; - var curry = function (f) { - var x = []; - for (var _i = 1; _i < arguments.length; _i++) { - x[_i - 1] = arguments[_i]; - } - var args = new Array(arguments.length - 1); - for (var i = 1; i < arguments.length; i++) - args[i - 1] = arguments[i]; - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - var newArgs = new Array(arguments.length); - for (var j = 0; j < newArgs.length; j++) - newArgs[j] = arguments[j]; - var all = args.concat(newArgs); - return f.apply(null, all); - }; - }; - var not = function (f) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return !f.apply(null, arguments); - }; - }; - var die = function (msg) { - return function () { - throw new Error(msg); - }; - }; - var apply = function (f) { - return f(); - }; - var call = function (f) { - f(); - }; - var never = constant(false); - var always = constant(true); - var $_dkohb3b4jgqkwzcb = { - noop: noop, - noarg: noarg, - compose: compose, - constant: constant, - identity: identity, - tripleEquals: tripleEquals, - curry: curry, - not: not, - die: die, - apply: apply, - call: call, - never: never, - always: always - }; - - var never$1 = $_dkohb3b4jgqkwzcb.never; - var always$1 = $_dkohb3b4jgqkwzcb.always; - var none = function () { - return NONE; - }; - var NONE = function () { - var eq = function (o) { - return o.isNone(); - }; - var call = function (thunk) { - return thunk(); - }; - var id = function (n) { - return n; - }; - var noop = function () { - }; - var me = { - fold: function (n, s) { - return n(); - }, - is: never$1, - isSome: never$1, - isNone: always$1, - getOr: id, - getOrThunk: call, - getOrDie: function (msg) { - throw new Error(msg || 'error: getOrDie called on none.'); - }, - or: id, - orThunk: call, - map: none, - ap: none, - each: noop, - bind: none, - flatten: none, - exists: never$1, - forall: always$1, - filter: none, - equals: eq, - equals_: eq, - toArray: function () { - return []; - }, - toString: $_dkohb3b4jgqkwzcb.constant('none()') - }; - if (Object.freeze) - Object.freeze(me); - return me; - }(); - var some = function (a) { - var constant_a = function () { - return a; - }; - var self = function () { - return me; - }; - var map = function (f) { - return some(f(a)); - }; - var bind = function (f) { - return f(a); - }; - var me = { - fold: function (n, s) { - return s(a); - }, - is: function (v) { - return a === v; - }, - isSome: always$1, - isNone: never$1, - getOr: constant_a, - getOrThunk: constant_a, - getOrDie: constant_a, - or: self, - orThunk: self, - map: map, - ap: function (optfab) { - return optfab.fold(none, function (fab) { - return some(fab(a)); - }); - }, - each: function (f) { - f(a); - }, - bind: bind, - flatten: constant_a, - exists: bind, - forall: bind, - filter: function (f) { - return f(a) ? me : NONE; - }, - equals: function (o) { - return o.is(a); - }, - equals_: function (o, elementEq) { - return o.fold(never$1, function (b) { - return elementEq(a, b); - }); - }, - toArray: function () { - return [a]; - }, - toString: function () { - return 'some(' + a + ')'; - } - }; - return me; - }; - var from = function (value) { - return value === null || value === undefined ? NONE : some(value); - }; - var Option = { - some: some, - none: none, - from: from - }; - - var typeOf = function (x) { - if (x === null) - return 'null'; - var t = typeof x; - if (t === 'object' && Array.prototype.isPrototypeOf(x)) - return 'array'; - if (t === 'object' && String.prototype.isPrototypeOf(x)) - return 'string'; - return t; - }; - var isType = function (type) { - return function (value) { - return typeOf(value) === type; - }; - }; - var $_e9th4lb5jgqkwzce = { - isString: isType('string'), - isObject: isType('object'), - isArray: isType('array'), - isNull: isType('null'), - isBoolean: isType('boolean'), - isUndefined: isType('undefined'), - isFunction: isType('function'), - isNumber: isType('number') - }; - - var rawIndexOf = function () { - var pIndexOf = Array.prototype.indexOf; - var fastIndex = function (xs, x) { - return pIndexOf.call(xs, x); - }; - var slowIndex = function (xs, x) { - return slowIndexOf(xs, x); - }; - return pIndexOf === undefined ? slowIndex : fastIndex; - }(); - var indexOf = function (xs, x) { - var r = rawIndexOf(xs, x); - return r === -1 ? Option.none() : Option.some(r); - }; - var contains = function (xs, x) { - return rawIndexOf(xs, x) > -1; - }; - var exists = function (xs, pred) { - return findIndex(xs, pred).isSome(); - }; - var range = function (num, f) { - var r = []; - for (var i = 0; i < num; i++) { - r.push(f(i)); - } - return r; - }; - var chunk = function (array, size) { - var r = []; - for (var i = 0; i < array.length; i += size) { - var s = array.slice(i, i + size); - r.push(s); - } - return r; - }; - var map = function (xs, f) { - var len = xs.length; - var r = new Array(len); - for (var i = 0; i < len; i++) { - var x = xs[i]; - r[i] = f(x, i, xs); - } - return r; - }; - var each = function (xs, f) { - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - f(x, i, xs); - } - }; - var eachr = function (xs, f) { - for (var i = xs.length - 1; i >= 0; i--) { - var x = xs[i]; - f(x, i, xs); - } - }; - var partition = function (xs, pred) { - var pass = []; - var fail = []; - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - var arr = pred(x, i, xs) ? pass : fail; - arr.push(x); - } - return { - pass: pass, - fail: fail - }; - }; - var filter = function (xs, pred) { - var r = []; - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - if (pred(x, i, xs)) { - r.push(x); - } - } - return r; - }; - var groupBy = function (xs, f) { - if (xs.length === 0) { - return []; - } else { - var wasType = f(xs[0]); - var r = []; - var group = []; - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - var type = f(x); - if (type !== wasType) { - r.push(group); - group = []; - } - wasType = type; - group.push(x); - } - if (group.length !== 0) { - r.push(group); - } - return r; - } - }; - var foldr = function (xs, f, acc) { - eachr(xs, function (x) { - acc = f(acc, x); - }); - return acc; - }; - var foldl = function (xs, f, acc) { - each(xs, function (x) { - acc = f(acc, x); - }); - return acc; - }; - var find = function (xs, pred) { - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - if (pred(x, i, xs)) { - return Option.some(x); - } - } - return Option.none(); - }; - var findIndex = function (xs, pred) { - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - if (pred(x, i, xs)) { - return Option.some(i); - } - } - return Option.none(); - }; - var slowIndexOf = function (xs, x) { - for (var i = 0, len = xs.length; i < len; ++i) { - if (xs[i] === x) { - return i; - } - } - return -1; - }; - var push = Array.prototype.push; - var flatten = function (xs) { - var r = []; - for (var i = 0, len = xs.length; i < len; ++i) { - if (!Array.prototype.isPrototypeOf(xs[i])) - throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs); - push.apply(r, xs[i]); - } - return r; - }; - var bind = function (xs, f) { - var output = map(xs, f); - return flatten(output); - }; - var forall = function (xs, pred) { - for (var i = 0, len = xs.length; i < len; ++i) { - var x = xs[i]; - if (pred(x, i, xs) !== true) { - return false; - } - } - return true; - }; - var equal = function (a1, a2) { - return a1.length === a2.length && forall(a1, function (x, i) { - return x === a2[i]; - }); - }; - var slice = Array.prototype.slice; - var reverse = function (xs) { - var r = slice.call(xs, 0); - r.reverse(); - return r; - }; - var difference = function (a1, a2) { - return filter(a1, function (x) { - return !contains(a2, x); - }); - }; - var mapToObject = function (xs, f) { - var r = {}; - for (var i = 0, len = xs.length; i < len; i++) { - var x = xs[i]; - r[String(x)] = f(x, i); - } - return r; - }; - var pure = function (x) { - return [x]; - }; - var sort = function (xs, comparator) { - var copy = slice.call(xs, 0); - copy.sort(comparator); - return copy; - }; - var head = function (xs) { - return xs.length === 0 ? Option.none() : Option.some(xs[0]); - }; - var last = function (xs) { - return xs.length === 0 ? Option.none() : Option.some(xs[xs.length - 1]); - }; - var from$1 = $_e9th4lb5jgqkwzce.isFunction(Array.from) ? Array.from : function (x) { - return slice.call(x); - }; - var $_5cx5j4b2jgqkwzc2 = { - map: map, - each: each, - eachr: eachr, - partition: partition, - filter: filter, - groupBy: groupBy, - indexOf: indexOf, - foldr: foldr, - foldl: foldl, - find: find, - findIndex: findIndex, - flatten: flatten, - bind: bind, - forall: forall, - exists: exists, - contains: contains, - equal: equal, - reverse: reverse, - chunk: chunk, - difference: difference, - mapToObject: mapToObject, - pure: pure, - sort: sort, - range: range, - head: head, - last: last, - from: from$1 - }; - - var global$1 = tinymce.util.Tools.resolve('tinymce.util.I18n'); - - var global$2 = tinymce.util.Tools.resolve('tinymce.Env'); - - var meta = global$2.mac ? '\u2318' : 'Ctrl'; - var access = global$2.mac ? 'Ctrl + Alt' : 'Shift + Alt'; - var shortcuts = [ - { - shortcut: meta + ' + B', - action: 'Bold' - }, - { - shortcut: meta + ' + I', - action: 'Italic' - }, - { - shortcut: meta + ' + U', - action: 'Underline' - }, - { - shortcut: meta + ' + A', - action: 'Select all' - }, - { - shortcut: meta + ' + Y or ' + meta + ' + Shift + Z', - action: 'Redo' - }, - { - shortcut: meta + ' + Z', - action: 'Undo' - }, - { - shortcut: access + ' + 1', - action: 'Header 1' - }, - { - shortcut: access + ' + 2', - action: 'Header 2' - }, - { - shortcut: access + ' + 3', - action: 'Header 3' - }, - { - shortcut: access + ' + 4', - action: 'Header 4' - }, - { - shortcut: access + ' + 5', - action: 'Header 5' - }, - { - shortcut: access + ' + 6', - action: 'Header 6' - }, - { - shortcut: access + ' + 7', - action: 'Paragraph' - }, - { - shortcut: access + ' + 8', - action: 'Div' - }, - { - shortcut: access + ' + 9', - action: 'Address' - }, - { - shortcut: 'Alt + F9', - action: 'Focus to menubar' - }, - { - shortcut: 'Alt + F10', - action: 'Focus to toolbar' - }, - { - shortcut: 'Alt + F11', - action: 'Focus to element path' - }, - { - shortcut: 'Ctrl + Shift + P > Ctrl + Shift + P', - action: 'Focus to contextual toolbar' - }, - { - shortcut: meta + ' + K', - action: 'Insert link (if link plugin activated)' - }, - { - shortcut: meta + ' + S', - action: 'Save (if save plugin activated)' - }, - { - shortcut: meta + ' + F', - action: 'Find (if searchreplace plugin activated)' - } - ]; - var $_g41d9pb7jgqkwzcg = { shortcuts: shortcuts }; - - var makeTab = function () { - var makeAriaLabel = function (shortcut) { - return 'aria-label="Action: ' + shortcut.action + ', Shortcut: ' + shortcut.shortcut.replace(/Ctrl/g, 'Control') + '"'; - }; - var shortcutLisString = $_5cx5j4b2jgqkwzc2.map($_g41d9pb7jgqkwzcg.shortcuts, function (shortcut) { - return '' + '' + global$1.translate(shortcut.action) + '' + '' + shortcut.shortcut + '' + ''; - }).join(''); - return { - title: 'Handy Shortcuts', - type: 'container', - style: 'overflow-y: auto; overflow-x: hidden; max-height: 250px', - items: [{ - type: 'container', - html: '
      ' + '' + '' + '' + '' + '' + shortcutLisString + '
      ' + global$1.translate('Action') + '' + global$1.translate('Shortcut') + '
      ' + '
      ' - }] - }; - }; - var $_2c2a02b1jgqkwzbv = { makeTab: makeTab }; - - var keys = function () { - var fastKeys = Object.keys; - var slowKeys = function (o) { - var r = []; - for (var i in o) { - if (o.hasOwnProperty(i)) { - r.push(i); - } - } - return r; - }; - return fastKeys === undefined ? slowKeys : fastKeys; - }(); - var each$1 = function (obj, f) { - var props = keys(obj); - for (var k = 0, len = props.length; k < len; k++) { - var i = props[k]; - var x = obj[i]; - f(x, i, obj); - } - }; - var objectMap = function (obj, f) { - return tupleMap(obj, function (x, i, obj) { - return { - k: i, - v: f(x, i, obj) - }; - }); - }; - var tupleMap = function (obj, f) { - var r = {}; - each$1(obj, function (x, i) { - var tuple = f(x, i, obj); - r[tuple.k] = tuple.v; - }); - return r; - }; - var bifilter = function (obj, pred) { - var t = {}; - var f = {}; - each$1(obj, function (x, i) { - var branch = pred(x, i) ? t : f; - branch[i] = x; - }); - return { - t: t, - f: f - }; - }; - var mapToArray = function (obj, f) { - var r = []; - each$1(obj, function (value, name) { - r.push(f(value, name)); - }); - return r; - }; - var find$1 = function (obj, pred) { - var props = keys(obj); - for (var k = 0, len = props.length; k < len; k++) { - var i = props[k]; - var x = obj[i]; - if (pred(x, i, obj)) { - return Option.some(x); - } - } - return Option.none(); - }; - var values = function (obj) { - return mapToArray(obj, function (v) { - return v; - }); - }; - var size = function (obj) { - return values(obj).length; - }; - var $_2czydcbajgqkwzcs = { - bifilter: bifilter, - each: each$1, - map: objectMap, - mapToArray: mapToArray, - tupleMap: tupleMap, - find: find$1, - keys: keys, - values: values, - size: size - }; - - var addToStart = function (str, prefix) { - return prefix + str; - }; - var addToEnd = function (str, suffix) { - return str + suffix; - }; - var removeFromStart = function (str, numChars) { - return str.substring(numChars); - }; - var removeFromEnd = function (str, numChars) { - return str.substring(0, str.length - numChars); - }; - var $_1xztqkbcjgqkwzd0 = { - addToStart: addToStart, - addToEnd: addToEnd, - removeFromStart: removeFromStart, - removeFromEnd: removeFromEnd - }; - - var first = function (str, count) { - return str.substr(0, count); - }; - var last$1 = function (str, count) { - return str.substr(str.length - count, str.length); - }; - var head$1 = function (str) { - return str === '' ? Option.none() : Option.some(str.substr(0, 1)); - }; - var tail = function (str) { - return str === '' ? Option.none() : Option.some(str.substring(1)); - }; - var $_vqh9cbdjgqkwzd2 = { - first: first, - last: last$1, - head: head$1, - tail: tail - }; - - var checkRange = function (str, substr, start) { - if (substr === '') - return true; - if (str.length < substr.length) - return false; - var x = str.substr(start, start + substr.length); - return x === substr; - }; - var supplant = function (str, obj) { - var isStringOrNumber = function (a) { - var t = typeof a; - return t === 'string' || t === 'number'; - }; - return str.replace(/\${([^{}]*)}/g, function (a, b) { - var value = obj[b]; - return isStringOrNumber(value) ? value : a; - }); - }; - var removeLeading = function (str, prefix) { - return startsWith(str, prefix) ? $_1xztqkbcjgqkwzd0.removeFromStart(str, prefix.length) : str; - }; - var removeTrailing = function (str, prefix) { - return endsWith(str, prefix) ? $_1xztqkbcjgqkwzd0.removeFromEnd(str, prefix.length) : str; - }; - var ensureLeading = function (str, prefix) { - return startsWith(str, prefix) ? str : $_1xztqkbcjgqkwzd0.addToStart(str, prefix); - }; - var ensureTrailing = function (str, prefix) { - return endsWith(str, prefix) ? str : $_1xztqkbcjgqkwzd0.addToEnd(str, prefix); - }; - var contains$1 = function (str, substr) { - return str.indexOf(substr) !== -1; - }; - var capitalize = function (str) { - return $_vqh9cbdjgqkwzd2.head(str).bind(function (head) { - return $_vqh9cbdjgqkwzd2.tail(str).map(function (tail) { - return head.toUpperCase() + tail; - }); - }).getOr(str); - }; - var startsWith = function (str, prefix) { - return checkRange(str, prefix, 0); - }; - var endsWith = function (str, suffix) { - return checkRange(str, suffix, str.length - suffix.length); - }; - var trim = function (str) { - return str.replace(/^\s+|\s+$/g, ''); - }; - var lTrim = function (str) { - return str.replace(/^\s+/g, ''); - }; - var rTrim = function (str) { - return str.replace(/\s+$/g, ''); - }; - var $_bbcqjqbbjgqkwzcv = { - supplant: supplant, - startsWith: startsWith, - removeLeading: removeLeading, - removeTrailing: removeTrailing, - ensureLeading: ensureLeading, - ensureTrailing: ensureTrailing, - endsWith: endsWith, - contains: contains$1, - trim: trim, - lTrim: lTrim, - rTrim: rTrim, - capitalize: capitalize - }; - - var urls = [ - { - key: 'advlist', - name: 'Advanced List' - }, - { - key: 'anchor', - name: 'Anchor' - }, - { - key: 'autolink', - name: 'Autolink' - }, - { - key: 'autoresize', - name: 'Autoresize' - }, - { - key: 'autosave', - name: 'Autosave' - }, - { - key: 'bbcode', - name: 'BBCode' - }, - { - key: 'charmap', - name: 'Character Map' - }, - { - key: 'code', - name: 'Code' - }, - { - key: 'codesample', - name: 'Code Sample' - }, - { - key: 'colorpicker', - name: 'Color Picker' - }, - { - key: 'compat3x', - name: '3.x Compatibility' - }, - { - key: 'contextmenu', - name: 'Context Menu' - }, - { - key: 'directionality', - name: 'Directionality' - }, - { - key: 'emoticons', - name: 'Emoticons' - }, - { - key: 'fullpage', - name: 'Full Page' - }, - { - key: 'fullscreen', - name: 'Full Screen' - }, - { - key: 'help', - name: 'Help' - }, - { - key: 'hr', - name: 'Horizontal Rule' - }, - { - key: 'image', - name: 'Image' - }, - { - key: 'imagetools', - name: 'Image Tools' - }, - { - key: 'importcss', - name: 'Import CSS' - }, - { - key: 'insertdatetime', - name: 'Insert Date/Time' - }, - { - key: 'legacyoutput', - name: 'Legacy Output' - }, - { - key: 'link', - name: 'Link' - }, - { - key: 'lists', - name: 'Lists' - }, - { - key: 'media', - name: 'Media' - }, - { - key: 'nonbreaking', - name: 'Nonbreaking' - }, - { - key: 'noneditable', - name: 'Noneditable' - }, - { - key: 'pagebreak', - name: 'Page Break' - }, - { - key: 'paste', - name: 'Paste' - }, - { - key: 'preview', - name: 'Preview' - }, - { - key: 'print', - name: 'Print' - }, - { - key: 'save', - name: 'Save' - }, - { - key: 'searchreplace', - name: 'Search and Replace' - }, - { - key: 'spellchecker', - name: 'Spell Checker' - }, - { - key: 'tabfocus', - name: 'Tab Focus' - }, - { - key: 'table', - name: 'Table' - }, - { - key: 'template', - name: 'Template' - }, - { - key: 'textcolor', - name: 'Text Color' - }, - { - key: 'textpattern', - name: 'Text Pattern' - }, - { - key: 'toc', - name: 'Table of Contents' - }, - { - key: 'visualblocks', - name: 'Visual Blocks' - }, - { - key: 'visualchars', - name: 'Visual Characters' - }, - { - key: 'wordcount', - name: 'Word Count' - } - ]; - var $_deieambejgqkwzd4 = { urls: urls }; - - var makeLink = $_dkohb3b4jgqkwzcb.curry($_bbcqjqbbjgqkwzcv.supplant, '${name}'); - var maybeUrlize = function (editor, key) { - return $_5cx5j4b2jgqkwzc2.find($_deieambejgqkwzd4.urls, function (x) { - return x.key === key; - }).fold(function () { - var getMetadata = editor.plugins[key].getMetadata; - return typeof getMetadata === 'function' ? makeLink(getMetadata()) : key; - }, function (x) { - return makeLink({ - name: x.name, - url: 'https://www.tinymce.com/docs/plugins/' + x.key - }); - }); - }; - var getPluginKeys = function (editor) { - var keys = $_2czydcbajgqkwzcs.keys(editor.plugins); - return editor.settings.forced_plugins === undefined ? keys : $_5cx5j4b2jgqkwzc2.filter(keys, $_dkohb3b4jgqkwzcb.not($_dkohb3b4jgqkwzcb.curry($_5cx5j4b2jgqkwzc2.contains, editor.settings.forced_plugins))); - }; - var pluginLister = function (editor) { - var pluginKeys = getPluginKeys(editor); - var pluginLis = $_5cx5j4b2jgqkwzc2.map(pluginKeys, function (key) { - return '
    • ' + maybeUrlize(editor, key) + '
    • '; - }); - var count = pluginLis.length; - var pluginsString = pluginLis.join(''); - return '

      ' + global$1.translate([ - 'Plugins installed ({0}):', - count - ]) + '

      ' + '
        ' + pluginsString + '
      '; - }; - var installedPlugins = function (editor) { - return { - type: 'container', - html: '
      ' + pluginLister(editor) + '
      ', - flex: 1 - }; - }; - var availablePlugins = function () { - return { - type: 'container', - html: '
      ' + '

      ' + global$1.translate('Premium plugins:') + '

      ' + '
        ' + '
      • PowerPaste
      • ' + '
      • Spell Checker Pro
      • ' + '
      • Accessibility Checker
      • ' + '
      • Advanced Code Editor
      • ' + '
      • Enhanced Media Embed
      • ' + '
      • Link Checker
      • ' + '

      ' + '

      ' + global$1.translate('Learn more...') + '

      ' + '
      ', - flex: 1 - }; - }; - var makeTab$1 = function (editor) { - return { - title: 'Plugins', - type: 'container', - style: 'overflow-y: auto; overflow-x: hidden;', - layout: 'flex', - padding: 10, - spacing: 10, - items: [ - installedPlugins(editor), - availablePlugins() - ] - }; - }; - var $_1qmxetb9jgqkwzcj = { makeTab: makeTab$1 }; - - var global$3 = tinymce.util.Tools.resolve('tinymce.EditorManager'); - - var getVersion = function (major, minor) { - return major.indexOf('@') === 0 ? 'X.X.X' : major + '.' + minor; - }; - var makeRow = function () { - var version = getVersion(global$3.majorVersion, global$3.minorVersion); - var changeLogLink = 'TinyMCE ' + version + ''; - return [ - { - type: 'label', - html: global$1.translate([ - 'You are using {0}', - changeLogLink - ]) - }, - { - type: 'spacer', - flex: 1 - }, - { - text: 'Close', - onclick: function () { - this.parent().parent().close(); - } - } - ]; - }; - var $_atagc7bfjgqkwzd6 = { makeRow: makeRow }; - - var open = function (editor, pluginUrl) { - return function () { - editor.windowManager.open({ - title: 'Help', - bodyType: 'tabpanel', - layout: 'flex', - body: [ - $_2c2a02b1jgqkwzbv.makeTab(), - $_1qmxetb9jgqkwzcj.makeTab(editor) - ], - buttons: $_atagc7bfjgqkwzd6.makeRow(), - onPostRender: function () { - var title = this.getEl('title'); - title.innerHTML = 'TinyMCE Logo'; - } - }); - }; - }; - var $_39tdb2b0jgqkwzbu = { open: open }; - - var register = function (editor, pluginUrl) { - editor.addCommand('mceHelp', $_39tdb2b0jgqkwzbu.open(editor, pluginUrl)); - }; - var $_1ekvu1azjgqkwzbs = { register: register }; - - var register$1 = function (editor, pluginUrl) { - editor.addButton('help', { - icon: 'help', - onclick: $_39tdb2b0jgqkwzbu.open(editor, pluginUrl) - }); - editor.addMenuItem('help', { - text: 'Help', - icon: 'help', - context: 'help', - onclick: $_39tdb2b0jgqkwzbu.open(editor, pluginUrl) - }); - }; - var $_bll4pubhjgqkwzd8 = { register: register$1 }; - - global.add('help', function (editor, pluginUrl) { - $_bll4pubhjgqkwzd8.register(editor, pluginUrl); - $_1ekvu1azjgqkwzbs.register(editor, pluginUrl); - editor.shortcuts.add('Alt+0', 'Open help dialog', 'mceHelp'); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.min.js deleted file mode 100755 index 95c071b4..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/help/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e,t,n,r,o,a,i=tinymce.util.Tools.resolve("tinymce.PluginManager"),u=function(e){return function(){return e}},c=u(!1),l=u(!0),s={noop:function(){for(var e=[],t=0;t Ctrl + Shift + P",action:"Focus to contextual toolbar"},{shortcut:F+" + K",action:"Insert link (if link plugin activated)"},{shortcut:F+" + S",action:"Save (if save plugin activated)"},{shortcut:F+" + F",action:"Find (if searchreplace plugin activated)"}]},E=function(){var e=C(M.shortcuts,function(e){return''+O.translate(e.action)+""+e.shortcut+"";var t}).join("");return{title:"Handy Shortcuts",type:"container",style:"overflow-y: auto; overflow-x: hidden; max-height: 250px",items:[{type:"container",html:'
      "+e+"
      '+O.translate("Action")+""+O.translate("Shortcut")+"
      "}]}},j=(a=Object.keys)===undefined?function(e){var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n);return t}:a,I=function(e,t){for(var n=j(e),r=0,o=n.length;r${name}'),R=function(r){var e,t,n=(e=r,t=z.keys(e.plugins),e.settings.forced_plugins===undefined?t:S(t,s.not(s.curry(T,e.settings.forced_plugins)))),o=C(n,function(e){return"
    • "+(t=r,n=e,P(D,function(e){return e.key===n}).fold(function(){var e=t.plugins[n].getMetadata;return"function"==typeof e?q(e()):n},function(e){return q({name:e.name,url:"https://www.tinymce.com/docs/plugins/"+e.key})}))+"
    • ";var t,n}),a=o.length,i=o.join("");return"

      "+O.translate(["Plugins installed ({0}):",a])+"

        "+i+"
      "},U=function(e){return{title:"Plugins",type:"container",style:"overflow-y: auto; overflow-x: hidden;",layout:"flex",padding:10,spacing:10,items:[(t=e,{type:"container",html:'
      '+R(t)+"
      ",flex:1}),{type:"container",html:'

      '+O.translate("Premium plugins:")+'

      • PowerPaste
      • Spell Checker Pro
      • Accessibility Checker
      • Advanced Code Editor
      • Enhanced Media Embed
      • Link Checker

      '+O.translate("Learn more...")+"

      ",flex:1}]};var t},V=tinymce.util.Tools.resolve("tinymce.EditorManager"),X=function(){var e,t,n='TinyMCE '+(e=V.majorVersion,t=V.minorVersion,0===e.indexOf("@")?"X.X.X":e+"."+t)+"";return[{type:"label",html:O.translate(["You are using {0}",n])},{type:"spacer",flex:1},{text:"Close",onclick:function(){this.parent().parent().close()}}]},$=function(e,t){return function(){e.windowManager.open({title:"Help",bodyType:"tabpanel",layout:"flex",body:[E(),U(e)],buttons:X(),onPostRender:function(){this.getEl("title").innerHTML='TinyMCE Logo'}})}},Y=function(e,t){e.addCommand("mceHelp",$(e,t))},Z=function(e,t){e.addButton("help",{icon:"help",onclick:$(e,t)}),e.addMenuItem("help",{text:"Help",icon:"help",context:"help",onclick:$(e,t)})};i.add("help",function(e,t){Z(e,t),Y(e,t),e.shortcuts.add("Alt+0","Open help dialog","mceHelp")})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/hr/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/hr/index.js deleted file mode 100755 index e4c56e5b..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/hr/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "hr" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/hr') -// ES2015: -// import 'tinymce/plugins/hr' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.js deleted file mode 100755 index 7710b591..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.js +++ /dev/null @@ -1,39 +0,0 @@ -(function () { -var hr = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var register = function (editor) { - editor.addCommand('InsertHorizontalRule', function () { - editor.execCommand('mceInsertContent', false, '
      '); - }); - }; - var $_cybu97c7jgqkwzhd = { register: register }; - - var register$1 = function (editor) { - editor.addButton('hr', { - icon: 'hr', - tooltip: 'Horizontal line', - cmd: 'InsertHorizontalRule' - }); - editor.addMenuItem('hr', { - icon: 'hr', - text: 'Horizontal line', - cmd: 'InsertHorizontalRule', - context: 'insert' - }); - }; - var $_dc77bbc8jgqkwzhe = { register: register$1 }; - - global.add('hr', function (editor) { - $_cybu97c7jgqkwzhd.register(editor); - $_dc77bbc8jgqkwzhe.register(editor); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.min.js deleted file mode 100755 index 72bc2cab..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/hr/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(n){n.addCommand("InsertHorizontalRule",function(){n.execCommand("mceInsertContent",!1,"
      ")})},o=function(n){n.addButton("hr",{icon:"hr",tooltip:"Horizontal line",cmd:"InsertHorizontalRule"}),n.addMenuItem("hr",{icon:"hr",text:"Horizontal line",cmd:"InsertHorizontalRule",context:"insert"})};n.add("hr",function(n){t(n),o(n)})}(); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/image/index.js b/iiif-5-day-workshop/day-three/mirador/plugins/image/index.js deleted file mode 100755 index 092c73ad..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/image/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Exports the "image" plugin for usage with module loaders -// Usage: -// CommonJS: -// require('tinymce/plugins/image') -// ES2015: -// import 'tinymce/plugins/image' -require('./plugin.js'); \ No newline at end of file diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.js b/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.js deleted file mode 100755 index 45465b58..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.js +++ /dev/null @@ -1,1337 +0,0 @@ -(function () { -var image = (function () { - 'use strict'; - - var global = tinymce.util.Tools.resolve('tinymce.PluginManager'); - - var hasDimensions = function (editor) { - return editor.settings.image_dimensions === false ? false : true; - }; - var hasAdvTab = function (editor) { - return editor.settings.image_advtab === true ? true : false; - }; - var getPrependUrl = function (editor) { - return editor.getParam('image_prepend_url', ''); - }; - var getClassList = function (editor) { - return editor.getParam('image_class_list'); - }; - var hasDescription = function (editor) { - return editor.settings.image_description === false ? false : true; - }; - var hasImageTitle = function (editor) { - return editor.settings.image_title === true ? true : false; - }; - var hasImageCaption = function (editor) { - return editor.settings.image_caption === true ? true : false; - }; - var getImageList = function (editor) { - return editor.getParam('image_list', false); - }; - var hasUploadUrl = function (editor) { - return editor.getParam('images_upload_url', false); - }; - var hasUploadHandler = function (editor) { - return editor.getParam('images_upload_handler', false); - }; - var getUploadUrl = function (editor) { - return editor.getParam('images_upload_url'); - }; - var getUploadHandler = function (editor) { - return editor.getParam('images_upload_handler'); - }; - var getUploadBasePath = function (editor) { - return editor.getParam('images_upload_base_path'); - }; - var getUploadCredentials = function (editor) { - return editor.getParam('images_upload_credentials'); - }; - var $_76jaztcdjgqkwzmx = { - hasDimensions: hasDimensions, - hasAdvTab: hasAdvTab, - getPrependUrl: getPrependUrl, - getClassList: getClassList, - hasDescription: hasDescription, - hasImageTitle: hasImageTitle, - hasImageCaption: hasImageCaption, - getImageList: getImageList, - hasUploadUrl: hasUploadUrl, - hasUploadHandler: hasUploadHandler, - getUploadUrl: getUploadUrl, - getUploadHandler: getUploadHandler, - getUploadBasePath: getUploadBasePath, - getUploadCredentials: getUploadCredentials - }; - - var global$1 = typeof window !== 'undefined' ? window : Function('return this;')(); - - var path = function (parts, scope) { - var o = scope !== undefined && scope !== null ? scope : global$1; - for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i) - o = o[parts[i]]; - return o; - }; - var resolve = function (p, scope) { - var parts = p.split('.'); - return path(parts, scope); - }; - var step = function (o, part) { - if (o[part] === undefined || o[part] === null) - o[part] = {}; - return o[part]; - }; - var forge = function (parts, target) { - var o = target !== undefined ? target : global$1; - for (var i = 0; i < parts.length; ++i) - o = step(o, parts[i]); - return o; - }; - var namespace = function (name, target) { - var parts = name.split('.'); - return forge(parts, target); - }; - var $_3ym5h8chjgqkwznn = { - path: path, - resolve: resolve, - forge: forge, - namespace: namespace - }; - - var unsafe = function (name, scope) { - return $_3ym5h8chjgqkwznn.resolve(name, scope); - }; - var getOrDie = function (name, scope) { - var actual = unsafe(name, scope); - if (actual === undefined || actual === null) - throw name + ' not available on this browser'; - return actual; - }; - var $_g2wawpcgjgqkwznj = { getOrDie: getOrDie }; - - function FileReader () { - var f = $_g2wawpcgjgqkwznj.getOrDie('FileReader'); - return new f(); - } - - var global$2 = tinymce.util.Tools.resolve('tinymce.util.Promise'); - - var global$3 = tinymce.util.Tools.resolve('tinymce.util.Tools'); - - var global$4 = tinymce.util.Tools.resolve('tinymce.util.XHR'); - - var parseIntAndGetMax = function (val1, val2) { - return Math.max(parseInt(val1, 10), parseInt(val2, 10)); - }; - var getImageSize = function (url, callback) { - var img = document.createElement('img'); - function done(width, height) { - if (img.parentNode) { - img.parentNode.removeChild(img); - } - callback({ - width: width, - height: height - }); - } - img.onload = function () { - var width = parseIntAndGetMax(img.width, img.clientWidth); - var height = parseIntAndGetMax(img.height, img.clientHeight); - done(width, height); - }; - img.onerror = function () { - done(0, 0); - }; - var style = img.style; - style.visibility = 'hidden'; - style.position = 'fixed'; - style.bottom = style.left = '0px'; - style.width = style.height = 'auto'; - document.body.appendChild(img); - img.src = url; - }; - var buildListItems = function (inputList, itemCallback, startItems) { - function appendItems(values, output) { - output = output || []; - global$3.each(values, function (item) { - var menuItem = { text: item.text || item.title }; - if (item.menu) { - menuItem.menu = appendItems(item.menu); - } else { - menuItem.value = item.value; - itemCallback(menuItem); - } - output.push(menuItem); - }); - return output; - } - return appendItems(inputList, startItems || []); - }; - var removePixelSuffix = function (value) { - if (value) { - value = value.replace(/px$/, ''); - } - return value; - }; - var addPixelSuffix = function (value) { - if (value.length > 0 && /^[0-9]+$/.test(value)) { - value += 'px'; - } - return value; - }; - var mergeMargins = function (css) { - if (css.margin) { - var splitMargin = css.margin.split(' '); - switch (splitMargin.length) { - case 1: - css['margin-top'] = css['margin-top'] || splitMargin[0]; - css['margin-right'] = css['margin-right'] || splitMargin[0]; - css['margin-bottom'] = css['margin-bottom'] || splitMargin[0]; - css['margin-left'] = css['margin-left'] || splitMargin[0]; - break; - case 2: - css['margin-top'] = css['margin-top'] || splitMargin[0]; - css['margin-right'] = css['margin-right'] || splitMargin[1]; - css['margin-bottom'] = css['margin-bottom'] || splitMargin[0]; - css['margin-left'] = css['margin-left'] || splitMargin[1]; - break; - case 3: - css['margin-top'] = css['margin-top'] || splitMargin[0]; - css['margin-right'] = css['margin-right'] || splitMargin[1]; - css['margin-bottom'] = css['margin-bottom'] || splitMargin[2]; - css['margin-left'] = css['margin-left'] || splitMargin[1]; - break; - case 4: - css['margin-top'] = css['margin-top'] || splitMargin[0]; - css['margin-right'] = css['margin-right'] || splitMargin[1]; - css['margin-bottom'] = css['margin-bottom'] || splitMargin[2]; - css['margin-left'] = css['margin-left'] || splitMargin[3]; - } - delete css.margin; - } - return css; - }; - var createImageList = function (editor, callback) { - var imageList = $_76jaztcdjgqkwzmx.getImageList(editor); - if (typeof imageList === 'string') { - global$4.send({ - url: imageList, - success: function (text) { - callback(JSON.parse(text)); - } - }); - } else if (typeof imageList === 'function') { - imageList(callback); - } else { - callback(imageList); - } - }; - var waitLoadImage = function (editor, data, imgElm) { - function selectImage() { - imgElm.onload = imgElm.onerror = null; - if (editor.selection) { - editor.selection.select(imgElm); - editor.nodeChanged(); - } - } - imgElm.onload = function () { - if (!data.width && !data.height && $_76jaztcdjgqkwzmx.hasDimensions(editor)) { - editor.dom.setAttribs(imgElm, { - width: imgElm.clientWidth, - height: imgElm.clientHeight - }); - } - selectImage(); - }; - imgElm.onerror = selectImage; - }; - var blobToDataUri = function (blob) { - return new global$2(function (resolve, reject) { - var reader = new FileReader(); - reader.onload = function () { - resolve(reader.result); - }; - reader.onerror = function () { - reject(FileReader.error.message); - }; - reader.readAsDataURL(blob); - }); - }; - var $_3p4hsscejgqkwzna = { - getImageSize: getImageSize, - buildListItems: buildListItems, - removePixelSuffix: removePixelSuffix, - addPixelSuffix: addPixelSuffix, - mergeMargins: mergeMargins, - createImageList: createImageList, - waitLoadImage: waitLoadImage, - blobToDataUri: blobToDataUri - }; - - var global$5 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var typeOf = function (x) { - if (x === null) - return 'null'; - var t = typeof x; - if (t === 'object' && Array.prototype.isPrototypeOf(x)) - return 'array'; - if (t === 'object' && String.prototype.isPrototypeOf(x)) - return 'string'; - return t; - }; - var isType = function (type) { - return function (value) { - return typeOf(value) === type; - }; - }; - var $_8qffccrjgqkwzod = { - isString: isType('string'), - isObject: isType('object'), - isArray: isType('array'), - isNull: isType('null'), - isBoolean: isType('boolean'), - isUndefined: isType('undefined'), - isFunction: isType('function'), - isNumber: isType('number') - }; - - var shallow = function (old, nu) { - return nu; - }; - var deep = function (old, nu) { - var bothObjects = $_8qffccrjgqkwzod.isObject(old) && $_8qffccrjgqkwzod.isObject(nu); - return bothObjects ? deepMerge(old, nu) : nu; - }; - var baseMerge = function (merger) { - return function () { - var objects = new Array(arguments.length); - for (var i = 0; i < objects.length; i++) - objects[i] = arguments[i]; - if (objects.length === 0) - throw new Error('Can\'t merge zero objects'); - var ret = {}; - for (var j = 0; j < objects.length; j++) { - var curObject = objects[j]; - for (var key in curObject) - if (curObject.hasOwnProperty(key)) { - ret[key] = merger(ret[key], curObject[key]); - } - } - return ret; - }; - }; - var deepMerge = baseMerge(deep); - var merge = baseMerge(shallow); - var $_sdccncqjgqkwzob = { - deepMerge: deepMerge, - merge: merge - }; - - var DOM = global$5.DOM; - var getHspace = function (image) { - if (image.style.marginLeft && image.style.marginRight && image.style.marginLeft === image.style.marginRight) { - return $_3p4hsscejgqkwzna.removePixelSuffix(image.style.marginLeft); - } else { - return ''; - } - }; - var getVspace = function (image) { - if (image.style.marginTop && image.style.marginBottom && image.style.marginTop === image.style.marginBottom) { - return $_3p4hsscejgqkwzna.removePixelSuffix(image.style.marginTop); - } else { - return ''; - } - }; - var getBorder = function (image) { - if (image.style.borderWidth) { - return $_3p4hsscejgqkwzna.removePixelSuffix(image.style.borderWidth); - } else { - return ''; - } - }; - var getAttrib = function (image, name) { - if (image.hasAttribute(name)) { - return image.getAttribute(name); - } else { - return ''; - } - }; - var getStyle = function (image, name) { - return image.style[name] ? image.style[name] : ''; - }; - var hasCaption = function (image) { - return image.parentNode !== null && image.parentNode.nodeName === 'FIGURE'; - }; - var setAttrib = function (image, name, value) { - image.setAttribute(name, value); - }; - var wrapInFigure = function (image) { - var figureElm = DOM.create('figure', { class: 'image' }); - DOM.insertAfter(figureElm, image); - figureElm.appendChild(image); - figureElm.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption')); - figureElm.contentEditable = 'false'; - }; - var removeFigure = function (image) { - var figureElm = image.parentNode; - DOM.insertAfter(image, figureElm); - DOM.remove(figureElm); - }; - var toggleCaption = function (image) { - if (hasCaption(image)) { - removeFigure(image); - } else { - wrapInFigure(image); - } - }; - var normalizeStyle = function (image, normalizeCss) { - var attrValue = image.getAttribute('style'); - var value = normalizeCss(attrValue !== null ? attrValue : ''); - if (value.length > 0) { - image.setAttribute('style', value); - image.setAttribute('data-mce-style', value); - } else { - image.removeAttribute('style'); - } - }; - var setSize = function (name, normalizeCss) { - return function (image, name, value) { - if (image.style[name]) { - image.style[name] = $_3p4hsscejgqkwzna.addPixelSuffix(value); - normalizeStyle(image, normalizeCss); - } else { - setAttrib(image, name, value); - } - }; - }; - var getSize = function (image, name) { - if (image.style[name]) { - return $_3p4hsscejgqkwzna.removePixelSuffix(image.style[name]); - } else { - return getAttrib(image, name); - } - }; - var setHspace = function (image, value) { - var pxValue = $_3p4hsscejgqkwzna.addPixelSuffix(value); - image.style.marginLeft = pxValue; - image.style.marginRight = pxValue; - }; - var setVspace = function (image, value) { - var pxValue = $_3p4hsscejgqkwzna.addPixelSuffix(value); - image.style.marginTop = pxValue; - image.style.marginBottom = pxValue; - }; - var setBorder = function (image, value) { - var pxValue = $_3p4hsscejgqkwzna.addPixelSuffix(value); - image.style.borderWidth = pxValue; - }; - var setBorderStyle = function (image, value) { - image.style.borderStyle = value; - }; - var getBorderStyle = function (image) { - return getStyle(image, 'borderStyle'); - }; - var isFigure = function (elm) { - return elm.nodeName === 'FIGURE'; - }; - var defaultData = function () { - return { - src: '', - alt: '', - title: '', - width: '', - height: '', - class: '', - style: '', - caption: false, - hspace: '', - vspace: '', - border: '', - borderStyle: '' - }; - }; - var getStyleValue = function (normalizeCss, data) { - var image = document.createElement('img'); - setAttrib(image, 'style', data.style); - if (getHspace(image) || data.hspace !== '') { - setHspace(image, data.hspace); - } - if (getVspace(image) || data.vspace !== '') { - setVspace(image, data.vspace); - } - if (getBorder(image) || data.border !== '') { - setBorder(image, data.border); - } - if (getBorderStyle(image) || data.borderStyle !== '') { - setBorderStyle(image, data.borderStyle); - } - return normalizeCss(image.getAttribute('style')); - }; - var create = function (normalizeCss, data) { - var image = document.createElement('img'); - write(normalizeCss, $_sdccncqjgqkwzob.merge(data, { caption: false }), image); - setAttrib(image, 'alt', data.alt); - if (data.caption) { - var figure = DOM.create('figure', { class: 'image' }); - figure.appendChild(image); - figure.appendChild(DOM.create('figcaption', { contentEditable: true }, 'Caption')); - figure.contentEditable = 'false'; - return figure; - } else { - return image; - } - }; - var read = function (normalizeCss, image) { - return { - src: getAttrib(image, 'src'), - alt: getAttrib(image, 'alt'), - title: getAttrib(image, 'title'), - width: getSize(image, 'width'), - height: getSize(image, 'height'), - class: getAttrib(image, 'class'), - style: normalizeCss(getAttrib(image, 'style')), - caption: hasCaption(image), - hspace: getHspace(image), - vspace: getVspace(image), - border: getBorder(image), - borderStyle: getStyle(image, 'borderStyle') - }; - }; - var updateProp = function (image, oldData, newData, name, set) { - if (newData[name] !== oldData[name]) { - set(image, name, newData[name]); - } - }; - var normalized = function (set, normalizeCss) { - return function (image, name, value) { - set(image, value); - normalizeStyle(image, normalizeCss); - }; - }; - var write = function (normalizeCss, newData, image) { - var oldData = read(normalizeCss, image); - updateProp(image, oldData, newData, 'caption', function (image, _name, _value) { - return toggleCaption(image); - }); - updateProp(image, oldData, newData, 'src', setAttrib); - updateProp(image, oldData, newData, 'alt', setAttrib); - updateProp(image, oldData, newData, 'title', setAttrib); - updateProp(image, oldData, newData, 'width', setSize('width', normalizeCss)); - updateProp(image, oldData, newData, 'height', setSize('height', normalizeCss)); - updateProp(image, oldData, newData, 'class', setAttrib); - updateProp(image, oldData, newData, 'style', normalized(function (image, value) { - return setAttrib(image, 'style', value); - }, normalizeCss)); - updateProp(image, oldData, newData, 'hspace', normalized(setHspace, normalizeCss)); - updateProp(image, oldData, newData, 'vspace', normalized(setVspace, normalizeCss)); - updateProp(image, oldData, newData, 'border', normalized(setBorder, normalizeCss)); - updateProp(image, oldData, newData, 'borderStyle', normalized(setBorderStyle, normalizeCss)); - }; - - var normalizeCss = function (editor, cssText) { - var css = editor.dom.styles.parse(cssText); - var mergedCss = $_3p4hsscejgqkwzna.mergeMargins(css); - var compressed = editor.dom.styles.parse(editor.dom.styles.serialize(mergedCss)); - return editor.dom.styles.serialize(compressed); - }; - var getSelectedImage = function (editor) { - var imgElm = editor.selection.getNode(); - var figureElm = editor.dom.getParent(imgElm, 'figure.image'); - if (figureElm) { - return editor.dom.select('img', figureElm)[0]; - } - if (imgElm && (imgElm.nodeName !== 'IMG' || imgElm.getAttribute('data-mce-object') || imgElm.getAttribute('data-mce-placeholder'))) { - return null; - } - return imgElm; - }; - var splitTextBlock = function (editor, figure) { - var dom = editor.dom; - var textBlock = dom.getParent(figure.parentNode, function (node) { - return editor.schema.getTextBlockElements()[node.nodeName]; - }); - if (textBlock) { - return dom.split(textBlock, figure); - } else { - return figure; - } - }; - var readImageDataFromSelection = function (editor) { - var image = getSelectedImage(editor); - return image ? read(function (css) { - return normalizeCss(editor, css); - }, image) : defaultData(); - }; - var insertImageAtCaret = function (editor, data) { - var elm = create(function (css) { - return normalizeCss(editor, css); - }, data); - editor.dom.setAttrib(elm, 'data-mce-id', '__mcenew'); - editor.focus(); - editor.selection.setContent(elm.outerHTML); - var insertedElm = editor.dom.select('*[data-mce-id="__mcenew"]')[0]; - editor.dom.setAttrib(insertedElm, 'data-mce-id', null); - if (isFigure(insertedElm)) { - var figure = splitTextBlock(editor, insertedElm); - editor.selection.select(figure); - } else { - editor.selection.select(insertedElm); - } - }; - var syncSrcAttr = function (editor, image) { - editor.dom.setAttrib(image, 'src', image.getAttribute('src')); - }; - var deleteImage = function (editor, image) { - if (image) { - var elm = editor.dom.is(image.parentNode, 'figure.image') ? image.parentNode : image; - editor.dom.remove(elm); - editor.focus(); - editor.nodeChanged(); - if (editor.dom.isEmpty(editor.getBody())) { - editor.setContent(''); - editor.selection.setCursorLocation(); - } - } - }; - var writeImageDataToSelection = function (editor, data) { - var image = getSelectedImage(editor); - write(function (css) { - return normalizeCss(editor, css); - }, data, image); - syncSrcAttr(editor, image); - if (isFigure(image.parentNode)) { - var figure = image.parentNode; - splitTextBlock(editor, figure); - editor.selection.select(image.parentNode); - } else { - editor.selection.select(image); - $_3p4hsscejgqkwzna.waitLoadImage(editor, data, image); - } - }; - var insertOrUpdateImage = function (editor, data) { - var image = getSelectedImage(editor); - if (image) { - if (data.src) { - writeImageDataToSelection(editor, data); - } else { - deleteImage(editor, image); - } - } else if (data.src) { - insertImageAtCaret(editor, data); - } - }; - - var updateVSpaceHSpaceBorder = function (editor) { - return function (evt) { - var dom = editor.dom; - var rootControl = evt.control.rootControl; - if (!$_76jaztcdjgqkwzmx.hasAdvTab(editor)) { - return; - } - var data = rootControl.toJSON(); - var css = dom.parseStyle(data.style); - rootControl.find('#vspace').value(''); - rootControl.find('#hspace').value(''); - css = $_3p4hsscejgqkwzna.mergeMargins(css); - if (css['margin-top'] && css['margin-bottom'] || css['margin-right'] && css['margin-left']) { - if (css['margin-top'] === css['margin-bottom']) { - rootControl.find('#vspace').value($_3p4hsscejgqkwzna.removePixelSuffix(css['margin-top'])); - } else { - rootControl.find('#vspace').value(''); - } - if (css['margin-right'] === css['margin-left']) { - rootControl.find('#hspace').value($_3p4hsscejgqkwzna.removePixelSuffix(css['margin-right'])); - } else { - rootControl.find('#hspace').value(''); - } - } - if (css['border-width']) { - rootControl.find('#border').value($_3p4hsscejgqkwzna.removePixelSuffix(css['border-width'])); - } else { - rootControl.find('#border').value(''); - } - if (css['border-style']) { - rootControl.find('#borderStyle').value(css['border-style']); - } else { - rootControl.find('#borderStyle').value(''); - } - rootControl.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css)))); - }; - }; - var updateStyle = function (editor, win) { - win.find('#style').each(function (ctrl) { - var value = getStyleValue(function (css) { - return normalizeCss(editor, css); - }, $_sdccncqjgqkwzob.merge(defaultData(), win.toJSON())); - ctrl.value(value); - }); - }; - var makeTab = function (editor) { - return { - title: 'Advanced', - type: 'form', - pack: 'start', - items: [ - { - label: 'Style', - name: 'style', - type: 'textbox', - onchange: updateVSpaceHSpaceBorder(editor) - }, - { - type: 'form', - layout: 'grid', - packV: 'start', - columns: 2, - padding: 0, - defaults: { - type: 'textbox', - maxWidth: 50, - onchange: function (evt) { - updateStyle(editor, evt.control.rootControl); - } - }, - items: [ - { - label: 'Vertical space', - name: 'vspace' - }, - { - label: 'Border width', - name: 'border' - }, - { - label: 'Horizontal space', - name: 'hspace' - }, - { - label: 'Border style', - type: 'listbox', - name: 'borderStyle', - width: 90, - maxWidth: 90, - onselect: function (evt) { - updateStyle(editor, evt.control.rootControl); - }, - values: [ - { - text: 'Select...', - value: '' - }, - { - text: 'Solid', - value: 'solid' - }, - { - text: 'Dotted', - value: 'dotted' - }, - { - text: 'Dashed', - value: 'dashed' - }, - { - text: 'Double', - value: 'double' - }, - { - text: 'Groove', - value: 'groove' - }, - { - text: 'Ridge', - value: 'ridge' - }, - { - text: 'Inset', - value: 'inset' - }, - { - text: 'Outset', - value: 'outset' - }, - { - text: 'None', - value: 'none' - }, - { - text: 'Hidden', - value: 'hidden' - } - ] - } - ] - } - ] - }; - }; - var $_d3lacecmjgqkwznt = { makeTab: makeTab }; - - var doSyncSize = function (widthCtrl, heightCtrl) { - widthCtrl.state.set('oldVal', widthCtrl.value()); - heightCtrl.state.set('oldVal', heightCtrl.value()); - }; - var doSizeControls = function (win, f) { - var widthCtrl = win.find('#width')[0]; - var heightCtrl = win.find('#height')[0]; - var constrained = win.find('#constrain')[0]; - if (widthCtrl && heightCtrl && constrained) { - f(widthCtrl, heightCtrl, constrained.checked()); - } - }; - var doUpdateSize = function (widthCtrl, heightCtrl, isContrained) { - var oldWidth = widthCtrl.state.get('oldVal'); - var oldHeight = heightCtrl.state.get('oldVal'); - var newWidth = widthCtrl.value(); - var newHeight = heightCtrl.value(); - if (isContrained && oldWidth && oldHeight && newWidth && newHeight) { - if (newWidth !== oldWidth) { - newHeight = Math.round(newWidth / oldWidth * newHeight); - if (!isNaN(newHeight)) { - heightCtrl.value(newHeight); - } - } else { - newWidth = Math.round(newHeight / oldHeight * newWidth); - if (!isNaN(newWidth)) { - widthCtrl.value(newWidth); - } - } - } - doSyncSize(widthCtrl, heightCtrl); - }; - var syncSize = function (win) { - doSizeControls(win, doSyncSize); - }; - var updateSize = function (win) { - doSizeControls(win, doUpdateSize); - }; - var createUi = function () { - var recalcSize = function (evt) { - updateSize(evt.control.rootControl); - }; - return { - type: 'container', - label: 'Dimensions', - layout: 'flex', - align: 'center', - spacing: 5, - items: [ - { - name: 'width', - type: 'textbox', - maxLength: 5, - size: 5, - onchange: recalcSize, - ariaLabel: 'Width' - }, - { - type: 'label', - text: 'x' - }, - { - name: 'height', - type: 'textbox', - maxLength: 5, - size: 5, - onchange: recalcSize, - ariaLabel: 'Height' - }, - { - name: 'constrain', - type: 'checkbox', - checked: true, - text: 'Constrain proportions' - } - ] - }; - }; - var $_3u35dhctjgqkwzoi = { - createUi: createUi, - syncSize: syncSize, - updateSize: updateSize - }; - - var onSrcChange = function (evt, editor) { - var srcURL, prependURL, absoluteURLPattern; - var meta = evt.meta || {}; - var control = evt.control; - var rootControl = control.rootControl; - var imageListCtrl = rootControl.find('#image-list')[0]; - if (imageListCtrl) { - imageListCtrl.value(editor.convertURL(control.value(), 'src')); - } - global$3.each(meta, function (value, key) { - rootControl.find('#' + key).value(value); - }); - if (!meta.width && !meta.height) { - srcURL = editor.convertURL(control.value(), 'src'); - prependURL = $_76jaztcdjgqkwzmx.getPrependUrl(editor); - absoluteURLPattern = new RegExp('^(?:[a-z]+:)?//', 'i'); - if (prependURL && !absoluteURLPattern.test(srcURL) && srcURL.substring(0, prependURL.length) !== prependURL) { - srcURL = prependURL + srcURL; - } - control.value(srcURL); - $_3p4hsscejgqkwzna.getImageSize(editor.documentBaseURI.toAbsolute(control.value()), function (data) { - if (data.width && data.height && $_76jaztcdjgqkwzmx.hasDimensions(editor)) { - rootControl.find('#width').value(data.width); - rootControl.find('#height').value(data.height); - $_3u35dhctjgqkwzoi.syncSize(rootControl); - } - }); - } - }; - var onBeforeCall = function (evt) { - evt.meta = evt.control.rootControl.toJSON(); - }; - var getGeneralItems = function (editor, imageListCtrl) { - var generalFormItems = [ - { - name: 'src', - type: 'filepicker', - filetype: 'image', - label: 'Source', - autofocus: true, - onchange: function (evt) { - onSrcChange(evt, editor); - }, - onbeforecall: onBeforeCall - }, - imageListCtrl - ]; - if ($_76jaztcdjgqkwzmx.hasDescription(editor)) { - generalFormItems.push({ - name: 'alt', - type: 'textbox', - label: 'Image description' - }); - } - if ($_76jaztcdjgqkwzmx.hasImageTitle(editor)) { - generalFormItems.push({ - name: 'title', - type: 'textbox', - label: 'Image Title' - }); - } - if ($_76jaztcdjgqkwzmx.hasDimensions(editor)) { - generalFormItems.push($_3u35dhctjgqkwzoi.createUi()); - } - if ($_76jaztcdjgqkwzmx.getClassList(editor)) { - generalFormItems.push({ - name: 'class', - type: 'listbox', - label: 'Class', - values: $_3p4hsscejgqkwzna.buildListItems($_76jaztcdjgqkwzmx.getClassList(editor), function (item) { - if (item.value) { - item.textStyle = function () { - return editor.formatter.getCssText({ - inline: 'img', - classes: [item.value] - }); - }; - } - }) - }); - } - if ($_76jaztcdjgqkwzmx.hasImageCaption(editor)) { - generalFormItems.push({ - name: 'caption', - type: 'checkbox', - label: 'Caption' - }); - } - return generalFormItems; - }; - var makeTab$1 = function (editor, imageListCtrl) { - return { - title: 'General', - type: 'form', - items: getGeneralItems(editor, imageListCtrl) - }; - }; - var $_4wnse9csjgqkwzof = { - makeTab: makeTab$1, - getGeneralItems: getGeneralItems - }; - - var url = function () { - return $_g2wawpcgjgqkwznj.getOrDie('URL'); - }; - var createObjectURL = function (blob) { - return url().createObjectURL(blob); - }; - var revokeObjectURL = function (u) { - url().revokeObjectURL(u); - }; - var $_7vzxnncvjgqkwzop = { - createObjectURL: createObjectURL, - revokeObjectURL: revokeObjectURL - }; - - var global$6 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); - - function XMLHttpRequest () { - var f = $_g2wawpcgjgqkwznj.getOrDie('XMLHttpRequest'); - return new f(); - } - - var noop = function () { - }; - var pathJoin = function (path1, path2) { - if (path1) { - return path1.replace(/\/$/, '') + '/' + path2.replace(/^\//, ''); - } - return path2; - }; - function Uploader (settings) { - var defaultHandler = function (blobInfo, success, failure, progress) { - var xhr, formData; - xhr = new XMLHttpRequest(); - xhr.open('POST', settings.url); - xhr.withCredentials = settings.credentials; - xhr.upload.onprogress = function (e) { - progress(e.loaded / e.total * 100); - }; - xhr.onerror = function () { - failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status); - }; - xhr.onload = function () { - var json; - if (xhr.status < 200 || xhr.status >= 300) { - failure('HTTP Error: ' + xhr.status); - return; - } - json = JSON.parse(xhr.responseText); - if (!json || typeof json.location !== 'string') { - failure('Invalid JSON: ' + xhr.responseText); - return; - } - success(pathJoin(settings.basePath, json.location)); - }; - formData = new FormData(); - formData.append('file', blobInfo.blob(), blobInfo.filename()); - xhr.send(formData); - }; - var uploadBlob = function (blobInfo, handler) { - return new global$2(function (resolve, reject) { - try { - handler(blobInfo, resolve, reject, noop); - } catch (ex) { - reject(ex.message); - } - }); - }; - var isDefaultHandler = function (handler) { - return handler === defaultHandler; - }; - var upload = function (blobInfo) { - return !settings.url && isDefaultHandler(settings.handler) ? global$2.reject('Upload url missing from the settings.') : uploadBlob(blobInfo, settings.handler); - }; - settings = global$3.extend({ - credentials: false, - handler: defaultHandler - }, settings); - return { upload: upload }; - } - - var onFileInput = function (editor) { - return function (evt) { - var Throbber = global$6.get('Throbber'); - var rootControl = evt.control.rootControl; - var throbber = new Throbber(rootControl.getEl()); - var file = evt.control.value(); - var blobUri = $_7vzxnncvjgqkwzop.createObjectURL(file); - var uploader = Uploader({ - url: $_76jaztcdjgqkwzmx.getUploadUrl(editor), - basePath: $_76jaztcdjgqkwzmx.getUploadBasePath(editor), - credentials: $_76jaztcdjgqkwzmx.getUploadCredentials(editor), - handler: $_76jaztcdjgqkwzmx.getUploadHandler(editor) - }); - var finalize = function () { - throbber.hide(); - $_7vzxnncvjgqkwzop.revokeObjectURL(blobUri); - }; - throbber.show(); - return $_3p4hsscejgqkwzna.blobToDataUri(file).then(function (dataUrl) { - var blobInfo = editor.editorUpload.blobCache.create({ - blob: file, - blobUri: blobUri, - name: file.name ? file.name.replace(/\.[^\.]+$/, '') : null, - base64: dataUrl.split(',')[1] - }); - return uploader.upload(blobInfo).then(function (url) { - var src = rootControl.find('#src'); - src.value(url); - rootControl.find('tabpanel')[0].activateTab(0); - src.fire('change'); - finalize(); - return url; - }); - }).catch(function (err) { - editor.windowManager.alert(err); - finalize(); - }); - }; - }; - var acceptExts = '.jpg,.jpeg,.png,.gif'; - var makeTab$2 = function (editor) { - return { - title: 'Upload', - type: 'form', - layout: 'flex', - direction: 'column', - align: 'stretch', - padding: '20 20 20 20', - items: [ - { - type: 'container', - layout: 'flex', - direction: 'column', - align: 'center', - spacing: 10, - items: [ - { - text: 'Browse for an image', - type: 'browsebutton', - accept: acceptExts, - onchange: onFileInput(editor) - }, - { - text: 'OR', - type: 'label' - } - ] - }, - { - text: 'Drop an image here', - type: 'dropzone', - accept: acceptExts, - height: 100, - onchange: onFileInput(editor) - } - ] - }; - }; - var $_1bnc59cujgqkwzok = { makeTab: makeTab$2 }; - - var noop$1 = function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - }; - var noarg = function (f) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return f(); - }; - }; - var compose = function (fa, fb) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return fa(fb.apply(null, arguments)); - }; - }; - var constant = function (value) { - return function () { - return value; - }; - }; - var identity = function (x) { - return x; - }; - var tripleEquals = function (a, b) { - return a === b; - }; - var curry = function (f) { - var x = []; - for (var _i = 1; _i < arguments.length; _i++) { - x[_i - 1] = arguments[_i]; - } - var args = new Array(arguments.length - 1); - for (var i = 1; i < arguments.length; i++) - args[i - 1] = arguments[i]; - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - var newArgs = new Array(arguments.length); - for (var j = 0; j < newArgs.length; j++) - newArgs[j] = arguments[j]; - var all = args.concat(newArgs); - return f.apply(null, all); - }; - }; - var not = function (f) { - return function () { - var x = []; - for (var _i = 0; _i < arguments.length; _i++) { - x[_i] = arguments[_i]; - } - return !f.apply(null, arguments); - }; - }; - var die = function (msg) { - return function () { - throw new Error(msg); - }; - }; - var apply = function (f) { - return f(); - }; - var call = function (f) { - f(); - }; - var never = constant(false); - var always = constant(true); - var $_f78tmwczjgqkwzox = { - noop: noop$1, - noarg: noarg, - compose: compose, - constant: constant, - identity: identity, - tripleEquals: tripleEquals, - curry: curry, - not: not, - die: die, - apply: apply, - call: call, - never: never, - always: always - }; - - var submitForm = function (editor, evt) { - var win = evt.control.getRoot(); - $_3u35dhctjgqkwzoi.updateSize(win); - editor.undoManager.transact(function () { - var data = $_sdccncqjgqkwzob.merge(readImageDataFromSelection(editor), win.toJSON()); - insertOrUpdateImage(editor, data); - }); - editor.editorUpload.uploadImagesAuto(); - }; - function Dialog (editor) { - function showDialog(imageList) { - var data = readImageDataFromSelection(editor); - var win, imageListCtrl; - if (imageList) { - imageListCtrl = { - type: 'listbox', - label: 'Image list', - name: 'image-list', - values: $_3p4hsscejgqkwzna.buildListItems(imageList, function (item) { - item.value = editor.convertURL(item.value || item.url, 'src'); - }, [{ - text: 'None', - value: '' - }]), - value: data.src && editor.convertURL(data.src, 'src'), - onselect: function (e) { - var altCtrl = win.find('#alt'); - if (!altCtrl.value() || e.lastControl && altCtrl.value() === e.lastControl.text()) { - altCtrl.value(e.control.text()); - } - win.find('#src').value(e.control.value()).fire('change'); - }, - onPostRender: function () { - imageListCtrl = this; - } - }; - } - if ($_76jaztcdjgqkwzmx.hasAdvTab(editor) || $_76jaztcdjgqkwzmx.hasUploadUrl(editor) || $_76jaztcdjgqkwzmx.hasUploadHandler(editor)) { - var body = [$_4wnse9csjgqkwzof.makeTab(editor, imageListCtrl)]; - if ($_76jaztcdjgqkwzmx.hasAdvTab(editor)) { - body.push($_d3lacecmjgqkwznt.makeTab(editor)); - } - if ($_76jaztcdjgqkwzmx.hasUploadUrl(editor) || $_76jaztcdjgqkwzmx.hasUploadHandler(editor)) { - body.push($_1bnc59cujgqkwzok.makeTab(editor)); - } - win = editor.windowManager.open({ - title: 'Insert/edit image', - data: data, - bodyType: 'tabpanel', - body: body, - onSubmit: $_f78tmwczjgqkwzox.curry(submitForm, editor) - }); - } else { - win = editor.windowManager.open({ - title: 'Insert/edit image', - data: data, - body: $_4wnse9csjgqkwzof.getGeneralItems(editor, imageListCtrl), - onSubmit: $_f78tmwczjgqkwzox.curry(submitForm, editor) - }); - } - $_3u35dhctjgqkwzoi.syncSize(win); - } - function open() { - $_3p4hsscejgqkwzna.createImageList(editor, showDialog); - } - return { open: open }; - } - - var register = function (editor) { - editor.addCommand('mceImage', Dialog(editor).open); - }; - var $_37k57zcbjgqkwzhm = { register: register }; - - var hasImageClass = function (node) { - var className = node.attr('class'); - return className && /\bimage\b/.test(className); - }; - var toggleContentEditableState = function (state) { - return function (nodes) { - var i = nodes.length, node; - var toggleContentEditable = function (node) { - node.attr('contenteditable', state ? 'true' : null); - }; - while (i--) { - node = nodes[i]; - if (hasImageClass(node)) { - node.attr('contenteditable', state ? 'false' : null); - global$3.each(node.getAll('figcaption'), toggleContentEditable); - } - } - }; - }; - var setup = function (editor) { - editor.on('preInit', function () { - editor.parser.addNodeFilter('figure', toggleContentEditableState(true)); - editor.serializer.addNodeFilter('figure', toggleContentEditableState(false)); - }); - }; - var $_4sbgi9d0jgqkwzp0 = { setup: setup }; - - var register$1 = function (editor) { - editor.addButton('image', { - icon: 'image', - tooltip: 'Insert/edit image', - onclick: Dialog(editor).open, - stateSelector: 'img:not([data-mce-object],[data-mce-placeholder]),figure.image' - }); - editor.addMenuItem('image', { - icon: 'image', - text: 'Image', - onclick: Dialog(editor).open, - context: 'insert', - prependToContext: true - }); - }; - var $_35d3byd1jgqkwzp2 = { register: register$1 }; - - global.add('image', function (editor) { - $_4sbgi9d0jgqkwzp0.setup(editor); - $_35d3byd1jgqkwzp2.register(editor); - $_37k57zcbjgqkwzhm.register(editor); - }); - function Plugin () { - } - - return Plugin; - -}()); -})(); diff --git a/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.min.js b/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.min.js deleted file mode 100755 index 2613fb56..00000000 --- a/iiif-5-day-workshop/day-three/mirador/plugins/image/plugin.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),d={hasDimensions:function(e){return!1!==e.settings.image_dimensions},hasAdvTab:function(e){return!0===e.settings.image_advtab},getPrependUrl:function(e){return e.getParam("image_prepend_url","")},getClassList:function(e){return e.getParam("image_class_list")},hasDescription:function(e){return!1!==e.settings.image_description},hasImageTitle:function(e){return!0===e.settings.image_title},hasImageCaption:function(e){return!0===e.settings.image_caption},getImageList:function(e){return e.getParam("image_list",!1)},hasUploadUrl:function(e){return e.getParam("images_upload_url",!1)},hasUploadHandler:function(e){return e.getParam("images_upload_handler",!1)},getUploadUrl:function(e){return e.getParam("images_upload_url")},getUploadHandler:function(e){return e.getParam("images_upload_handler")},getUploadBasePath:function(e){return e.getParam("images_upload_base_path")},getUploadCredentials:function(e){return e.getParam("images_upload_credentials")}},a="undefined"!=typeof window?window:Function("return this;")(),r=function(e,t){for(var n=t!==undefined&&null!==t?t:a,r=0;r max) { - value = max; - } else if (value < min) { - value = min; - } - return value; - } - function identity$1() { - return [ - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]; - } - var DELTA_INDEX = [ - 0, - 0.01, - 0.02, - 0.04, - 0.05, - 0.06, - 0.07, - 0.08, - 0.1, - 0.11, - 0.12, - 0.14, - 0.15, - 0.16, - 0.17, - 0.18, - 0.2, - 0.21, - 0.22, - 0.24, - 0.25, - 0.27, - 0.28, - 0.3, - 0.32, - 0.34, - 0.36, - 0.38, - 0.4, - 0.42, - 0.44, - 0.46, - 0.48, - 0.5, - 0.53, - 0.56, - 0.59, - 0.62, - 0.65, - 0.68, - 0.71, - 0.74, - 0.77, - 0.8, - 0.83, - 0.86, - 0.89, - 0.92, - 0.95, - 0.98, - 1, - 1.06, - 1.12, - 1.18, - 1.24, - 1.3, - 1.36, - 1.42, - 1.48, - 1.54, - 1.6, - 1.66, - 1.72, - 1.78, - 1.84, - 1.9, - 1.96, - 2, - 2.12, - 2.25, - 2.37, - 2.5, - 2.62, - 2.75, - 2.87, - 3, - 3.2, - 3.4, - 3.6, - 3.8, - 4, - 4.3, - 4.7, - 4.9, - 5, - 5.5, - 6, - 6.5, - 6.8, - 7, - 7.3, - 7.5, - 7.8, - 8, - 8.4, - 8.7, - 9, - 9.4, - 9.6, - 9.8, - 10 - ]; - function multiply(matrix1, matrix2) { - var i, j, k, val, col = [], out = new Array(10); - for (i = 0; i < 5; i++) { - for (j = 0; j < 5; j++) { - col[j] = matrix2[j + i * 5]; - } - for (j = 0; j < 5; j++) { - val = 0; - for (k = 0; k < 5; k++) { - val += matrix1[j + k * 5] * col[k]; - } - out[j + i * 5] = val; - } - } - return out; - } - function adjust(matrix, adjustValue) { - adjustValue = clamp(adjustValue, 0, 1); - return matrix.map(function (value, index) { - if (index % 6 === 0) { - value = 1 - (1 - value) * adjustValue; - } else { - value *= adjustValue; - } - return clamp(value, 0, 1); - }); - } - function adjustContrast(matrix, value) { - var x; - value = clamp(value, -1, 1); - value *= 100; - if (value < 0) { - x = 127 + value / 100 * 127; - } else { - x = value % 1; - if (x === 0) { - x = DELTA_INDEX[value]; - } else { - x = DELTA_INDEX[Math.floor(value)] * (1 - x) + DELTA_INDEX[Math.floor(value) + 1] * x; - } - x = x * 127 + 127; - } - return multiply(matrix, [ - x / 127, - 0, - 0, - 0, - 0.5 * (127 - x), - 0, - x / 127, - 0, - 0, - 0.5 * (127 - x), - 0, - 0, - x / 127, - 0, - 0.5 * (127 - x), - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]); - } - function adjustSaturation(matrix, value) { - var x, lumR, lumG, lumB; - value = clamp(value, -1, 1); - x = 1 + (value > 0 ? 3 * value : value); - lumR = 0.3086; - lumG = 0.6094; - lumB = 0.082; - return multiply(matrix, [ - lumR * (1 - x) + x, - lumG * (1 - x), - lumB * (1 - x), - 0, - 0, - lumR * (1 - x), - lumG * (1 - x) + x, - lumB * (1 - x), - 0, - 0, - lumR * (1 - x), - lumG * (1 - x), - lumB * (1 - x) + x, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]); - } - function adjustHue(matrix, angle) { - var cosVal, sinVal, lumR, lumG, lumB; - angle = clamp(angle, -180, 180) / 180 * Math.PI; - cosVal = Math.cos(angle); - sinVal = Math.sin(angle); - lumR = 0.213; - lumG = 0.715; - lumB = 0.072; - return multiply(matrix, [ - lumR + cosVal * (1 - lumR) + sinVal * -lumR, - lumG + cosVal * -lumG + sinVal * -lumG, - lumB + cosVal * -lumB + sinVal * (1 - lumB), - 0, - 0, - lumR + cosVal * -lumR + sinVal * 0.143, - lumG + cosVal * (1 - lumG) + sinVal * 0.14, - lumB + cosVal * -lumB + sinVal * -0.283, - 0, - 0, - lumR + cosVal * -lumR + sinVal * -(1 - lumR), - lumG + cosVal * -lumG + sinVal * lumG, - lumB + cosVal * (1 - lumB) + sinVal * lumB, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]); - } - function adjustBrightness(matrix, value) { - value = clamp(255 * value, -255, 255); - return multiply(matrix, [ - 1, - 0, - 0, - 0, - value, - 0, - 1, - 0, - 0, - value, - 0, - 0, - 1, - 0, - value, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]); - } - function adjustColors(matrix, adjustR, adjustG, adjustB) { - adjustR = clamp(adjustR, 0, 2); - adjustG = clamp(adjustG, 0, 2); - adjustB = clamp(adjustB, 0, 2); - return multiply(matrix, [ - adjustR, - 0, - 0, - 0, - 0, - 0, - adjustG, - 0, - 0, - 0, - 0, - 0, - adjustB, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ]); - } - function adjustSepia(matrix, value) { - value = clamp(value, 0, 1); - return multiply(matrix, adjust([ - 0.393, - 0.769, - 0.189, - 0, - 0, - 0.349, - 0.686, - 0.168, - 0, - 0, - 0.272, - 0.534, - 0.131, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ], value)); - } - function adjustGrayscale(matrix, value) { - value = clamp(value, 0, 1); - return multiply(matrix, adjust([ - 0.33, - 0.34, - 0.33, - 0, - 0, - 0.33, - 0.34, - 0.33, - 0, - 0, - 0.33, - 0.34, - 0.33, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 0, - 0, - 0, - 0, - 1 - ], value)); - } - var $_cbx1vcdpjgqkwzuj = { - identity: identity$1, - adjust: adjust, - multiply: multiply, - adjustContrast: adjustContrast, - adjustBrightness: adjustBrightness, - adjustSaturation: adjustSaturation, - adjustHue: adjustHue, - adjustColors: adjustColors, - adjustSepia: adjustSepia, - adjustGrayscale: adjustGrayscale - }; - - function colorFilter(ir, matrix) { - return ir.toCanvas().then(function (canvas) { - return applyColorFilter(canvas, ir.getType(), matrix); - }); - } - function applyColorFilter(canvas, type, matrix) { - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - var pixels; - function applyMatrix(pixels, m) { - var d = pixels.data, r, g, b, a, i, m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3], m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7], m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11], m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15], m16 = m[16], m17 = m[17], m18 = m[18], m19 = m[19]; - for (i = 0; i < d.length; i += 4) { - r = d[i]; - g = d[i + 1]; - b = d[i + 2]; - a = d[i + 3]; - d[i] = r * m0 + g * m1 + b * m2 + a * m3 + m4; - d[i + 1] = r * m5 + g * m6 + b * m7 + a * m8 + m9; - d[i + 2] = r * m10 + g * m11 + b * m12 + a * m13 + m14; - d[i + 3] = r * m15 + g * m16 + b * m17 + a * m18 + m19; - } - return pixels; - } - pixels = applyMatrix(context.getImageData(0, 0, canvas.width, canvas.height), matrix); - context.putImageData(pixels, 0, 0); - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - } - function convoluteFilter(ir, matrix) { - return ir.toCanvas().then(function (canvas) { - return applyConvoluteFilter(canvas, ir.getType(), matrix); - }); - } - function applyConvoluteFilter(canvas, type, matrix) { - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - var pixelsIn, pixelsOut; - function applyMatrix(pixelsIn, pixelsOut, matrix) { - var rgba, drgba, side, halfSide, x, y, r, g, b, cx, cy, scx, scy, offset, wt, w, h; - function clamp(value, min, max) { - if (value > max) { - value = max; - } else if (value < min) { - value = min; - } - return value; - } - side = Math.round(Math.sqrt(matrix.length)); - halfSide = Math.floor(side / 2); - rgba = pixelsIn.data; - drgba = pixelsOut.data; - w = pixelsIn.width; - h = pixelsIn.height; - for (y = 0; y < h; y++) { - for (x = 0; x < w; x++) { - r = g = b = 0; - for (cy = 0; cy < side; cy++) { - for (cx = 0; cx < side; cx++) { - scx = clamp(x + cx - halfSide, 0, w - 1); - scy = clamp(y + cy - halfSide, 0, h - 1); - offset = (scy * w + scx) * 4; - wt = matrix[cy * side + cx]; - r += rgba[offset] * wt; - g += rgba[offset + 1] * wt; - b += rgba[offset + 2] * wt; - } - } - offset = (y * w + x) * 4; - drgba[offset] = clamp(r, 0, 255); - drgba[offset + 1] = clamp(g, 0, 255); - drgba[offset + 2] = clamp(b, 0, 255); - } - } - return pixelsOut; - } - pixelsIn = context.getImageData(0, 0, canvas.width, canvas.height); - pixelsOut = context.getImageData(0, 0, canvas.width, canvas.height); - pixelsOut = applyMatrix(pixelsIn, pixelsOut, matrix); - context.putImageData(pixelsOut, 0, 0); - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - } - function functionColorFilter(colorFn) { - var filterImpl = function (canvas, type, value) { - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - var pixels, i, lookup = new Array(256); - function applyLookup(pixels, lookup) { - var d = pixels.data, i; - for (i = 0; i < d.length; i += 4) { - d[i] = lookup[d[i]]; - d[i + 1] = lookup[d[i + 1]]; - d[i + 2] = lookup[d[i + 2]]; - } - return pixels; - } - for (i = 0; i < lookup.length; i++) { - lookup[i] = colorFn(i, value); - } - pixels = applyLookup(context.getImageData(0, 0, canvas.width, canvas.height), lookup); - context.putImageData(pixels, 0, 0); - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - }; - return function (ir, value) { - return ir.toCanvas().then(function (canvas) { - return filterImpl(canvas, ir.getType(), value); - }); - }; - } - function complexAdjustableColorFilter(matrixAdjustFn) { - return function (ir, adjust) { - return colorFilter(ir, matrixAdjustFn($_cbx1vcdpjgqkwzuj.identity(), adjust)); - }; - } - function basicColorFilter(matrix) { - return function (ir) { - return colorFilter(ir, matrix); - }; - } - function basicConvolutionFilter(kernel) { - return function (ir) { - return convoluteFilter(ir, kernel); - }; - } - var $_75nl4xdnjgqkwzu5 = { - invert: basicColorFilter([ - -1, - 0, - 0, - 0, - 255, - 0, - -1, - 0, - 0, - 255, - 0, - 0, - -1, - 0, - 255, - 0, - 0, - 0, - 1, - 0 - ]), - brightness: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustBrightness), - hue: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustHue), - saturate: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustSaturation), - contrast: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustContrast), - grayscale: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustGrayscale), - sepia: complexAdjustableColorFilter($_cbx1vcdpjgqkwzuj.adjustSepia), - colorize: function (ir, adjustR, adjustG, adjustB) { - return colorFilter(ir, $_cbx1vcdpjgqkwzuj.adjustColors($_cbx1vcdpjgqkwzuj.identity(), adjustR, adjustG, adjustB)); - }, - sharpen: basicConvolutionFilter([ - 0, - -1, - 0, - -1, - 5, - -1, - 0, - -1, - 0 - ]), - emboss: basicConvolutionFilter([ - -2, - -1, - 0, - -1, - 1, - 1, - 0, - 1, - 2 - ]), - gamma: functionColorFilter(function (color, value) { - return Math.pow(color / 255, 1 - value) * 255; - }), - exposure: functionColorFilter(function (color, value) { - return 255 * (1 - Math.exp(-(color / 255) * value)); - }), - colorFilter: colorFilter, - convoluteFilter: convoluteFilter - }; - - function scale(image, dW, dH) { - var sW = $_fj8o2qdbjgqkwztf.getWidth(image); - var sH = $_fj8o2qdbjgqkwztf.getHeight(image); - var wRatio = dW / sW; - var hRatio = dH / sH; - var scaleCapped = false; - if (wRatio < 0.5 || wRatio > 2) { - wRatio = wRatio < 0.5 ? 0.5 : 2; - scaleCapped = true; - } - if (hRatio < 0.5 || hRatio > 2) { - hRatio = hRatio < 0.5 ? 0.5 : 2; - scaleCapped = true; - } - var scaled = _scale(image, wRatio, hRatio); - return !scaleCapped ? scaled : scaled.then(function (tCanvas) { - return scale(tCanvas, dW, dH); - }); - } - function _scale(image, wRatio, hRatio) { - return new Promise(function (resolve) { - var sW = $_fj8o2qdbjgqkwztf.getWidth(image); - var sH = $_fj8o2qdbjgqkwztf.getHeight(image); - var dW = Math.floor(sW * wRatio); - var dH = Math.floor(sH * hRatio); - var canvas = $_fs2b5bdajgqkwzte.create(dW, dH); - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - context.drawImage(image, 0, 0, sW, sH, 0, 0, dW, dH); - resolve(canvas); - }); - } - var $_ro477drjgqkwzuy = { scale: scale }; - - function rotate(ir, angle) { - return ir.toCanvas().then(function (canvas) { - return applyRotate(canvas, ir.getType(), angle); - }); - } - function applyRotate(image, type, angle) { - var canvas = $_fs2b5bdajgqkwzte.create(image.width, image.height); - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - var translateX = 0, translateY = 0; - angle = angle < 0 ? 360 + angle : angle; - if (angle == 90 || angle == 270) { - $_fs2b5bdajgqkwzte.resize(canvas, canvas.height, canvas.width); - } - if (angle == 90 || angle == 180) { - translateX = canvas.width; - } - if (angle == 270 || angle == 180) { - translateY = canvas.height; - } - context.translate(translateX, translateY); - context.rotate(angle * Math.PI / 180); - context.drawImage(image, 0, 0); - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - } - function flip(ir, axis) { - return ir.toCanvas().then(function (canvas) { - return applyFlip(canvas, ir.getType(), axis); - }); - } - function applyFlip(image, type, axis) { - var canvas = $_fs2b5bdajgqkwzte.create(image.width, image.height); - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - if (axis == 'v') { - context.scale(1, -1); - context.drawImage(image, 0, -canvas.height); - } else { - context.scale(-1, 1); - context.drawImage(image, -canvas.width, 0); - } - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - } - function crop(ir, x, y, w, h) { - return ir.toCanvas().then(function (canvas) { - return applyCrop(canvas, ir.getType(), x, y, w, h); - }); - } - function applyCrop(image, type, x, y, w, h) { - var canvas = $_fs2b5bdajgqkwzte.create(w, h); - var context = $_fs2b5bdajgqkwzte.get2dContext(canvas); - context.drawImage(image, -x, -y); - return $_7b10xvdojgqkwzub.fromCanvas(canvas, type); - } - function resize$1(ir, w, h) { - return ir.toCanvas().then(function (canvas) { - return $_ro477drjgqkwzuy.scale(canvas, w, h).then(function (newCanvas) { - return $_7b10xvdojgqkwzub.fromCanvas(newCanvas, ir.getType()); - }); - }); - } - var $_55u117dqjgqkwzuv = { - rotate: rotate, - flip: flip, - crop: crop, - resize: resize$1 - }; - - var invert = function (ir) { - return $_75nl4xdnjgqkwzu5.invert(ir); - }; - var sharpen = function (ir) { - return $_75nl4xdnjgqkwzu5.sharpen(ir); - }; - var emboss = function (ir) { - return $_75nl4xdnjgqkwzu5.emboss(ir); - }; - var gamma = function (ir, value) { - return $_75nl4xdnjgqkwzu5.gamma(ir, value); - }; - var exposure = function (ir, value) { - return $_75nl4xdnjgqkwzu5.exposure(ir, value); - }; - var colorize = function (ir, adjustR, adjustG, adjustB) { - return $_75nl4xdnjgqkwzu5.colorize(ir, adjustR, adjustG, adjustB); - }; - var brightness = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.brightness(ir, adjust); - }; - var hue = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.hue(ir, adjust); - }; - var saturate = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.saturate(ir, adjust); - }; - var contrast = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.contrast(ir, adjust); - }; - var grayscale = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.grayscale(ir, adjust); - }; - var sepia = function (ir, adjust) { - return $_75nl4xdnjgqkwzu5.sepia(ir, adjust); - }; - var flip$1 = function (ir, axis) { - return $_55u117dqjgqkwzuv.flip(ir, axis); - }; - var crop$1 = function (ir, x, y, w, h) { - return $_55u117dqjgqkwzuv.crop(ir, x, y, w, h); - }; - var resize$2 = function (ir, w, h) { - return $_55u117dqjgqkwzuv.resize(ir, w, h); - }; - var rotate$1 = function (ir, angle) { - return $_55u117dqjgqkwzuv.rotate(ir, angle); - }; - var $_72jnzmdmjgqkwzu2 = { - invert: invert, - sharpen: sharpen, - emboss: emboss, - brightness: brightness, - hue: hue, - saturate: saturate, - contrast: contrast, - grayscale: grayscale, - sepia: sepia, - colorize: colorize, - gamma: gamma, - exposure: exposure, - flip: flip$1, - crop: crop$1, - resize: resize$2, - rotate: rotate$1 - }; - - var blobToImageResult = function (blob) { - return $_7b10xvdojgqkwzub.fromBlob(blob); - }; - var fromBlobAndUrlSync$1 = function (blob, uri) { - return $_7b10xvdojgqkwzub.fromBlobAndUrlSync(blob, uri); - }; - var imageToImageResult = function (image) { - return $_7b10xvdojgqkwzub.fromImage(image); - }; - var imageResultToBlob = function (ir, type, quality) { - if (type === undefined && quality === undefined) { - return imageResultToOriginalBlob(ir); - } else { - return ir.toAdjustedBlob(type, quality); - } - }; - var imageResultToOriginalBlob = function (ir) { - return ir.toBlob(); - }; - var imageResultToDataURL = function (ir) { - return ir.toDataURL(); - }; - var $_1qhurodsjgqkwzv0 = { - blobToImageResult: blobToImageResult, - fromBlobAndUrlSync: fromBlobAndUrlSync$1, - imageToImageResult: imageToImageResult, - imageResultToBlob: imageResultToBlob, - imageResultToOriginalBlob: imageResultToOriginalBlob, - imageResultToDataURL: imageResultToDataURL - }; - - var url = function () { - return $_6zd5xbdgjgqkwztt.getOrDie('URL'); - }; - var createObjectURL = function (blob) { - return url().createObjectURL(blob); - }; - var revokeObjectURL = function (u) { - url().revokeObjectURL(u); - }; - var $_2r7ypsdtjgqkwzv2 = { - createObjectURL: createObjectURL, - revokeObjectURL: revokeObjectURL - }; - - var global$3 = tinymce.util.Tools.resolve('tinymce.util.Delay'); - - var global$4 = tinymce.util.Tools.resolve('tinymce.util.Promise'); - - var global$5 = tinymce.util.Tools.resolve('tinymce.util.URI'); - - var getToolbarItems = function (editor) { - return editor.getParam('imagetools_toolbar', 'rotateleft rotateright | flipv fliph | crop editimage imageoptions'); - }; - var getProxyUrl = function (editor) { - return editor.getParam('imagetools_proxy'); - }; - var getCorsHosts = function (editor) { - return editor.getParam('imagetools_cors_hosts', [], 'string[]'); - }; - var getCredentialsHosts = function (editor) { - return editor.getParam('imagetools_credentials_hosts', [], 'string[]'); - }; - var getApiKey = function (editor) { - return editor.getParam('api_key', editor.getParam('imagetools_api_key', '', 'string'), 'string'); - }; - var getUploadTimeout = function (editor) { - return editor.getParam('images_upload_timeout', 30000, 'number'); - }; - var shouldReuseFilename = function (editor) { - return editor.getParam('images_reuse_filename', false, 'boolean'); - }; - - var global$6 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils'); - - var global$7 = tinymce.util.Tools.resolve('tinymce.ui.Factory'); - - function UndoStack () { - var data = []; - var index = -1; - function add(state) { - var removed; - removed = data.splice(++index); - data.push(state); - return { - state: state, - removed: removed - }; - } - function undo() { - if (canUndo()) { - return data[--index]; - } - } - function redo() { - if (canRedo()) { - return data[++index]; - } - } - function canUndo() { - return index > 0; - } - function canRedo() { - return index !== -1 && index < data.length - 1; - } - return { - data: data, - add: add, - undo: undo, - redo: redo, - canUndo: canUndo, - canRedo: canRedo - }; - } - - var global$8 = tinymce.util.Tools.resolve('tinymce.geom.Rect'); - - var loadImage$1 = function (image) { - return new global$4(function (resolve) { - var loaded = function () { - image.removeEventListener('load', loaded); - resolve(image); - }; - if (image.complete) { - resolve(image); - } else { - image.addEventListener('load', loaded); - } - }); - }; - var $_3kefr2e4jgqkwzvx = { loadImage: loadImage$1 }; - - var global$9 = tinymce.util.Tools.resolve('tinymce.dom.DomQuery'); - - var global$10 = tinymce.util.Tools.resolve('tinymce.util.Observable'); - - var global$11 = tinymce.util.Tools.resolve('tinymce.util.VK'); - - var count = 0; - function CropRect (currentRect, viewPortRect, clampRect, containerElm, action) { - var instance; - var handles; - var dragHelpers; - var blockers; - var prefix = 'mce-'; - var id = prefix + 'crid-' + count++; - handles = [ - { - name: 'move', - xMul: 0, - yMul: 0, - deltaX: 1, - deltaY: 1, - deltaW: 0, - deltaH: 0, - label: 'Crop Mask' - }, - { - name: 'nw', - xMul: 0, - yMul: 0, - deltaX: 1, - deltaY: 1, - deltaW: -1, - deltaH: -1, - label: 'Top Left Crop Handle' - }, - { - name: 'ne', - xMul: 1, - yMul: 0, - deltaX: 0, - deltaY: 1, - deltaW: 1, - deltaH: -1, - label: 'Top Right Crop Handle' - }, - { - name: 'sw', - xMul: 0, - yMul: 1, - deltaX: 1, - deltaY: 0, - deltaW: -1, - deltaH: 1, - label: 'Bottom Left Crop Handle' - }, - { - name: 'se', - xMul: 1, - yMul: 1, - deltaX: 0, - deltaY: 0, - deltaW: 1, - deltaH: 1, - label: 'Bottom Right Crop Handle' - } - ]; - blockers = [ - 'top', - 'right', - 'bottom', - 'left' - ]; - function getAbsoluteRect(outerRect, relativeRect) { - return { - x: relativeRect.x + outerRect.x, - y: relativeRect.y + outerRect.y, - w: relativeRect.w, - h: relativeRect.h - }; - } - function getRelativeRect(outerRect, innerRect) { - return { - x: innerRect.x - outerRect.x, - y: innerRect.y - outerRect.y, - w: innerRect.w, - h: innerRect.h - }; - } - function getInnerRect() { - return getRelativeRect(clampRect, currentRect); - } - function moveRect(handle, startRect, deltaX, deltaY) { - var x, y, w, h, rect; - x = startRect.x; - y = startRect.y; - w = startRect.w; - h = startRect.h; - x += deltaX * handle.deltaX; - y += deltaY * handle.deltaY; - w += deltaX * handle.deltaW; - h += deltaY * handle.deltaH; - if (w < 20) { - w = 20; - } - if (h < 20) { - h = 20; - } - rect = currentRect = global$8.clamp({ - x: x, - y: y, - w: w, - h: h - }, clampRect, handle.name === 'move'); - rect = getRelativeRect(clampRect, rect); - instance.fire('updateRect', { rect: rect }); - setInnerRect(rect); - } - function render() { - function createDragHelper(handle) { - var startRect; - var DragHelper = global$7.get('DragHelper'); - return new DragHelper(id, { - document: containerElm.ownerDocument, - handle: id + '-' + handle.name, - start: function () { - startRect = currentRect; - }, - drag: function (e) { - moveRect(handle, startRect, e.deltaX, e.deltaY); - } - }); - } - global$9('
      ').appendTo(containerElm); - global$1.each(blockers, function (blocker) { - global$9('#' + id, containerElm).append('