├── .circleci └── config.yml ├── .eslintrc.json ├── .gitignore ├── Gruntfile.js ├── LICENSE ├── NEWS ├── README.md ├── development.html ├── docs ├── bfe-api.md └── changelog.md ├── editor-dev.html ├── env.sh ├── fulleditor-dev.html ├── index.html ├── nodemon.json ├── package-lock.json ├── package.json ├── server-bfe.js ├── src ├── bfe.js ├── bfeapi.js ├── bfelabels.js ├── bfeliterallang.js ├── bfelogging.js ├── bfelookups.js ├── bfestore.js ├── bfeusertemplates.js ├── css │ ├── bfeliterallang.css │ ├── bfeusertemplates.css │ ├── bootstrap-extra.css │ └── typeahead.css ├── lib │ ├── aceconfig.js │ └── mini_require.js └── lookups │ ├── agents.js │ ├── lcshared.js │ ├── lcshared_suggest1.js │ ├── lcshared_suggest2.js │ └── names-preprod.js ├── static ├── css │ ├── jsonld-vis.css │ └── tooltipster.bundle.css ├── images │ └── favicon.ico ├── js │ ├── config-bibframeorg.js │ ├── config-dev.js │ ├── config-editor-dev.js │ ├── config-fulleditor-dev.js │ ├── config-test.js │ ├── config.js │ ├── jsonld-vis.js │ ├── lodash.min.js │ ├── n3-browser.min.js │ ├── rdf-ext.js │ ├── rdfstore.js │ ├── require.js │ ├── short-uuid.min.js │ ├── tooltipster.bundle.min.js │ └── typeahead.jquery.corejavascript.fork.js └── v1.json └── test.html /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:12.10.0 11 | 12 | # Specify service dependencies here if necessary 13 | # CircleCI maintains a library of pre-built images 14 | # documented at https://circleci.com/docs/2.0/circleci-images/ 15 | # - image: circleci/mongo:3.4.4 16 | 17 | working_directory: ~/repo 18 | 19 | steps: 20 | - checkout 21 | 22 | # Download and cache dependencies 23 | - restore_cache: 24 | keys: 25 | - v1-dependencies-{{ checksum "package.json" }} 26 | # fallback to using the latest cache if no exact match is found 27 | # - v1-dependencies- 28 | 29 | - run: yarn install 30 | 31 | - save_cache: 32 | paths: 33 | - node_modules 34 | key: v1-dependencies-{{ checksum "package.json" }} 35 | 36 | # run tests! 37 | - run: yarn run lint 38 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "globals": { 4 | "_" : false, 5 | "bfe": false, 6 | "bfelog": false, 7 | "bfeditor": false, 8 | "config": false, 9 | "d3": false, 10 | "N3": false, 11 | "jsonld": false, 12 | "define": false, 13 | "moment": false 14 | }, 15 | "env":{ 16 | "browser": true, 17 | "es6": true, 18 | "jquery": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | tmp 2 | examples 3 | node_modules 4 | builds/* 5 | docs/plato/* 6 | 7 | # static/js/config-*.js 8 | 9 | .csslintrc 10 | .jshintrc 11 | .eslintrc 12 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | grunt.initConfig({ 3 | pkg: grunt.file.readJSON('package.json'), 4 | concat: { 5 | options: { 6 | stripBanners: true, 7 | banner: '/* <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */', 8 | }, 9 | test: { 10 | files: { 11 | 'builds/bfe-test.js' : [ 12 | 'src/lib/mini_require.js', 13 | 'src/bfe.js','src/bfestore.js', 14 | 'src/bfelogging.js', 15 | 'src/bfeusertemplates.js', 16 | 'src/bfeliterallang.js', 17 | 18 | 'src/lookups/lcshared.js', 19 | 'src/lookups/lcshared_suggest1.js', 20 | 'src/lookups/lcshared_suggest2.js', 21 | 'src/bfelookups.js', 22 | 'src/lookups/names-preprod.js', 23 | 24 | 'src/bfelabels.js', 25 | 'src/bfeapi.js', 26 | 'src/lib/aceconfig.js' 27 | ], 28 | 29 | 'builds/bfe-test.css' : [ 30 | 'src/css/bootstrap-extra.css', 31 | 'src/css/typeahead.css', 32 | 'src/css/bfeusertemplates.css', 33 | 'src/css/bfeliterallang.css' 34 | ], 35 | } 36 | }, 37 | dist: { 38 | files: { 39 | 'builds/bfe.js' : [ 40 | 'src/lib/mini_require.js', 41 | 'src/bfe.js', 42 | 'src/bfestore.js', 43 | 'src/bfelogging.js', 44 | 'src/bfeusertemplates.js', 45 | 'src/bfeliterallang.js', 46 | 47 | 'src/lookups/lcshared.js', 48 | 'src/lookups/lcshared_suggest1.js', 49 | 'src/lookups/lcshared_suggest2.js', 50 | 'src/bfelookups.js', 51 | 'src/lookups/names-preprod.js', 52 | 53 | 'src/bfelabels.js', 54 | 'src/bfeapi.js', 55 | 'src/lib/aceconfig.js' 56 | ], 57 | 58 | 'builds/bfe.css' : [ 59 | 'src/css/bootstrap-extra.css', 60 | 'src/css/typeahead.css', 61 | 'src/css/bfeusertemplates.css', 62 | 'src/css/bfeliterallang.css' 63 | ], 64 | } 65 | }, 66 | }, 67 | uglify: { 68 | options: { 69 | stripBanners: true, 70 | banner: '/* <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */', 71 | }, 72 | dist: { 73 | files: [ 74 | {src: 'builds/bfe.js', dest: 'builds/bfe.min.js'} 75 | ] 76 | }, 77 | }, 78 | cssmin: { 79 | add_banner: { 80 | options: { 81 | banner: '/* <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */' 82 | }, 83 | }, 84 | combine: { 85 | files: { 86 | 'builds/bfe.min.css': ['builds/bfe.css'] 87 | } 88 | } 89 | } 90 | }); 91 | 92 | grunt.loadNpmTasks('grunt-contrib-uglify-es'); 93 | grunt.loadNpmTasks('grunt-contrib-cssmin'); 94 | grunt.loadNpmTasks('grunt-contrib-concat'); 95 | 96 | grunt.registerTask('default', ['concat:dist','uglify', 'cssmin']); 97 | }; 98 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | CC0 1.0 Universal 2 | 3 | Statement of Purpose 4 | 5 | The laws of most jurisdictions throughout the world automatically confer 6 | exclusive Copyright and Related Rights (defined below) upon the creator and 7 | subsequent owner(s) (each and all, an "owner") of an original work of 8 | authorship and/or a database (each, a "Work"). 9 | 10 | Certain owners wish to permanently relinquish those rights to a Work for the 11 | purpose of contributing to a commons of creative, cultural and scientific 12 | works ("Commons") that the public can reliably and without fear of later 13 | claims of infringement build upon, modify, incorporate in other works, reuse 14 | and redistribute as freely as possible in any form whatsoever and for any 15 | purposes, including without limitation commercial purposes. These owners may 16 | contribute to the Commons to promote the ideal of a free culture and the 17 | further production of creative, cultural and scientific works, or to gain 18 | reputation or greater distribution for their Work in part through the use and 19 | efforts of others. 20 | 21 | For these and/or other purposes and motivations, and without any expectation 22 | of additional consideration or compensation, the person associating CC0 with a 23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright 24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work 25 | and publicly distribute the Work under its terms, with knowledge of his or her 26 | Copyright and Related Rights in the Work and the meaning and intended legal 27 | effect of CC0 on those rights. 28 | 29 | 1. Copyright and Related Rights. A Work made available under CC0 may be 30 | protected by copyright and related or neighboring rights ("Copyright and 31 | Related Rights"). Copyright and Related Rights include, but are not limited 32 | to, the following: 33 | 34 | i. the right to reproduce, adapt, distribute, perform, display, communicate, 35 | and translate a Work; 36 | 37 | ii. moral rights retained by the original author(s) and/or performer(s); 38 | 39 | iii. publicity and privacy rights pertaining to a person's image or likeness 40 | depicted in a Work; 41 | 42 | iv. rights protecting against unfair competition in regards to a Work, 43 | subject to the limitations in paragraph 4(a), below; 44 | 45 | v. rights protecting the extraction, dissemination, use and reuse of data in 46 | a Work; 47 | 48 | vi. database rights (such as those arising under Directive 96/9/EC of the 49 | European Parliament and of the Council of 11 March 1996 on the legal 50 | protection of databases, and under any national implementation thereof, 51 | including any amended or successor version of such directive); and 52 | 53 | vii. other similar, equivalent or corresponding rights throughout the world 54 | based on applicable law or treaty, and any national implementations thereof. 55 | 56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of, 57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and 58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright 59 | and Related Rights and associated claims and causes of action, whether now 60 | known or unknown (including existing as well as future claims and causes of 61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum 62 | duration provided by applicable law or treaty (including future time 63 | extensions), (iii) in any current or future medium and for any number of 64 | copies, and (iv) for any purpose whatsoever, including without limitation 65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes 66 | the Waiver for the benefit of each member of the public at large and to the 67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver 68 | shall not be subject to revocation, rescission, cancellation, termination, or 69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work 70 | by the public as contemplated by Affirmer's express Statement of Purpose. 71 | 72 | 3. Public License Fallback. Should any part of the Waiver for any reason be 73 | judged legally invalid or ineffective under applicable law, then the Waiver 74 | shall be preserved to the maximum extent permitted taking into account 75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver 76 | is so judged Affirmer hereby grants to each affected person a royalty-free, 77 | non transferable, non sublicensable, non exclusive, irrevocable and 78 | unconditional license to exercise Affirmer's Copyright and Related Rights in 79 | the Work (i) in all territories worldwide, (ii) for the maximum duration 80 | provided by applicable law or treaty (including future time extensions), (iii) 81 | in any current or future medium and for any number of copies, and (iv) for any 82 | purpose whatsoever, including without limitation commercial, advertising or 83 | promotional purposes (the "License"). The License shall be deemed effective as 84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the 85 | License for any reason be judged legally invalid or ineffective under 86 | applicable law, such partial invalidity or ineffectiveness shall not 87 | invalidate the remainder of the License, and in such case Affirmer hereby 88 | affirms that he or she will not (i) exercise any of his or her remaining 89 | Copyright and Related Rights in the Work or (ii) assert any associated claims 90 | and causes of action with respect to the Work, in either case contrary to 91 | Affirmer's express Statement of Purpose. 92 | 93 | 4. Limitations and Disclaimers. 94 | 95 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 96 | surrendered, licensed or otherwise affected by this document. 97 | 98 | b. Affirmer offers the Work as-is and makes no representations or warranties 99 | of any kind concerning the Work, express, implied, statutory or otherwise, 100 | including without limitation warranties of title, merchantability, fitness 101 | for a particular purpose, non infringement, or the absence of latent or 102 | other defects, accuracy, or the present or absence of errors, whether or not 103 | discoverable, all to the greatest extent permissible under applicable law. 104 | 105 | c. Affirmer disclaims responsibility for clearing rights of other persons 106 | that may apply to the Work or any use thereof, including without limitation 107 | any person's Copyright and Related Rights in the Work. Further, Affirmer 108 | disclaims responsibility for obtaining any necessary consents, permissions 109 | or other rights required for any use of the Work. 110 | 111 | d. Affirmer understands and acknowledges that Creative Commons is not a 112 | party to this document and has no duty or obligation with respect to this 113 | CC0 or use of the Work. 114 | 115 | For more information, please see 116 | 117 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | --- 1.2.1 (2019-05-24) 2 | 3 | • Work posting & Table updates: Stopped assuming works had LCCNs, N/A doesn’t prevent linking to LDS work 4 | • unposted description: pick the right work when there was more than one (stubs, etc.) 5 | • Issues displaying Classification numbers: Classification was split into two profiles, moving the resource templates into a single profile fixed this 6 | • Posting not working w/o preview: Preview was generating the RDF+XML, fixed it so RDF+XML happens outside of preview 7 | • BFE lookup: add pop-up to children's subjects: added 8 | • Load error handling: Load features now fail gracefully if you input an invalid string in the load box 9 | • Script dropdown issues: For the lit-lang, script is blank and allows no script, which would be common for latin script languages (e.g. @en) 10 | • IBC description drops LCCN: Fixed situation where the table load process clears out the bfestore 11 | • Resource templates can be non-repeatable, set this way with generated AdminMetadta 12 | • madsrdf and rdfs:label text regenerated when subjects are edited 13 | • Added NEWS file 14 | 15 | --- v1.2.0 (2019-04-26) 16 | 17 | • Configuration modifications 18 | • Starting points have been moved to be served from a file or from verso 19 | • Config methods have been pushed into src/bfe.js 20 | • properties have been externalized into env variables 21 | • Support for Literal Languages added 22 | • OCLC is now an allowed type of lookup for loading MARC from Worldcat in addition to bibids and LCCN from catalog.loc.gov via metaproxy 23 | • Many types of labels have been modified to display more consistently 24 | • Based on user feedback Primary contribution has been added to the table 25 | • UI improved to remove static menu sidebar and replace it with a creation button, along with a consistent toolbar 26 | • Modal windows modified to be movable & do not close when clicking outside of window. 27 | • Various other bug fixes 28 | 29 | --- v1.1.1 (2019-04-01) 30 | 31 | • Add option to link to external database, externalize database urls. 32 | • Various bug fixes 33 | 34 | --- v1.1.0 (2019-03-01) 35 | 36 | • Admin Metadata enhancements 37 | • Enter key fixed, no longer refreshes browser in single property modal windows. 38 | • Implement lists in bfestore 39 | • Fix date rendering 40 | • Implement user templates 41 | • Fix headings 42 | • Speedup jQuery Datatable loading 43 | 44 | --- v1.0.0 (2018-10-18) 45 | 46 | • Fixes for labels 47 | • Set rectoBase using env variable; use env.sh to populate 48 | • Updated documentation 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [bfe][demo-page] 2 | ======================= 3 | [![CircleCI](https://circleci.com/gh/lcnetdev/bfe/tree/main.svg?style=svg)](https://circleci.com/gh/lcnetdev/bfe/tree/main) 4 | *** Note: This editor is no longer under development. The Library of Congress is using MARVA to edit BIBFRAME resources. *** 5 | 6 | `bfe` is a standalone Editor for the Library of Congress's [Bibliographic Framework 7 | (BIBFRAME) Initiative][bfi]. It can be used more generically as an editor for RDF data. 8 | `bfe` uses [BIBFRAME Profiles][profilespec] to render an HTML/UI input form; it is 9 | capable of integrating 'lookup' services, which query data from external Web APIs; 10 | and implementers can define the input and extract the output. 11 | 12 | This repository includes a development example, a "production" example, and 13 | various BIBFRAME Profiles with which to begin experimenting. In order 14 | to get started with `bfe` quickly and easily, there are two main aspects of `bfe`: 15 | a javascript library and an accompanying CSS file. The packaged javascript 16 | library bundles a few additional libraries, some of which are [JQuery], [Lo-Dash], 17 | elements from Twitter's [Bootstrap.js][Bootstrap], and 18 | Twitter's [typeahead.js]. The CSS bundle includes mostly elements of 19 | Twitter's [Bootstrap] and a few additional custom CSS declarations. 20 | 21 | 22 | 23 | [demo-page]: http://bibframe.org/bfe/index.html 24 | [ontology]: http://id.loc.gov/ontologies/bibframe/ 25 | [bfi]: http://www.loc.gov/bibframe/ 26 | 27 | Getting Started 28 | --------------- 29 | `bfe` is currently submodule of [recto](http://github.com/lcnetdev/recto), an express-based webserver, which uses [verso](http://github.com/lcnetdev/verso) a loopback-based server for backend data. The current recommendation is to install recto and verso and use bfe as part of the demonstration environment. 30 | 31 | `bfe`'s `RECTOBASE` is now set using an environment variable. 32 | Note: default `RECTOBASE` value is `http://localhost:3000`. 33 | 34 | ```bash 35 | ./env.sh > builds/env.js 36 | npm install 37 | grunt 38 | ``` 39 | 40 | `bfe` can be run as a demo or development version using a simple express-based server - found in the main `bfe` directory - 41 | that ships with `bfe`: 42 | 43 | ```bash 44 | node server-bfe.js 45 | ``` 46 | 47 | Documentation 48 | ------------- 49 | 50 | * [API] 51 | 52 | [API]: https://github.com/lcnetdev/bfe/blob/master/docs/bfe-api.md 53 | 54 | 55 | Demo? 56 | -------- 57 | 58 | [Online Demo][demo-page] 59 | 60 | 61 | 62 | [demo-page]: http://bibframe.org/bibliomata/bfe/index.html 63 | 64 | Browser Support 65 | --------------- 66 | 67 | * Chrome 34 68 | * Firefox 24+ 69 | * Safari - 6+ 70 | * Opera - 12+ 71 | 72 | **NOTE:** `bfe` has also not been **thoroughly** tested in the browsers for which 73 | support is currently listed. It has been developed primarily using Chrome. 74 | It has been tested in both Chrome and Safari mobile versions. IE is no longer supported. 75 | 76 | Issues 77 | ------ 78 | 79 | Log them here: 80 | 81 | https://github.com/lcnetdev/bfe/issues 82 | 83 | 84 | Support 85 | ---------------- 86 | 87 | For technical questions about `bfe`, you can use the GitHub [Issues] feature, but 88 | please "label" your question a 'question.' 89 | 90 | Although you are encouraged to ask your quesion publicly (the answer might 91 | help everyone), you may also email this repository's [maintainer][khes] 92 | directly. 93 | 94 | For general questions about BIBFRAME, you can subscribe to the [BIBFRAME Listserv][listserv] 95 | and ask in that forum. 96 | 97 | 98 | 99 | [Issues]: https://github.com/lcnetdev/bfe/issues 100 | [khes]: mailto:khes@loc.gov 101 | [listserv]: http://listserv.loc.gov/cgi-bin/wa?SUBED1=bibframe&A=1 102 | 103 | Developers 104 | ---------- 105 | 106 | From a design standpoint, the objective with `bfe` was to create the simplest 107 | 'pluggable' form editor one can to maximize experimental implementer's abilities 108 | to create/edit BIBFRAME data. The current focus is to transform bfe into a production ready tool. 109 | 110 | All contributions are welcome. If you do not code, surely you will discover an 111 | [issue] you can report. 112 | 113 | 'Building' `bfe` requires npm, bundled with [node.js] and [grunt]. See `package.json` for dependencies. 114 | See `Gruntfile.json` for build dependencies. 115 | 116 | Basic build steps: 117 | * npm init 118 | * npm install 119 | * grunt 120 | 121 | 122 | 123 | [issue]: https://github.com/lcnetdev/bfe/issues 124 | [Lookup]: https://github.com/lcnetdev/bfe/tree/master/src/bfelookups.js 125 | [node.js]: http://nodejs.org 126 | [Grunt]: http://gruntjs.com 127 | 128 | Acknowledgements 129 | ---------- 130 | 131 | In addition to all the good people who have worked on [JQuery], [Lo-Dash], 132 | Twitter's [Bootstrap], Twitter's [typeahead.js], [require.js], [dryice], and 133 | more, all of whom made this simpler, special recognition needs to 134 | go to the developers who have worked on [Ajax.org's Ace editor][ace] and 135 | the fine individuals at [Zepheira]. 136 | 137 | Using `require.js`, `Ace`'s developers figured out a great way to bundle their code 138 | into a single distributable. `Ace`'s methods were studied and emulated, and when 139 | that wasn't enough, their code was ported (with credit, of course, and those 140 | snippets were ported only in support of building the package with `dryice`). The 141 | `Ace`'s devs also just have a really smart way of approaching this type of 142 | javascript project. 143 | 144 | In late 2013, and demoed at the American Library Association's Midwinter Conference, 145 | Zepheira developed a prototype BIBFRAME Editor. Although that project never moved 146 | beyond an experimental phase, Zepheira's work was nevertheless extremely influential, 147 | especially with respect to `bfe`'s UI design. (None of the code in `bfe` was ported 148 | from Zepheira's prototype.) Zepheira also developed the [BIBFRAME Profile 149 | Specification][profilespec]. 150 | 151 | 152 | 153 | [JQuery]: http://jquery.com/ 154 | [Lo-Dash]: http://lodash.com/ 155 | [Bootstrap]: http://getbootstrap.com/ 156 | [typeahead.js]: https://github.com/twitter/typeahead.js 157 | [require.js]: http://requirejs.org/ 158 | [dryice]: https://github.com/mozilla/dryice 159 | [ace]: https://github.com/ajaxorg/ace 160 | [Zepheira]: https://zepheira.com/ 161 | 162 | 163 | Contributors 164 | ----------- 165 | 166 | * [Jeremy Nelson](https://github.com/jermnelson) 167 | * [Kevin Ford](https://github.com/kefo) 168 | * [Kirk Hess](https://github.com/kirkhess) 169 | * [Matt Miller](https://github.com/thisismattmiller) 170 | 171 | [Index Data](http://indexdata.com/): 172 | * [Charles Ledvina](https://github.com/cledvina) 173 | * [Wayne Schneider](https://github.com/wafschneider) 174 | 175 | Maintainer 176 | ----------- 177 | 178 | * **Kirk Hess** 179 | * [GitHub](https://github.com/kirkhess) 180 | 181 | 182 | License 183 | ------- 184 | 185 | Unless otherwise noted, code that is original to `bfe` is in the Public Domain. 186 | 187 | http://creativecommons.org/publicdomain/mark/1.0/ 188 | 189 | **NOTE:** `bfe` includes or depends on software from other open source projects, all or 190 | most of which will carry their own license and copyright. The Public Domain mark 191 | stops at `bfe` original code and does not convey to these projects. 192 | -------------------------------------------------------------------------------- /development.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (Bibliographic Framework Initiative Technical Site - BIBFRAME.ORG) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 91 | 92 |
93 |
94 |
95 | 96 | 103 | 104 | 105 |
106 |
107 |
108 | 109 |
110 | 117 | 118 | 121 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/bfe-api.md: -------------------------------------------------------------------------------- 1 | `bfe` API 2 | ---------------- 3 | 4 | `bfe` is a Javascript UI application that renders an HTML form based on defined 5 | Profiles. There are things to know about configuring and using `bfe`. 6 | 7 | Contents 8 | ----------------- 9 | 10 | * [`bfe`](#bfe) 11 | * [Configuring `bfe`](#configuring-bfe) 12 | * [`bfelookup`](#bfelookup) 13 | * [`bfestore`](#bfestore) 14 | * [`bfelog`](#bfelog) 15 | 16 | 17 | ---------------- 18 | 19 | ### `bfe` 20 | 21 | The defined, Javascript namespace for `bfe` when loaded. 22 | 23 | #### bfe.lcapplication(Object configObject, String divid) 24 | 25 | Invokes the "LC Application." This mode includes an entire tab-mased menu to load records 26 | from various LC-specific sources, such as LC's bibframe database, OCLC, etc. 27 | *This mode will not work for any user but LC.* It will also include all of the 28 | `fulleditor` mode. See [below](#configuring-bfe) for more about the `configObject`. 29 | `id` is the identifier of the HTML element into which the editor will be loaded. 30 | Use a `div`. 31 | 32 | ```javascript 33 | var bfeditor = bfe.fulleditor(Object configObject, divid); 34 | ``` 35 | 36 | #### bfe.fulleditor(Object configObject, String divid) 37 | 38 | Invokes the "full editor," meaning a left-side navigation menu will be included. 39 | See [below](#configuring-bfe) for more about the `configObject`. `id` is the 40 | identifier of the HTML element into which the editor will be loaded. Use a `div`. 41 | 42 | ```javascript 43 | var bfeditor = bfe.fulleditor(Object configObject, divid); 44 | ``` 45 | 46 | 47 | #### bfe.editor(Object configObject, String divid) 48 | 49 | Invokes only the `form` component of the "editor," meaning a left-side navigation 50 | menu will *not* be included. See [below](#configuring-bfe) for more about the 51 | `configObject`. `id` is the identifier of the HTML element into which the editor 52 | will be loaded. Use a `div`. 53 | 54 | ```javascript 55 | var bfeditor = bfe.editor(configObject, divid); 56 | ``` 57 | 58 | ---------------- 59 | 60 | ### Configuring `bfe` 61 | 62 | The `config` object is a JSON Object that, minimally, identifies which Profiles 63 | to load and, if invoking the "full editor," the structure of the left-side menu. 64 | Providing a `return` description is generally necessary in order to provide a 65 | callback function for when the user hits the `save` button. 66 | 67 | #### `config` Properties 68 | 69 | Required 70 | 71 | * `url`: (String) the url for the server, which in the example config is set to 72 | rectoBase, which by default is `http://localhost:3000`, or the value of RECTOBASE 73 | which is set in env.js by env.sh. 74 | 75 | * `baseURI`: (String) the base URI to use when minting new identifiers. Defaults 76 | to `http://example.org/`. 77 | 78 | * `literalLangDataUrl`: (String) Url to a JSON structure that contains config information 79 | for language and scripts to handle non-latin cataloging. QUESTION: Why is this 80 | handled this way? It's inherent functionality. 81 | 82 | * `profiles`: (Array) locations (URLs) of Profiles to be 83 | loaded. Profiles should be in the form of a JSON array with one or 84 | more objects that contain a "name" and a "json" property with the 85 | profile itself. For example: 86 | 87 | ```json 88 | [ 89 | { 90 | "name": "BIBFRAME 2.0 Agent", 91 | "json": { 92 | "Profile": { 93 | [...] 94 | } 95 | } 96 | } 97 | ] 98 | ``` 99 | 100 | * `return`: (Object) contains two properties. `format`, which indicates how the 101 | the data should be formatted/serialized. Only "jsonld-expanded" is supported 102 | presently. `callback` is the name of the callback function, which expects one 103 | parameter, the returned data formatted according to the `format` instruction. 104 | 105 | * `startingPoints` (only for fulleditor or lcapplication): (Array) Each member of the 106 | array is an object representing 107 | a menu group, which consists of a heading (`menuGroup`) and an array of 108 | items (`menuItems`). Each item has a `label` and an array of applicable 109 | resource templates (`useResourceTemplates`) to be used when rendering that item. 110 | `useResourceTemplates` expects the identifier value of a resource template (not 111 | the identifer for a Profile). If more than one resource template identifier is 112 | listed, then the multiple resource templates are combined into one form for 113 | editing. This property must be present OR `startingPointsUrl` must be present. 114 | 115 | ```json 116 | "startingPoints": [ 117 | {"menuGroup": "Monograph", 118 | "menuItems": [ 119 | { 120 | label: "Instance", 121 | type: ["http://id.loc.gov/ontologies/bibframe/Instance"], 122 | useResourceTemplates: [ "profile:bf2:Monograph:Instance" ] 123 | }, 124 | { 125 | label: "Work", 126 | type: ["http://id.loc.gov/ontologies/bibframe/Work"], 127 | useResourceTemplates: [ "profile:bf2:Monograph:Work" ] 128 | } 129 | 130 | ]} 131 | ] 132 | ``` 133 | 134 | * `startingPointsUrl` (only for fulleditor or lcapplication): (Array) A URL 135 | that provides a JSON object that contains the `startingPoints` array as described 136 | above. This property must be present OR `startingPoints` must be present. 137 | The JSON should be structured as follows: 138 | 139 | ```json 140 | [ 141 | { 142 | "id":"d1ab69a1-fe18-40d6-b596-40039a1144ae", 143 | "name":"config", 144 | "configType":"startingPoints", 145 | "json": [ 146 | { 147 | "menuGroup": "Monograph", 148 | "menuItems": [ 149 | { 150 | label: "Instance", 151 | type: ["http://id.loc.gov/ontologies/bibframe/Instance"], 152 | useResourceTemplates: [ "profile:bf2:Monograph:Instance" ] 153 | }, 154 | { 155 | label: "Work", 156 | type: ["http://id.loc.gov/ontologies/bibframe/Work"], 157 | useResourceTemplates: [ "profile:bf2:Monograph:Work" ] 158 | } 159 | ] 160 | } 161 | ] 162 | } 163 | ] 164 | ``` 165 | 166 | Optional 167 | * `basedbURI`: Used to determine whether the "Search BIBFRAME database" link appears 168 | and where the link goes. 169 | * `buildContext`: (Boolean) True to build typeahead side panels, which provide more 170 | information - context - about the highlighted drop down option to assist with selection. 171 | Defaults to `false`. 172 | * `buildContextFor`: (Array) An array of strings that, when tested against a URI, will return `True` if a context panel 173 | should be generated for that particular URI. For example, this array - `['id.loc.gov/authorities/names/','id.loc.gov/authorities/subjects/']`- 174 | would generate a context panel for any Names or Subjects URI/Resource. 175 | * `buildContextForWorksEndpoint`: (String) This is a custom override for LC to redirect context panel requests from resources 176 | at ID.LOC.GOV to an internal source. QUESTION: Is this necessary still or could we use the ID data? 177 | * `enableUserTemplates`: (Boolean) This will permit users to generate their own "templates," which is a means to hide not-required fields in 178 | a chosen profile. Default "true". 179 | * `enableLoadMarc`: (Boolean) This option - really only useful to LC - will enable the "Load MARC" tab in the `lcapplication` (see above). 180 | * `logging`: (Object) with two properties. `level` indicates the level of logging 181 | desired. INFO and DEBUG are the two options. DEBUG is verbose. Default is 182 | INFO. `toConsole` is a boolean value. "True" will write the output to the 183 | Javascript console during runtime. Default is "True". 184 | * lookups: (Object) an object of objects. The object's key is a scheme identifier used or 185 | expected to be used with the useValuesFrom property constraint from a property in a 186 | property template which is part of a profile's resource template. Each object consists of 187 | two properties. name is a label/identifier for the lookup. It is used by the typeahead library. 188 | load is the location of the Javascript file the contains the functions required to populate 189 | the typeahead drop down selection list and then to process the selected item. QUESTION: It 190 | is really hard to tell if this would even work any more. Will it? 191 | * `resourceURI`: Base URI for resources in the triplestore. 192 | * `toload`: Object that contains the template to load and the resource to load (i.e. populate the form) 193 | ```json 194 | { 195 | "defaulturi": "http://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b", 196 | "templates": [ 197 | { 198 | "templateID": "lc:RT:bf2:Hub:Hub" 199 | } 200 | ], 201 | "source": { 202 | "location": "https://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b.bibframe_edit.json?test", 203 | "requestType": "json", 204 | "data": "UNUSED, BUT REMEMBER IT" 205 | } 206 | } 207 | ``` 208 | 209 | 210 | ---------------- 211 | 212 | ### `bfelookup` 213 | 214 | `bfe` Lookups 215 | ---------------- 216 | 217 | A `bfe` lookup is a Javascript function that contains logic to fetch typeahead suggestions, 218 | format those suggestions for display, and, after a suggestion is selected, a 219 | lookup performs post-selection processing and returns the data to the editor. 220 | 221 | Each lookup must contain three exported objects: 222 | 223 | * `scheme` - (String) representing the scheme identifier. This is used to match 224 | the lookup with the appropriate declaration in the `useValuesFrom` declaration 225 | in the profile. 226 | * `source` - (Function) expects two parameters - `query, process` - and 227 | ultimately returns a list of objects each with a `uri` property and `value` 228 | property, the latter containing the humand readable text to display. 229 | * `getResource` - (Function) expects four parameters: `subjecturi, propertyuri, 230 | selected, process`. `subjecturi` is the URI for the resource being described. 231 | `propertyuri` is the property uri of the property that invoked the lookup. 232 | `selected` is the selected item, it has two properties `uri` and `value`, about 233 | which see `source` above. Finally, `process` is the callback. At the end, `process` is called with 234 | one parameter, which is an array of triples formatted according to the [`bfestore`](#bfestore). 235 | It is not necessary to include the `guid` property for each triple; that is added 236 | after the data is returned to the editor. 237 | 238 | Lookups can be created and dynamically loaded at run time. See [configuring 239 | `bfe`](#configuring-bfe). If a 'key' of a dynamically loaded lookup is the same 240 | as a pre-existing/pre-loaded lookup, the pre-loaded one is overwritten and not 241 | used. 242 | 243 | 244 | 245 | ---------------- 246 | 247 | ### `bfestore` 248 | 249 | The `bfestore` is an in-memory store of the data being created or modified. If 250 | data is loaded for editing, the store is populated with that data. As data is 251 | otherwise created, deleted, or modified during an editing session, the store is 252 | updated accordingly. `bfestore` provides a few methods for accessing the data. 253 | 254 | #### bfe.bfestore.store 255 | 256 | Is the store itself. The store is an array of triples of the following form. 257 | 258 | ```javascript 259 | [ 260 | { 261 | "guid": "79d84d4c-9752-fecd-9d79-91455a552dc5", 262 | "rtID": "profile:bf:Instance", 263 | "s": "http://example.org/79d84d4c-9752-fecd-9d79-91455a552dc5", 264 | "p": "http://www.w3.org/1999/02/22-rdf-syntax-ns#type", 265 | "o": "http://bibframe.org/vocab/Instance", 266 | "otype": "uri" 267 | }, 268 | { 269 | "guid": "0dfcafb2-1a0c-e190-a372-7423675dd9c0", 270 | "s": "http://example.org/79d84d4c-9752-fecd-9d79-91455a552dc5", 271 | "p": "http://bibframe.org/vocab/title", 272 | "o": "Some title", 273 | "otype": "literal", 274 | "olang": "en" 275 | } 276 | ] 277 | ``` 278 | #### bfe.bfestore.jsonld2store 279 | Expects expanded jsonld, and converts the jsonld to an array of triples. 280 | 281 | #### bfe.bfestore.rdfxml2store 282 | Using ajax uses `http://rdf-translator.appstpot.com` to convert rdfxml to jsonld, which used the helper function `jsonldcompascted2store` to expand the jsonld and normalize blanknodes and identifiers. Used with Load Marc in editor. 283 | 284 | #### bfe.bfestore.store2rdfxml 285 | 286 | Using jsonld, converts the jsonld to nquads, which is converted to turtle by N3.js. The prefixes are set and the turtle 287 | is sent to rapper using a rest api on recto. Used in the preview pane. 288 | 289 | #### bfe.bfestore.n32store 290 | 291 | Using N3.js, convert n3/turtle to quads, which is passed to jsonld, expanded and pushed into the bfestore. 292 | 293 | #### bfe.bfestore.store2turtle() 294 | 295 | Returns the store formatted as turtle, for use in the preview pane. 296 | 297 | #### bfe.bfestore.store2jsonldcompacted 298 | Returns the store formatted as compacted jsonld, for use in the preview pane. 299 | 300 | ---------------- 301 | 302 | ### `bfelog` 303 | 304 | `bfelog` manages INFO and DEBUG logging for `bfe`. See the 305 | [`bfe` config options above](#configuring-bfe) for more information about setting 306 | logging levels. `bfelog` was put together quickly and is a candidate for serious 307 | rethinking. 308 | 309 | #### bfe.bfelog.getLog() 310 | 311 | Returns the log as a JSON object. Sample: 312 | 313 | ```javascript 314 | [ 315 | { 316 | "dt": "2014-05-01T14:02:33.477Z", 317 | "dtLocaleSort": "2014-05-01T14:02:33.477Z", 318 | "dtLocaleReadable": "5/1/2014, 10:02:33 AM", 319 | "type": "INFO", 320 | "fileName": "src/bfelogging.js", 321 | "lineNumber": 23, 322 | "msg": "Logging instantiated: level is DEBUG; log to console is set to true" 323 | }, 324 | { 325 | "dt": "2014-05-01T14:02:33.486Z", 326 | "dtLocaleSort": "2014-05-01T14:02:33.486Z", 327 | "dtLocaleReadable": "5/1/2014, 10:02:33 AM", 328 | "type": "INFO", 329 | "fileName": "src/bfelogging.js", 330 | "lineNumber": 24, 331 | "msg": "http://localhost:8000/" 332 | }, 333 | { 334 | "dt": "2014-05-01T14:02:33.486Z", 335 | "dtLocaleSort": "2014-05-01T14:02:33.486Z", 336 | "dtLocaleReadable": "5/1/2014, 10:02:33 AM", 337 | "type": "INFO", 338 | "fileName": "src/bfe.js", 339 | "lineNumber": 126, 340 | "msg": "Loading profile: /static/profiles/bibframe/Agents.json" 341 | } 342 | ] 343 | ``` 344 | 345 | 346 | 347 | -------------------------------------------------------------------------------- /docs/changelog.md: -------------------------------------------------------------------------------- 1 | Change Log 2 | 3 | ---------------- 4 | 5 | This change log pertains to builds. 6 | 7 | ---------------- 8 | * 1.1.0 (2018-03-01) 9 | * Enter key fixed, no longer refreshes browser in single property modal windows. 10 | * Implement lists in bfestore 11 | * Fix date rendering 12 | * Implement user templates 13 | * Fix headings 14 | * Speedup jQuery Datatable loading 15 | 16 | * 1.0.0 (2018-10-18) 17 | * Fixes for labels 18 | * Set rectoBase using env variable; use env.sh to populate 19 | * Updated documentation 20 | 21 | * 0.4.0 (2018-09-24) 22 | * Fixes for #13, #14, #15, #16, #17, #18, #19 23 | * This release is incorporated into Recto lcnetdev/recto as a submodule. 24 | * Please change the rectoBase variable in static/js/config.js and static/js/config-dev.js to your path. 25 | 26 | * 0.3.1 (2018-03-26) 27 | * Minor profile and code fixes 28 | 29 | * 0.3.0 (2018-03-21) 30 | * LC BIBFRAME 2.0 Pilot version 31 | * Includes BIBFRAME 2.0 Profiles 32 | 33 | * 0.2.0 (2015-10-20) 34 | * Replace dryice with grunt 35 | * Refactor build w/o request.js (deprecated) 36 | * Support LC Pilot w/many new lookups added 37 | * Lookups in single file. 38 | 39 | * 0.1.5 (2014-10-03) 40 | * Fix: Use '@type' in JSONLD expanded. 41 | 42 | * 0.1.4 (2014-08-11) 43 | * Bug Fix: Invalid JSONLD expanded. 44 | 45 | * 0.1.3 (2014-05-06) 46 | * Bug Fix: Bad var name resulting in 'undefined.' 47 | 48 | * 0.1.2 (2014-05-02) 49 | * Bug Fix: Allow lookup if not the initial property on base form. 50 | * Bug Fix: only return bf-specific triples for lcnames and lcsubjects lookups 51 | when propertyuri is in the bf or relators namespaces. 52 | 53 | * 0.1.1 (2014-05-02) 54 | * Bug Fix: Remove default language tag from literals. 55 | 56 | * 0.1.0 (2014-05-02) 57 | * Initial release. 58 | 59 | -------------------------------------------------------------------------------- /editor-dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (Bibliographic Framework Initiative Technical Site - BIBFRAME.ORG) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
75 |
76 |
77 | 78 | 79 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /env.sh: -------------------------------------------------------------------------------- 1 | echo "env = {" 2 | echo " RECTOBASE: '$RECTOBASE'," 3 | echo " BASEDBURI: '$BASEDBURI'" 4 | echo "}" 5 | -------------------------------------------------------------------------------- /fulleditor-dev.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (Bibliographic Framework Initiative Technical Site - BIBFRAME.ORG) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 |
75 |
76 |
77 | 78 | 79 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (Bibliographic Framework Initiative Technical Site - BIBFRAME.ORG) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 72 | 73 |
74 |
75 |
76 | 77 | 84 | 85 | 86 |
87 |
88 |
89 | 90 |
91 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "events": { 3 | "start": "grunt concat:test" 4 | }, 5 | "ext": "js html css", 6 | "watch": "src" 7 | } 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bfe", 3 | "description": "Editor for BIBFRAME data (but more generically an RDF editor)", 4 | "keywords": [ 5 | "bibframe", 6 | "editor", 7 | "rdf" 8 | ], 9 | "version": "2.0.2", 10 | "engines": { 11 | "node": ">=10.0.0" 12 | }, 13 | "homepage": "http://github.com/lcnetdev/bfe", 14 | "author": "Kevin Ford ", 15 | "main": "Gruntfile.js", 16 | "repository": { 17 | "type": "git", 18 | "url": "http://github.com/lcnetdev/bfe.git" 19 | }, 20 | "devDependencies": { 21 | "eslint": ">=7.12.1", 22 | "express": "^4.17.1", 23 | "serve-static": "^1.13.2" 24 | }, 25 | "bugs": { 26 | "url": "http://github.com/lcnetdev/bfe/issues" 27 | }, 28 | "license": "CC0-1.0", 29 | "directories": { 30 | "doc": "docs" 31 | }, 32 | "scripts": { 33 | "test": "echo \"Error: no test specified\" && exit 1", 34 | "lint": "eslint --config .eslintrc.json src/" 35 | }, 36 | "dependencies": { 37 | "grunt": "^1.x.x", 38 | "grunt-contrib-concat": "^1.x.x", 39 | "grunt-contrib-cssmin": "^3.x.x", 40 | "grunt-contrib-uglify-es": "^3.x.x", 41 | "lodash": "^4.17.19" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /server-bfe.js: -------------------------------------------------------------------------------- 1 | // Minimal BIBFRAME Editor Node.js server. To run from the command-line: 2 | // node server-bfe.js 3 | 4 | var port = 8000; 5 | var express = require('express'); 6 | 7 | var app = express(); 8 | 9 | app.use(express.static(__dirname + '/')); 10 | app.listen(port); 11 | 12 | console.log('BIBFRAME Editor running on ' + port); 13 | console.log('Press Ctrl + C to stop.'); 14 | -------------------------------------------------------------------------------- /src/bfelabels.js: -------------------------------------------------------------------------------- 1 | /*eslint no-console: 0*/ 2 | /*eslint no-useless-escape: "error"*/ 3 | bfe.define('src/bfelabels', ['require', 'exports','src/bfelogging' ], function(require, exports) { 4 | 5 | var bfelog = require('src/bfelogging'); 6 | 7 | exports.getLabel = function(resource, property, store, labelProp="http://www.w3.org/2000/01/rdf-schema#label") { 8 | var label = ""; 9 | var triple = _.find(resource, { 10 | 'p': property 11 | }); 12 | if (triple !== undefined) { 13 | var uri = triple.o; 14 | var labelResource = _.find(store, { 15 | 's': uri, 16 | 'p': labelProp 17 | }); 18 | if (labelResource !== undefined) { 19 | label = labelResource.o; 20 | 21 | } else if (uri.endsWith('marcxml.xml')) { 22 | label = /[^/]*$/.exec(uri)[0].split('.')[0]; 23 | 24 | } else if (uri.match(/[works|instances]\/\d+#\w+\d+-\d+/) || uri.match(/_:.*/g) ) { 25 | // For URIs that have ampersands and other odd things. 26 | // For blank nodes. 27 | if(_.some(store, { s: uri, p: "http://www.w3.org/2000/01/rdf-schema#label"})){ 28 | label = _.find(store, { s: uri, p: "http://www.w3.org/2000/01/rdf-schema#label" }).o; 29 | } else if(_.some(store, { s: uri, p: "http://www.loc.gov/mads/rdf/v1#authoritativeLabel"})){ 30 | label = _.find(store, { s: uri, p: "http://www.loc.gov/mads/rdf/v1#authoritativeLabel" }).o; 31 | } else if(_.some(store, { s: uri, p: "http://www.w3.org/1999/02/22-rdf-syntax-ns#value"})){ 32 | label = _.find(store, { s: uri, p: "http://www.w3.org/1999/02/22-rdf-syntax-ns#value" }).o; 33 | } else if(_.some(store, { s: uri, p: "http://id.loc.gov/ontologies/bflc/aap"})){ 34 | label = _.find(store, { s: uri, p: "http://id.loc.gov/ontologies/bflc/aap" }).o; 35 | } else { 36 | label = ""; 37 | } 38 | 39 | } else { 40 | bfelog.addMsg(new Error(), 'DEBUG', 'No label found for ' + property + ' - Looking up: ' + uri); 41 | findLabel(uri, function (foundLabel) { 42 | label = foundLabel; 43 | }); 44 | } 45 | } 46 | return label; 47 | }; 48 | 49 | function findLabel(uri, callback) { 50 | var label = uri; 51 | uri = uri.replace(/^(https:)/,"http:"); 52 | bfelog.addMsg(new Error(), 'DEBUG', 'findLabel uri: ' + uri); 53 | 54 | var jsonuri = uri + '.json'; 55 | // normalize 56 | if (uri.startsWith('http://id.loc.gov/resources/works') || uri.startsWith('http://id.loc.gov/resources/instances')&& !_.isEmpty(config.resourceURI)) { 57 | jsonuri = uri.replace('http://id.loc.gov/resources', config.resourceURI) + '.jsonld'; 58 | jsonuri = jsonuri.replace(/^(http:)/,"https:"); 59 | } else if (uri.startsWith('http://id.loc.gov') && uri.match(/(authorities|vocabulary)/)) { 60 | jsonuri = uri + '.madsrdf_raw.json'; 61 | jsonuri = jsonuri.replace(/^(http:)/,"https:"); 62 | } 63 | bfelog.addMsg(new Error(), 'DEBUG', 'Making call to recto whichrt using: ' + jsonuri); 64 | $.ajax({ 65 | type: 'GET', 66 | async: false, 67 | data: { 68 | uri: jsonuri 69 | }, 70 | url: config.url + '/profile-edit/server/whichrt', 71 | success: function (data) { 72 | var labelElements; 73 | var authoritativeLabelElements; 74 | var aapElements; 75 | if(_.some(_.find(data, { '@id': uri }))) { 76 | labelElements = _.find(data, { '@id': uri })['http://www.w3.org/2000/01/rdf-schema#label'] 77 | authoritativeLabelElements = _.find(data, { '@id': uri })['http://www.loc.gov/mads/rdf/v1#authoritativeLabel']; 78 | aapElements = _.find(data, { '@id': uri })['http://id.loc.gov/ontologies/bflc/aap']; 79 | } 80 | if (!_.isEmpty(labelElements)) { 81 | label = labelElements[0]["@value"]; 82 | } else if (!_.isEmpty(aapElements)) { 83 | label = aapElements[0]["@value"] 84 | } else if (!_.isEmpty(authoritativeLabelElements)) { 85 | label = authoritativeLabelElements[0]["@value"] 86 | } else { 87 | // look for a rdfslabel 88 | var labels = _.filter(data[2], function (prop) { if (prop[0] === 'rdfs:label') return prop; }); 89 | if (!_.isEmpty(labels)) { 90 | label = labels[0][2]; 91 | } else if (_.has(data, "@graph")) { 92 | if (_.some(data["@graph"], {"@id": uri})) { 93 | label = _.find(data["@graph"], {"@id": uri})["rdf-schema:label"] 94 | } else if ( _.some(data["@graph"], {"@type": ["http://id.loc.gov/ontologies/lclocal/Hub"]})) { 95 | label = _.find(data["@graph"], {"@type": ["http://id.loc.gov/ontologies/lclocal/Hub"]})["rdf-schema:label"] 96 | } 97 | } 98 | } 99 | callback(label); 100 | }, 101 | error: function (XMLHttpRequest, textStatus, errorThrown) { 102 | bfelog.addMsg(new Error(), 'ERROR', 'Request status: ' + textStatus + '; Error msg: ' + errorThrown); 103 | callback(label); 104 | } 105 | }); 106 | } 107 | 108 | exports.findURIatID = function(scheme, label) { 109 | var idInfo = { uri: "", validationMessage: "Not found", label: label }; 110 | var labelservice = scheme + "/label/" + encodeURIComponent(label); 111 | labelservice = labelservice.replace(/^(http:)/,"https:"); 112 | labelservice = labelservice.replace('//id.loc.gov/','//preprod-8288.id.loc.gov/'); 113 | bfelog.addMsg(new Error(), 'DEBUG', 'labelservice uri: ' + labelservice); 114 | 115 | /* 116 | The browser will automatically follow 302, 303 redirects. It is impossible 117 | therefore to perform a HEAD request, get the initial response, pluck the 118 | X-URI out of it, and move one with our lives. We must wait for all the 119 | redirects to play out and the content delivered. 120 | */ 121 | $.ajax({ 122 | type: 'GET', 123 | async: false, 124 | headers: { 'Accept': 'application/json' }, 125 | url: labelservice 126 | }) 127 | .done(function(d, s, xhr) { 128 | uri = xhr.getResponseHeader('x-uri'); 129 | preflabel = xhr.getResponseHeader('x-preflabel'); 130 | idInfo = { uri: uri, label: preflabel }; 131 | prelabel_normalized = preflabel.replace('.', '').replace(' ', ''); 132 | label_normalized = label.replace('.', '').replace(' ', ''); 133 | if (prelabel_normalized != label_normalized) { 134 | idInfo.validationMessage = "See reference"; 135 | } else { 136 | idInfo.validationMessage = "Heading validated"; 137 | } 138 | }) 139 | .fail(function (XMLHttpRequest, textStatus, errorThrown) { 140 | bfelog.addMsg(new Error(), 'ERROR', 'Request status: ' + textStatus + '; Error msg: ' + errorThrown); 141 | }); 142 | return idInfo; 143 | }; 144 | 145 | }); -------------------------------------------------------------------------------- /src/bfeliterallang.js: -------------------------------------------------------------------------------- 1 | /*eslint no-console: 0*/ 2 | /*eslint no-useless-escape: "error"*/ 3 | bfe.define('src/bfeliterallang', ['require', 'exports','src/bfelogging' ], function(require, exports) { 4 | 5 | 6 | var bfelog = require('src/bfelogging'); 7 | 8 | exports.iso6391 = []; 9 | exports.iso6392 = []; 10 | exports.iso6392to6391 = []; 11 | exports.iso15924 = []; 12 | exports.languagePatterns = []; 13 | 14 | exports.loadData = function(config){ 15 | $.ajax({ 16 | context: this, 17 | url: config.literalLangDataUrl, 18 | success: function (data) { 19 | bfelog.addMsg(new Error(), 'INFO', 'Fetched external source baseURI' + config.literalLangDataUrl); 20 | bfelog.addMsg(new Error(), 'DEBUG', 'Source data', data); 21 | 22 | // save off each of the data pieces 23 | data.forEach(function(d){ 24 | if (d.name==='literalLangPatterns') this.languagePatterns = d.json; 25 | if (d.name==='iso6391') this.iso6391 = d.json; 26 | if (d.name==='iso6392') this.iso6392 = d.json; 27 | if (d.name==='iso15924') this.iso15924 = d.json; 28 | if (d.name==='iso6392to6391') this.iso6392to6391 = d.json; 29 | }.bind(this)); 30 | 31 | // turn all the strings into real regexes right now for later 32 | this.languagePatterns.forEach(function(p){ 33 | p.regex = new RegExp(p.regex, "ig"); 34 | }); 35 | }, 36 | error: function (XMLHttpRequest, textStatus, errorThrown) { 37 | bfelog.addMsg(new Error(), 'ERROR', 'FAILED to load external source: ' + config.literalLangDataUrl); 38 | bfelog.addMsg(new Error(), 'ERROR', 'Request status: ' + textStatus + '; Error msg: ' + errorThrown); 39 | } 40 | }); 41 | } 42 | 43 | 44 | // sent text from the literal input to try detect lang and script 45 | exports.identifyLangScript = function(text){ 46 | 47 | var bestGuess = []; 48 | 49 | this.languagePatterns.forEach(function(p){ 50 | 51 | var count = ((text || '').match(p.regex) || []).length; 52 | if (count>0){ 53 | bestGuess.push([p.name, count]) 54 | } 55 | 56 | 57 | 58 | }) 59 | // sort them to get the best one, the one with most hits 60 | bestGuess.sort(function(a, b) { 61 | return b[1] - a[1]; 62 | }); 63 | 64 | // if we got one use it 65 | if (bestGuess.length>0){ 66 | var usePattern = this.languagePatterns.filter(function(p){return p.name === bestGuess[0][0]})[0]; 67 | if (usePattern.script === 'Latn'){ 68 | usePattern.script = null; 69 | } 70 | return {script: usePattern.script, iso6391: usePattern['iso639-1']} 71 | }else{ 72 | return {script: null, iso6391: null} 73 | 74 | } 75 | 76 | 77 | } 78 | 79 | exports.characterShortcuts = function (chr) { 80 | //chr + meta key (aka ⊞ Win) + alt key 81 | var charMap = [ 82 | {"g": {name: "Soft Sign", val: "ʹ", code:0x02b9 }}, 83 | {"G": {name: "Hard Sign", val: "ʺ", code:0x02ba }}, 84 | {"k": {name: "Ligature Left", val: "", code:0xfe20 }}, 85 | {"l": {name: "Ligature Right", val: "", code:0xfe21 }}, 86 | {".": {name: "Breve", val: "", code:0x0306 }}, 87 | {"N": {name: "Dot above", val: "", code:0x0307 }}, 88 | {"f": {name: "Macron", val: "", code:0x0304 }}, 89 | {"m": {name: "Umlaut", val: "", code:0x0308 }}, 90 | {"p": {name: "Hachek", val: "", code:0x0161 }}, 91 | {"U": {name: "Dyet upper", val: "Đ", code:0x0110 }}, 92 | {"u": {name: "Dyet lower", val: "đ", code:0x0111 }}, 93 | {"A": {name: "Ya upper", val: "Я", code:0x042F }}, 94 | {"a": {name: "Ya lower", val: "я", code:0x044F }}, 95 | {"I": {name: "Yat upper", val: "Ѣ", code:0x0462 }}, 96 | {"i": {name: "Yat lower", val: "ѣ", code:0x0463 }}, 97 | {"R": {name: "Yu upper", val: "Ю", code:0x042F }}, 98 | {"r": {name: "Yu lower", val: "ю", code:0x0444E }}, 99 | {"T": {name: "Tse upper", val: "Ц", code:0x0426 }}, 100 | {"t": {name: "Tse lower", val: "ц", code:0x0446 }}, 101 | {"o": {name: "Acute", val: "", code:0x0301}}, 102 | {"`": {name: "Grave", val: "", code:0x0300}}, 103 | {"h": {name: "Hook right", val: "", code:0x0328}}, 104 | {"<": {name: "Non-sort beg", val: "˜", code:0x0098}}, 105 | {">": {name: "Non-sort end", val: "œ", code:0x009C}} 106 | ] 107 | 108 | var returnChar = _.find(charMap, chr); 109 | 110 | if(_.isEmpty(returnChar)) { 111 | return "" 112 | } else { 113 | if (!_.isEmpty(returnChar[chr].val)) { 114 | return returnChar[chr].val; 115 | } else { 116 | return String.fromCodePoint(returnChar[chr].code) 117 | } 118 | } 119 | } 120 | 121 | }); 122 | -------------------------------------------------------------------------------- /src/bfelogging.js: -------------------------------------------------------------------------------- 1 | /*eslint no-console: 0*/ 2 | bfe.define('src/bfelogging', ['require', 'exports' ], function(require, exports) { 3 | 4 | var level = "INFO"; 5 | var toConsole = true; 6 | var domain = window.location.protocol + "//" + window.location.host + "/"; 7 | 8 | exports.log = []; 9 | 10 | exports.getLog = function() { 11 | return exports.log; 12 | } 13 | 14 | exports.init = function(config) { 15 | if (config.logging !== undefined) { 16 | if (config.logging.level !== undefined && config.logging.level == "DEBUG") { 17 | level = config.logging.level; 18 | } 19 | if (config.logging.toConsole !== undefined && !config.logging.toConsole) { 20 | toConsole = config.logging.toConsole; 21 | } 22 | } 23 | var msg = "Logging instantiated: level is " + level + "; log to console is set to " + toConsole; 24 | exports.addMsg(new Error(), "INFO", msg); 25 | exports.addMsg(new Error(), "INFO", domain); 26 | }; 27 | 28 | // acceptable ltypes are: INFO, DEBUG, WARN, ERROR 29 | exports.addMsg = function(error, ltype, data, obj) { 30 | if (error.lineNumber === undefined && error.fileName === undefined) { 31 | // Not firefox, so let's try and see if it is chrome 32 | try { 33 | var stack = error.stack.split("\n"); 34 | var fileinfo = stack[1].substring(stack[1].indexOf("(") + 1); 35 | fileinfo = fileinfo.replace(domain, ""); 36 | var infoparts = fileinfo.split(":"); 37 | error.fileName = infoparts[0]; 38 | error.lineNumber = infoparts[1]; 39 | } catch(e) { 40 | // Probably IE. 41 | error.fileName = "unknown"; 42 | error.lineNumber = "?"; 43 | 44 | } 45 | } 46 | error.fileName = error.fileName.replace(domain, ""); 47 | if (level == "INFO" && ltype.match(/INFO|WARN|ERROR/)) { 48 | setMsg(ltype, data, error, obj); 49 | consoleOut(ltype, data, error, obj); 50 | } else if (level == "DEBUG") { 51 | setMsg(ltype, data, error, obj); 52 | consoleOut(ltype, data, error, obj); 53 | } 54 | }; 55 | 56 | function consoleOut(ltype, data, error, obj) { 57 | if (toConsole) { 58 | console.log(error.fileName + ":" + error.lineNumber + " -> " + data); 59 | if (typeof data==="object" || data instanceof Array) { 60 | console.log(data); 61 | } 62 | if (obj !== undefined && (typeof obj==="object" || obj instanceof Array)) { 63 | console.log(obj); 64 | } 65 | } 66 | } 67 | 68 | function setMsg(ltype, data, error, obj) { 69 | var dateTime = new Date(); 70 | var locale = dateTime.toJSON(); 71 | var localestr = dateTime.toLocaleString(); 72 | var entry = {}; 73 | entry.dt = dateTime; 74 | entry.dtLocaleSort = locale; 75 | entry.dtLocaleReadable = localestr; 76 | entry.type = ltype; 77 | entry.fileName = error.fileName; 78 | entry.lineNumber = error.lineNumber; 79 | if (typeof data==="object" || data instanceof Array) { 80 | console.log(typeof data); 81 | console.log(data); 82 | entry.msg = JSON.stringify(data); 83 | } else { 84 | entry.msg = data; 85 | } 86 | if (obj !== undefined && (typeof obj==="object" || obj instanceof Array)) { 87 | entry.obj = JSON.stringify(obj); 88 | } 89 | exports.log.push(entry); 90 | } 91 | 92 | }); -------------------------------------------------------------------------------- /src/bfelookups.js: -------------------------------------------------------------------------------- 1 | bfe.define('src/lookups/lcnames', ['require', 'exports', 'src/lookups/lcshared', 'src/lookups/lcshared_suggest2', 'src/bfelogging'], function (require, exports) { 2 | var lcshared = require('src/lookups/lcshared'); 3 | var suggest2 = require('src/lookups/lcshared_suggest2'); 4 | var bfelog = require('src/bfelogging'); 5 | var cache = {}; 6 | 7 | // This var is required because it is used as an identifier. 8 | exports.scheme = 'http://id.loc.gov/authorities/names'; 9 | 10 | exports.source = function (query, processSync, processAsync, formobject) { 11 | // console.log(JSON.stringify(formobject.store)); 12 | 13 | var triples = formobject.store; 14 | 15 | var type = ''; 16 | var hits = _.where(triples, { 17 | 's': formobject.defaulturi, 18 | 'p': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' 19 | }); 20 | if (hits[0] !== undefined) { 21 | type = hits[0].o; 22 | } 23 | // console.log("type is " + type); 24 | 25 | var scheme = exports.scheme; 26 | 27 | var rdftype = lcshared.rdfType(type); 28 | 29 | var q = ''; 30 | if (scheme !== '' && rdftype !== '') { 31 | q = '&cs:' + scheme + '&rdftype=' + rdftype; 32 | } else if (rdftype !== '') { 33 | q = '&rdftype=' + rdftype; 34 | } else if (scheme !== '') { 35 | q = '&cs:' + scheme; 36 | } 37 | if (q !== '') { 38 | q = '(' + query + ' OR ' + query + '* OR *' + query + '*)' + q; 39 | } else { 40 | q = '(' + query + ' OR ' + query + '* OR *' + query + '*)'; 41 | } 42 | // console.log('q is ' + q); 43 | q = encodeURI(q); 44 | 45 | if (cache[q]) { 46 | processSync(cache[q]); 47 | return; 48 | } 49 | if (typeof this.searching !== 'undefined') { 50 | clearTimeout(this.searching); 51 | processSync([]); 52 | } 53 | 54 | this.searching = setTimeout(function () { 55 | if (query.length > 2 && query.substr(0, 1) != '?' && !query.match(/^[Nn][A-z\s]{0,1}\d/)) { 56 | var suggestquery = query.normalize(); 57 | bfelog.addMsg(new Error(), 'INFO',query); 58 | if (rdftype !== '') { suggestquery += '&rdftype=' + rdftype.replace('rdftype:', ''); } 59 | 60 | var u = exports.scheme + '/suggest2/?q=' + suggestquery + '&count=50'; 61 | u = u.replace(/^(http:)/,""); 62 | $.ajax({ 63 | url: u, 64 | dataType: 'jsonp', 65 | success: function (data) { 66 | var parsedlist = suggest2.processSuggestions(data, query); 67 | cache[q] = parsedlist; 68 | return processAsync(parsedlist); 69 | } 70 | }); 71 | } else if (query.length > 2) { 72 | if (query.match(/^[Nn][A-z\s]{0,1}\d/)){ 73 | q = query.replace(/\s+/g,'').normalize(); 74 | } 75 | u = 'http://id.loc.gov/search/?format=jsonp&start=1&count=50&q=' + q.replace('?', ''); 76 | u = u.replace(/^(http:)/,""); 77 | $.ajax({ 78 | url: u, 79 | dataType: 'jsonp', 80 | success: function (data) { 81 | var parsedlist = lcshared.processATOM(data, query); 82 | cache[q] = parsedlist; 83 | return processAsync(parsedlist); 84 | } 85 | }); 86 | } else { 87 | return []; 88 | } 89 | }, 300); // 300 ms 90 | }; 91 | 92 | /* 93 | 94 | subjecturi hasAuthority selected.uri 95 | subjecturi bf:label selected.value 96 | */ 97 | exports.getResource = lcshared.getResource; 98 | }); 99 | 100 | 101 | bfe.define('src/lookups/lcsubjects', ['require', 'exports', 'src/lookups/lcshared', 'src/lookups/lcshared_suggest2', 'src/bfelogging'], function (require, exports) { 102 | var lcshared = require('src/lookups/lcshared'); 103 | var suggest2 = require('src/lookups/lcshared_suggest2'); 104 | var bfelog = require('src/bfelogging'); 105 | var cache = []; 106 | 107 | exports.scheme = 'http://id.loc.gov/authorities/subjects'; 108 | 109 | exports.source = function (query, processSync, processAsync, formobject) { 110 | // console.log(JSON.stringify(formobject.store)); 111 | 112 | var triples = formobject.store; 113 | 114 | var type = ''; 115 | var hits = _.where(triples, { 116 | 's': formobject.defaulturi, 117 | 'p': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' 118 | }); 119 | if (hits[0] !== undefined) { 120 | type = hits[0].o; 121 | } 122 | // console.log("type is " + type); 123 | 124 | var scheme = exports.scheme; 125 | 126 | var rdftype = lcshared.rdfType(type); 127 | 128 | var q = ''; 129 | if (scheme !== '' && rdftype !== '') { 130 | q = '&cs:' + scheme + '&rdftype=' + rdftype; 131 | } else if (rdftype !== '') { 132 | q = '&rdftype=' + rdftype; 133 | } else if (scheme !== '') { 134 | q = '&cs:' + scheme; 135 | } 136 | 137 | if (q !== '') { 138 | q = query.normalize() + '*' + q; 139 | } else { 140 | q = query.normalize(); 141 | } 142 | // console.log('q is ' + q); 143 | //q = encodeURI(q); 144 | 145 | if (cache[q]) { 146 | processSync(cache[q]); 147 | return; 148 | } 149 | if (typeof this.searching !== 'undefined') { 150 | clearTimeout(this.searching); 151 | processSync([]); 152 | } 153 | 154 | this.searching = setTimeout(function () { 155 | if (query.length > 2 && query.substr(0, 1) != '?' && !query.match(/[Ss][A-z\s]{0,2}\d/)) { 156 | var suggestquery = query.normalize(); 157 | if (rdftype !== '') { suggestquery += '&rdftype=' + rdftype.replace('rdftype:', ''); } 158 | 159 | var u = exports.scheme + '/suggest2/?count=20&q=' + suggestquery; 160 | u = u.replace(/^(http:)/,""); 161 | $.ajax({ 162 | url: encodeURI(u), 163 | dataType: 'jsonp', 164 | success: function (data) { 165 | var parsedlist = suggest2.processSuggestions(data, query); 166 | cache[q] = parsedlist; 167 | return processAsync(parsedlist); 168 | } 169 | }); 170 | } else if (query.length > 2) { 171 | if (query.match(/^[Ss][A-z\s]{0,2}\d/)){ 172 | q = query.replace(/\s+/g,'').normalize(); 173 | } 174 | u = 'https://id.loc.gov/search/?format=jsonp&start=1&count=50&q=' + q; 175 | u = u.replace(/^(http:)/,""); 176 | $.ajax({ 177 | url: encodeURI(u), 178 | dataType: 'jsonp', 179 | success: function (data) { 180 | var parsedlist = lcshared.processATOM(data, query); 181 | cache[q] = parsedlist; 182 | return processAsync(parsedlist); 183 | }, 184 | fail: function (err){ 185 | bfelog.addMsg(new Error(), 'INFO',err); 186 | } 187 | }); 188 | } else { 189 | return []; 190 | } 191 | }, 300); // 300 ms 192 | }; 193 | 194 | /* 195 | 196 | subjecturi hasAuthority selected.uri 197 | subjecturi bf:label selected.value 198 | */ 199 | exports.getResource = lcshared.getResource; 200 | }); 201 | bfe.define('src/lookups/lcgenreforms', ['require', 'exports', 'src/lookups/lcshared_suggest2', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 202 | var lcshared = require('src/lookups/lcshared'); 203 | var suggest2 = require('src/lookups/lcshared_suggest2'); 204 | var bfelog = require('src/bfelogging'); 205 | var cache = []; 206 | 207 | exports.scheme = 'http://id.loc.gov/authorities/genreForms'; 208 | 209 | exports.source = function (query, processSync, processAsync, formobject) { 210 | bfelog.addMsg(new Error(), 'INFO', query); 211 | return suggest2.suggest2Query(query, cache, exports.scheme, processSync, processAsync, formobject); 212 | }; 213 | 214 | exports.getResource = lcshared.getResource; 215 | }); 216 | 217 | bfe.define('src/lookups/rdaformatnotemus', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 218 | var lcshared = require('src/lookups/lcshared'); 219 | var suggest1 = require('src/lookups/lcshared_suggest1'); 220 | var bfelog = require('src/bfelogging'); 221 | var cache = []; 222 | exports.scheme = 'http://rdaregistry.info/termList/FormatNoteMus'; 223 | 224 | exports.source = function (query, processSync, processAsync) { 225 | bfelog.addMsg(new Error(), 'INFO', query); 226 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 227 | }; 228 | 229 | exports.getResource = lcshared.getResource; 230 | }); 231 | bfe.define('src/lookups/rdamediatype', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 232 | var lcshared = require('src/lookups/lcshared'); 233 | var suggest1 = require('src/lookups/lcshared_suggest1'); 234 | var bfelog = require('src/bfelogging'); 235 | var cache = []; 236 | exports.scheme = 'http://rdaregistry.info/termList/RDAMediaType'; 237 | 238 | exports.source = function (query, processSync, processAsync) { 239 | bfelog.addMsg(new Error(), 'INFO', query); 240 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 241 | }; 242 | 243 | exports.getResource = lcshared.getResource; 244 | }); 245 | bfe.define('src/lookups/rdamodeissue', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 246 | var lcshared = require('src/lookups/lcshared'); 247 | var suggest1 = require('src/lookups/lcshared_suggest1'); 248 | var bfelog = require('src/bfelogging'); 249 | var cache = []; 250 | exports.scheme = 'http://rdaregistry.info/termList/ModeIssue'; 251 | 252 | exports.source = function (query, processSync, processAsync) { 253 | bfelog.addMsg(new Error(), 'INFO', query); 254 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 255 | }; 256 | 257 | exports.getResource = lcshared.getResource; 258 | }); 259 | bfe.define('src/lookups/rdacarriertype', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 260 | var lcshared = require('src/lookups/lcshared'); 261 | var suggest1 = require('src/lookups/lcshared_suggest1'); 262 | var bfelog = require('src/bfelogging'); 263 | var cache = []; 264 | exports.scheme = 'http://rdaregistry.info/termList/RDACarrierType'; 265 | 266 | exports.source = function (query, processSync, processAsync) { 267 | bfelog.addMsg(new Error(), 'INFO', query); 268 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 269 | }; 270 | 271 | exports.getResource = lcshared.getResource; 272 | }); 273 | bfe.define('src/lookups/rdacontenttype', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 274 | var lcshared = require('src/lookups/lcshared'); 275 | var suggest1 = require('src/lookups/lcshared_suggest1'); 276 | var bfelog = require('src/bfelogging'); 277 | var cache = []; 278 | exports.scheme = 'http://rdaregistry.info/termList/RDAContentType'; 279 | 280 | exports.source = function (query, processSync, processAsync) { 281 | bfelog.addMsg(new Error(), 'INFO', query); 282 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 283 | }; 284 | 285 | exports.getResource = lcshared.getResource; 286 | }); 287 | 288 | bfe.define('src/lookups/rdafrequency', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 289 | var lcshared = require('src/lookups/lcshared'); 290 | var suggest1 = require('src/lookups/lcshared_suggest1'); 291 | var bfelog = require('src/bfelogging'); 292 | var cache = []; 293 | exports.scheme = 'http://rdaregistry.info/termList/frequency'; 294 | 295 | exports.source = function (query, processSync, processAsync) { 296 | bfelog.addMsg(new Error(), 'INFO', query); 297 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync); 298 | }; 299 | 300 | exports.getResource = lcshared.getResource; 301 | }); 302 | bfe.define('src/lookups/rdaaspectration', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 303 | var lcshared = require('src/lookups/lcshared'); 304 | var suggest1 = require('src/lookups/lcshared_suggest1'); 305 | var bfelog = require('src/bfelogging'); 306 | var cache = []; 307 | exports.scheme = 'http://rdaregistry.info/termList/AspectRatio'; 308 | 309 | exports.source = function (query, processSync, processAsync) { 310 | bfelog.addMsg(new Error(), 'INFO', query); 311 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 312 | }; 313 | 314 | exports.getResource = lcshared.getResource; 315 | }); 316 | bfe.define('src/lookups/rdageneration', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 317 | var lcshared = require('src/lookups/lcshared'); 318 | var suggest1 = require('src/lookups/lcshared_suggest1'); 319 | var bfelog = require('src/bfelogging'); 320 | var cache = []; 321 | exports.scheme = 'http://rdaregistry.info/termList/RDAGeneration'; 322 | 323 | exports.source = function (query, processSync, processAsync) { 324 | bfelog.addMsg(new Error(), 'INFO', query); 325 | return suggest1.suggest1Query(query, cache, exports.scheme, "RDA", processSync, processAsync, null); 326 | }; 327 | 328 | exports.getResource = lcshared.getResource; 329 | }); 330 | 331 | bfe.define('src/lookups/qagetty', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 332 | var lcshared = require('src/lookups/lcshared'); 333 | var suggest1 = require('src/lookups/lcshared_suggest1'); 334 | var bfelog = require('src/bfelogging'); 335 | var cache = []; 336 | exports.scheme = 'https://lookup.ld4l.org/authorities/search/linked_data/getty_aat_ld4l_cache'; 337 | 338 | exports.source = function (query, processSync, processAsync, formobject) { 339 | bfelog.addMsg(new Error(), 'INFO', query); 340 | return suggest1.suggest1Query(query, cache, exports.scheme, "QA", processSync, processAsync, formobject); 341 | }; 342 | 343 | exports.getResource = lcshared.getResource; 344 | }); 345 | 346 | bfe.define('src/lookups/notetype', ['require', 'exports', 'src/lookups/lcshared_suggest1', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 347 | var lcshared = require('src/lookups/lcshared'); 348 | var suggest1 = require('src/lookups/lcshared_suggest1'); 349 | var bfelog = require('src/bfelogging'); 350 | var cache = []; 351 | exports.scheme = '/api/listconfigs/?where=index.resourceType:noteTypes'; 352 | 353 | exports.source = function (query, processSync, processAsync, formobject) { 354 | bfelog.addMsg(new Error(), 'INFO', query); 355 | return suggest1.suggest1Query(query, cache, exports.scheme, "NoteType", processSync, processAsync, formobject); 356 | }; 357 | 358 | exports.getResource = lcshared.getResource; 359 | }); 360 | -------------------------------------------------------------------------------- /src/css/bfeliterallang.css: -------------------------------------------------------------------------------- 1 | /* 2 | CSS Styles associated with Literal-lang data type interface elements 3 | */ 4 | 5 | 6 | .literal-input-group{ 7 | width: 90%; 8 | } 9 | 10 | .literal-input{ 11 | width:70% !important; 12 | 13 | } 14 | 15 | .literal-select{ 16 | width:10% !important; 17 | padding: 1px; 18 | font-family: monospace; 19 | 20 | } 21 | 22 | .literal-select-error-start{ 23 | border-color: red; 24 | transition: border-color 1s; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/css/bfeusertemplates.css: -------------------------------------------------------------------------------- 1 | 2 | .template-controls{ 3 | display:inline-block; 4 | width:auto; 5 | max-width:400px; 6 | margin-right:10px; 7 | 8 | } 9 | 10 | .template-controls select{ 11 | display: inline-block; 12 | width: 210px; 13 | z-index:10; 14 | position:relative; 15 | 16 | } 17 | #template-controls-actions{ 18 | display: inline-block; 19 | width: 180px; 20 | background-color: whitesmoke; 21 | height: 31px; 22 | right: -185px; 23 | padding: 1px; 24 | border: 1px solid lightgray; 25 | top: -2px; 26 | border-radius: 5px; 27 | z-index: 0; 28 | font-size: 0.75em; 29 | line-height: 25px; 30 | position:relative; 31 | 32 | } 33 | #template-controls-actions button{ 34 | margin-left: 10px; 35 | } 36 | .template-property-hover:hover{ 37 | 38 | background-color: rgba(253, 255, 35, 0.45); 39 | -webkit-box-shadow: 0px 0px 30px 0px rgba(253, 255, 35, 0.67); 40 | -moz-box-shadow: 0px 0px 30px 0px rgba(253, 255, 35, 0.67); 41 | box-shadow: 0px 0px 30px 0px rgba(253, 255, 35, 0.67); 42 | } 43 | 44 | .template-toggle{ 45 | float:left; 46 | } 47 | .template-toggle-hide{ 48 | display:none; 49 | } 50 | 51 | .fa-refresh-animate { 52 | -animation: spin .7s infinite linear; 53 | -webkit-animation: spin2 .7s infinite linear; 54 | } 55 | 56 | @-webkit-keyframes spin2 { 57 | from { -webkit-transform: rotate(0deg);} 58 | to { -webkit-transform: rotate(360deg);} 59 | } 60 | 61 | @keyframes spin { 62 | from { transform: scale(1) rotate(0deg);} 63 | to { transform: scale(1) rotate(360deg);} 64 | } 65 | 66 | .column-title{ 67 | min-width:300px; 68 | } 69 | 70 | .column-contribution{ 71 | min-width:150px; 72 | } 73 | 74 | .column-identifier { 75 | min-width: 80px; 76 | } 77 | -------------------------------------------------------------------------------- /src/css/bootstrap-extra.css: -------------------------------------------------------------------------------- 1 | /* Bootsrap extras/custom */ 2 | .dropdown-submenu { 3 | position: relative; 4 | } 5 | 6 | .dropdown-submenu a::after { 7 | transform: rotate(-90deg); 8 | position: absolute; 9 | right: 6px; 10 | top: .8em; 11 | } 12 | 13 | .dropdown-submenu .dropdown-menu { 14 | top: 0; 15 | left: 100%; 16 | margin-top: -1px; 17 | } 18 | 19 | 20 | /* Change link colors for sandstone theme. */ 21 | a { 22 | color: #325d88; 23 | text-decoration: none; 24 | background-color: transparent; 25 | } 26 | 27 | a:hover { 28 | color: #1d3750; 29 | text-decoration: underline; 30 | } 31 | 32 | /* Sandstone has buttons that are ALL CAPS. This resets that. */ 33 | .btn { 34 | text-transform: none; 35 | } 36 | 37 | /* Change edit button colors for sandstone theme. */ 38 | .btn-warning { 39 | color: #fff; 40 | background-color: #f4bf3c; 41 | border-color: #f4bf3c; 42 | } 43 | 44 | .btn-warning:hover { 45 | color: #fff; 46 | background-color: #ab852a; 47 | border-color: #ab852a; 48 | } 49 | 50 | .btn-warning:focus, .btn-warning.focus { 51 | color: #fff; 52 | background-color: #ab852a; 53 | border-color: #ab852a; 54 | -webkit-box-shadow: 0 0 0 0.2rem rgba(246, 144, 89, 0.5); 55 | box-shadow: 0 0 0 0.2rem rgba(246, 144, 89, 0.5); 56 | } 57 | 58 | .btn-warning.disabled, .btn-warning:disabled { 59 | color: #fff; 60 | background-color: #f47c3c; 61 | border-color: #f47c3c; 62 | } 63 | 64 | .btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, 65 | .show > .btn-warning.dropdown-toggle { 66 | color: #fff; 67 | background-color: #ef5c0e; 68 | border-color: #e3570d; 69 | } 70 | -------------------------------------------------------------------------------- /src/css/typeahead.css: -------------------------------------------------------------------------------- 1 | /* One must skin the typeahead one's self */ 2 | /* https://github.com/twitter/typeahead.js/issues/790 */ 3 | 4 | /* .typeahead, 5 | .tt-query, 6 | .tt-hint{ */ 7 | /* 8 | width: 396px; 9 | height: 30px; 10 | padding: 8px 12px; 11 | font-size: 24px; 12 | line-height: 30px; 13 | border: 2px solid #ccc; 14 | width: 400px; 15 | */ 16 | /* -webkit-border-radius:8px; 17 | -moz-border-radius:8px; 18 | border-radius:8px; 19 | outline:none; 20 | } */ 21 | /* 22 | .typeahead{ 23 | background-color:#fff; 24 | } 25 | 26 | .typeahead:focus{ 27 | border:2px solid #0097cf; 28 | } 29 | 30 | .twitter-typeahead{ 31 | width:100%; 32 | } 33 | 34 | .tt-query{ 35 | -webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); 36 | -moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); 37 | box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075); 38 | } 39 | 40 | .tt-hint{ 41 | color:#999 42 | } 43 | 44 | .tt-dropdown-menu{ */ 45 | /* 46 | width: 422px; 47 | 48 | padding: 8px 0; 49 | border: 1px solid #ccc; 50 | border: 1px solid rgba(0, 0, 0, 0.2); 51 | */ 52 | /* margin-top:0px; 53 | background-color:#fff; 54 | -webkit-border-radius:8px; 55 | -moz-border-radius:8px; 56 | border-radius:8px; 57 | -webkit-box-shadow:0 5px 10px rgba(0, 0, 0, .2); 58 | -moz-box-shadow:0 5px 10px rgba(0, 0, 0, .2); 59 | box-shadow:0 5px 10px rgba(0, 0, 0, .2); 60 | height:300px; 61 | overflow-y:auto; 62 | } 63 | 64 | 65 | .tt-suggestion{ 66 | padding:3px 20px; 67 | */ /* font-size: 18px; */ 68 | /* line-height:16px; 69 | } 70 | 71 | 72 | .tt-suggestion.tt-cursor{ 73 | color:#fff; 74 | background-color:#0097cf; 75 | 76 | } 77 | 78 | .tt-suggestion p{ 79 | margin:0; 80 | } 81 | */ 82 | 83 | .typeahead, 84 | .tt-query, 85 | .tt-hint { 86 | width: 396px; 87 | height: 30px; 88 | padding: 8px 12px; 89 | font-size: 14px; 90 | line-height: 30px; 91 | border: 2px solid #ccc; 92 | -webkit-border-radius: 8px; 93 | -moz-border-radius: 8px; 94 | border-radius: 8px; 95 | outline: none; 96 | } 97 | 98 | .typeahead { 99 | background-color: #fff; 100 | } 101 | 102 | .typeahead:focus { 103 | border: 2px solid #0097cf; 104 | } 105 | 106 | .tt-query { 107 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 108 | -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 109 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); 110 | } 111 | 112 | .tt-hint { 113 | color: #999 114 | } 115 | 116 | .tt-menu { 117 | width: 422px; 118 | margin: 12px 0; 119 | padding: 8px 0; 120 | background-color: #fff; 121 | border: 1px solid #ccc; 122 | border: 1px solid rgba(0, 0, 0, 0.2); 123 | -webkit-border-radius: 8px; 124 | -moz-border-radius: 8px; 125 | border-radius: 8px; 126 | -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); 127 | -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); 128 | box-shadow: 0 5px 10px rgba(0,0,0,.2); 129 | height:500px; 130 | overflow-y:auto; 131 | } 132 | 133 | .tt-suggestion { 134 | padding: 3px 20px; 135 | font-size: 14px; 136 | line-height: 24px; 137 | } 138 | 139 | .tt-suggestion:hover { 140 | cursor: pointer; 141 | color: #fff; 142 | background-color: #0097cf; 143 | } 144 | 145 | /* .tt-suggestion strong { 146 | font-weight: normal; 147 | background-color: lightyellow; 148 | } */ 149 | 150 | .tt-suggestion.tt-cursor { 151 | color: #fff; 152 | background-color: #0097cf; 153 | 154 | } 155 | 156 | .tt-suggestion p { 157 | margin: 0; 158 | } 159 | 160 | .tt-dataset h3{ 161 | margin-top:5px; 162 | margin-bottom:5px; 163 | font-size:18px; 164 | } 165 | 166 | div#save-btn{ 167 | margin-bottom:10px; 168 | } 169 | 170 | .context-sources-list{ 171 | max-height:400px; 172 | overflow-y:auto; 173 | max-width: 500px; 174 | overflow-x:auto; 175 | } 176 | 177 | .add-property-input{ 178 | width:100%; 179 | } 180 | -------------------------------------------------------------------------------- /src/lib/aceconfig.js: -------------------------------------------------------------------------------- 1 | /*eslint no-prototype-builtins: "off"*/ 2 | /* 3 | This file is needed to define the javascript bfe namespace. 4 | @deprecated 0.2.0 does not use dryice. 5 | From: https://github.com/ajaxorg/ace/blob/master/lib/ace/config.js 6 | 7 | */ 8 | 9 | /* ***** BEGIN LICENSE BLOCK ***** 10 | * Distributed under the BSD license: 11 | * 12 | * Copyright (c) 2010, Ajax.org B.V. 13 | * All rights reserved. 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions are met: 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * * Redistributions in binary form must reproduce the above copyright 20 | * notice, this list of conditions and the following disclaimer in the 21 | * documentation and/or other materials provided with the distribution. 22 | * * Neither the name of Ajax.org B.V. nor the 23 | * names of its contributors may be used to endorse or promote products 24 | * derived from this software without specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 27 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 28 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 29 | * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY 30 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 31 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 32 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 33 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | /*eslint no-console: 0*/ 39 | bfe.define('src/lib/aceconfig', ['require', 'exports', 'module' ], function(require, exports, module) { 40 | 41 | var global = (function() { 42 | return this; 43 | })(); 44 | 45 | var options = { 46 | packaged: false, 47 | workerPath: null, 48 | modePath: null, 49 | themePath: null, 50 | basePath: "", 51 | suffix: ".js", 52 | $moduleUrls: {} 53 | }; 54 | 55 | exports.set = function(key, value) { 56 | if (!options.hasOwnProperty(key)) 57 | throw new Error("Unknown config key: " + key); 58 | 59 | options[key] = value; 60 | }; 61 | 62 | // initialization 63 | function init(packaged) { 64 | options.packaged = packaged || require.packaged || module.packaged || (global.define && define.packaged); 65 | 66 | if (!global.document) 67 | return ""; 68 | 69 | var scriptOptions = {}; 70 | var scriptUrl = ""; 71 | 72 | var scripts = document.getElementsByTagName("script"); 73 | for (var i=0; i 2) { 32 | //if (query.match(/^[Nn][A-z\s]{0,1}\d/)){ 33 | //q = query.replace(/\s+/g,'').normalize(); 34 | //} 35 | var u = 'http://id.loc.gov/search/?format=jsonp&start=1&count=50&q=' + q; 36 | $.ajax({ 37 | url: u, 38 | dataType: 'jsonp', 39 | success: function (data) { 40 | var parsedlist = lcshared.processATOM(data, query); 41 | cache[q] = parsedlist; 42 | return processAsync(parsedlist); 43 | } 44 | }); 45 | } else { 46 | return []; 47 | } 48 | }, 300); // 300 ms 49 | }; 50 | 51 | exports.getResource = function (subjecturi, property, selected, process) { 52 | // Unfortunately, we do not know the type at this stage. 53 | 54 | var triples = []; 55 | 56 | var agenturi = selected.uri.replace('authorities/names', 'rwo/agents'); 57 | 58 | var triple = {}; 59 | triple.s = subjecturi; 60 | triple.p = property.propertyURI; 61 | triple.o = agenturi; 62 | triple.otype = 'uri'; 63 | triples.push(triple); 64 | 65 | triple = {}; 66 | triple.s = agenturi; 67 | triple.p = 'http://www.w3.org/2000/01/rdf-schema#label'; 68 | triple.o = selected.value; 69 | triple.otype = 'literal'; 70 | triples.push(triple); 71 | 72 | triple = {}; 73 | triple.s = agenturi; 74 | triple.p = 'http://www.loc.gov/mads/rdf/v1#isIdentifiedByAuthority'; 75 | triple.o = selected.uri; 76 | triple.otype = 'uri'; 77 | triples.push(triple); 78 | 79 | return process(triples, property); 80 | }; 81 | }); -------------------------------------------------------------------------------- /src/lookups/lcshared.js: -------------------------------------------------------------------------------- 1 | bfe.define('src/lookups/lcshared', ['require', 'exports', 'src/bfelogging'], function (require, exports) { 2 | // require('https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js'); 3 | 4 | /* 5 | subjecturi propertyuri selected.uri 6 | selected.uri bf:label selected.value 7 | */ 8 | var bfelog = require('src/bfelogging'); 9 | 10 | exports.getResource = function (subjecturi, property, selected, process) { 11 | var triples = []; 12 | var triple = {}; 13 | if (selected.id == 'literalLookup'){ 14 | triple.s = subjecturi; 15 | triple.p = property.propertyURI; 16 | triple.o = selected.value; 17 | triple.otype = 'literal'; 18 | triples.push(triple); 19 | } else if (selected.id == 'literal'){ 20 | triple.s = subjecturi; 21 | triple.p = 'http://www.w3.org/2000/01/rdf-schema#label'; 22 | triple.o = selected.value; 23 | triple.otype = 'literal'; 24 | triples.push(triple); 25 | } else { 26 | triple.s = subjecturi; 27 | triple.p = property.propertyURI; 28 | triple.o = selected.uri; 29 | triple.otype = 'uri'; 30 | triples.push(triple); 31 | 32 | triple = {}; 33 | triple.s = selected.uri; 34 | triple.p = 'http://www.w3.org/2000/01/rdf-schema#label'; 35 | triple.o = selected.value; 36 | triple.otype = 'literal'; 37 | //triple.olang = 'en'; 38 | triples.push(triple); 39 | } 40 | 41 | return process(triples, property); 42 | }; 43 | 44 | exports.getResourceLabelLookup = function (subjecturi, propertyuri, selected, process) { 45 | var triples = []; 46 | 47 | var triple = {}; 48 | triple.s = subjecturi; 49 | triple.p = propertyuri; 50 | triple.o = selected.uri; 51 | triple.otype = 'uri'; 52 | triples.push(triple); 53 | // add label 54 | var url = selected.uri.replace(/^(http:)/,""); 55 | $.ajax({ 56 | url: url + '.jsonp', 57 | dataType: 'jsonp', 58 | success: function (data) { 59 | data.forEach(function (resource) { 60 | if (resource['@id'] === selected.uri) { 61 | var label = {}; 62 | label.s = selected.uri; 63 | label.otype = 'literal'; 64 | label.p = 'http://www.w3.org/2000/01/rdf-schema#label'; 65 | label.o = resource['http://www.loc.gov/mads/rdf/v1#authoritativeLabel'][0]['@value']; 66 | triples.push(label); 67 | return process(triples); 68 | } 69 | }); 70 | } 71 | }); 72 | }; 73 | 74 | 75 | exports.extractContextData = function(data){ 76 | var results = { source: [], variant : [], uri: data.uri, title: null, contributor:[], date:null, genreForm: null, nodeMap:{}}; 77 | 78 | // if it is in jsonld format 79 | if (data['@graph']){ 80 | data = data['@graph']; 81 | } 82 | 83 | var nodeMap = {}; 84 | 85 | data.forEach(function(n){ 86 | if (n['http://www.loc.gov/mads/rdf/v1#birthDate']){ 87 | nodeMap.birthDate = n['http://www.loc.gov/mads/rdf/v1#birthDate'].map(function(d){ return d['@id']}) 88 | } 89 | if (n['http://www.loc.gov/mads/rdf/v1#birthPlace']){ 90 | nodeMap.birthPlace = n['http://www.loc.gov/mads/rdf/v1#birthPlace'].map(function(d){ return d['@id']}) 91 | } 92 | 93 | if (n['http://www.loc.gov/mads/rdf/v1#associatedLocale']){ 94 | nodeMap.associatedLocale = n['http://www.loc.gov/mads/rdf/v1#associatedLocale'].map(function(d){ return d['@id']}) 95 | } 96 | if (n['http://www.loc.gov/mads/rdf/v1#fieldOfActivity']){ 97 | nodeMap.fieldOfActivity = n['http://www.loc.gov/mads/rdf/v1#fieldOfActivity'].map(function(d){ return d['@id']}) 98 | } 99 | if (n['http://www.loc.gov/mads/rdf/v1#gender']){ 100 | nodeMap.gender = n['http://www.loc.gov/mads/rdf/v1#gender'].map(function(d){ return d['@id']}) 101 | } 102 | if (n['http://www.loc.gov/mads/rdf/v1#occupation']){ 103 | nodeMap.occupation = n['http://www.loc.gov/mads/rdf/v1#occupation'].map(function(d){ return d['@id']}) 104 | } 105 | if (n['http://www.loc.gov/mads/rdf/v1#associatedLanguage']){ 106 | nodeMap.associatedLanguage = n['http://www.loc.gov/mads/rdf/v1#associatedLanguage'].map(function(d){ return d['@id']}) 107 | } 108 | if (n['http://www.loc.gov/mads/rdf/v1#deathDate']){ 109 | nodeMap.deathDate = n['http://www.loc.gov/mads/rdf/v1#deathDate'].map(function(d){ return d['@id']}) 110 | } 111 | if (n['http://www.loc.gov/mads/rdf/v1#hasBroaderAuthority']){ 112 | nodeMap.hasBroaderAuthority = n['http://www.loc.gov/mads/rdf/v1#hasBroaderAuthority'].map(function(d){ return d['@id']}) 113 | } 114 | if (n['http://www.loc.gov/mads/rdf/v1#hasNarrowerAuthority']){ 115 | nodeMap.hasNarrowerAuthority = n['http://www.loc.gov/mads/rdf/v1#hasNarrowerAuthority'].map(function(d){ return d['@id']}) 116 | } 117 | if (n['http://www.loc.gov/mads/rdf/v1#see']){ 118 | nodeMap.see = n['http://www.loc.gov/mads/rdf/v1#see'].map(function(d){ return d['@id']}) 119 | } 120 | if (n['http://www.loc.gov/mads/rdf/v1#hasRelatedAuthority']){ 121 | nodeMap.hasRelatedAuthority = n['http://www.loc.gov/mads/rdf/v1#hasRelatedAuthority'].map(function(d){ return d['@id']}) 122 | } 123 | 124 | }) 125 | // pull out the labels 126 | data.forEach(function(n){ 127 | 128 | // loop through all the possible types of row 129 | Object.keys(nodeMap).forEach(function(k){ 130 | if (!results.nodeMap[k]) { results.nodeMap[k] = [] } 131 | // loop through each uri we have for this type 132 | nodeMap[k].forEach(function(uri){ 133 | if (n['@id'] && n['@id'] == uri){ 134 | 135 | if (n['http://www.loc.gov/mads/rdf/v1#authoritativeLabel']){ 136 | n['http://www.loc.gov/mads/rdf/v1#authoritativeLabel'].forEach(function(val){ 137 | if (val['@value']){ 138 | results.nodeMap[k].push(val['@value']); 139 | } 140 | }) 141 | } 142 | if (n['http://www.w3.org/2000/01/rdf-schema#label']){ 143 | n['http://www.w3.org/2000/01/rdf-schema#label'].forEach(function(val){ 144 | if (val['@value']){ 145 | results.nodeMap[k].push(val['@value']); 146 | } 147 | }) 148 | } 149 | } 150 | }) 151 | }) 152 | }) 153 | 154 | data.forEach(function(n){ 155 | 156 | var citation = ''; 157 | var variant = ''; 158 | 159 | if (n['http://www.loc.gov/mads/rdf/v1#citationSource']) { 160 | citation = citation + n['http://www.loc.gov/mads/rdf/v1#citationSource'].map(function (v) { return v['@value'] + ' '; }) 161 | } 162 | if (n['http://www.loc.gov/mads/rdf/v1#citationNote']) { 163 | citation = citation + n['http://www.loc.gov/mads/rdf/v1#citationNote'].map(function (v) { return v['@value'] + ' '; }) 164 | } 165 | if (n['http://www.loc.gov/mads/rdf/v1#citationStatus']) { 166 | citation = citation + n['http://www.loc.gov/mads/rdf/v1#citationStatus'].map(function (v) { return v['@value'] + ' '; }) 167 | } 168 | if (n['http://www.loc.gov/mads/rdf/v1#variantLabel']) { 169 | variant = variant + n['http://www.loc.gov/mads/rdf/v1#variantLabel'].map(function (v) { return v['@value'] + ' '; }) 170 | } 171 | citation = citation.trim() 172 | variant = variant.trim() 173 | if (variant != ''){ results.variant.push(variant)} 174 | if (citation != ''){ results.source.push(citation)} 175 | 176 | 177 | if (n['@type'] && n['@type'] == 'http://id.loc.gov/ontologies/bibframe/Title'){ 178 | if (n['bibframe:mainTitle']){ 179 | results.title = n['bibframe:mainTitle'] 180 | } 181 | } 182 | if (n['@type'] && (n['@type'] == 'http://id.loc.gov/ontologies/bibframe/Agent' || n['@type'].indexOf('http://id.loc.gov/ontologies/bibframe/Agent') > -1 )){ 183 | if (n['bflc:name00MatchKey']){ 184 | results.contributor.push(n['bflc:name00MatchKey']); 185 | } 186 | } 187 | if (n['bibframe:creationDate'] && n['bibframe:creationDate']['@value']){ 188 | results.date = n['bibframe:creationDate']['@value']; 189 | } 190 | if (n['@type'] && n['@type'] == 'http://id.loc.gov/ontologies/bibframe/GenreForm'){ 191 | if (n['bibframe:mainTitle']){ 192 | results.genreForm = n['rdf-schema:label']; 193 | } 194 | } 195 | 196 | if (n['http://www.loc.gov/mads/rdf/v1#isMemberOfMADSCollection']) { 197 | results.nodeMap.collections = []; 198 | n['http://www.loc.gov/mads/rdf/v1#isMemberOfMADSCollection'].forEach(function(val){ 199 | if (val['@id']) { 200 | var coll_label_parts = val['@id'].split("_"); 201 | var coll_label = coll_label_parts[1]; 202 | if (coll_label_parts.length > 2) { 203 | coll_label = coll_label_parts.slice(1).join(' '); 204 | } 205 | if (coll_label != "LCNAF" && coll_label.match(/[A-Z]{4}|[A-Z][a-z]+/g)) { 206 | coll_label = coll_label.match(/[A-Z]{4}|[A-Z][a-z]+/g).join(" "); 207 | } 208 | results.nodeMap.collections.push(coll_label); 209 | } 210 | }) 211 | } 212 | 213 | }); 214 | return results; 215 | } 216 | 217 | exports.fetchContextData = function(uri,callback){ 218 | 219 | if (uri.indexOf('id.loc.gov/') > -1 && uri.match(/(authorities|vocabulary)/)) { 220 | var jsonuri = uri + '.madsrdf_raw.jsonld'; 221 | } else { 222 | jsonuri = uri + '.jsonld'; 223 | } 224 | 225 | if (uri.indexOf('id.loc.gov') > -1) { 226 | jsonuri = jsonuri.replace(/^(http:)/,"https:"); 227 | } 228 | 229 | $.ajax({ 230 | url: jsonuri, 231 | dataType: 'json', 232 | success: function (data) { 233 | 234 | var id = uri.split('/')[uri.split('/').length-1]; 235 | data.uri = uri; 236 | 237 | var d = JSON.stringify(exports.extractContextData(data)); 238 | sessionStorage.setItem(id, d); 239 | if (callback){ 240 | callback(d) 241 | } 242 | } 243 | }); 244 | }; 245 | 246 | exports.processATOM = function (atomjson, query) { 247 | var typeahead_source = []; 248 | for (var k in atomjson) { 249 | if (atomjson[k][0] == 'atom:entry') { 250 | var t = ''; 251 | var u = ''; 252 | var source = ''; 253 | var d = ''; 254 | for (var e in atomjson[k]) { 255 | if (atomjson[k][e][0] == 'atom:title') { 256 | t = atomjson[k][e][2]; 257 | } 258 | if (atomjson[k][e][0] == 'atom:link') { 259 | u = atomjson[k][e][1].href; 260 | source = u.substr(0, u.lastIndexOf('/')); 261 | var id = u.replace(/.+\/(.+)/, '$1'); 262 | d = t + ' (' + id + ')'; 263 | } 264 | if (t !== '' && u !== '') { 265 | typeahead_source.push({ 266 | uri: u, 267 | source: source, 268 | value: t, 269 | display: d 270 | }); 271 | break; 272 | } 273 | bfelog.addMsg(new Error(), 'INFO', typeahead_source); 274 | } 275 | } 276 | } 277 | if (typeahead_source.length === 0) { 278 | typeahead_source[0] = { 279 | uri: '', 280 | display: '[No suggestions found for ' + query + '.]' 281 | }; 282 | } 283 | // console.log(typeahead_source); 284 | return typeahead_source; 285 | }; 286 | 287 | exports.rdfType = function(type){ 288 | var rdftype = ''; 289 | if (type == 'http://www.loc.gov/mads/rdf/v1#PersonalName' || type == 'http://id.loc.gov/ontologies/bibframe/Person') { 290 | rdftype = 'rdftype:PersonalName'; 291 | } else if (type == 'http://id.loc.gov/ontologies/bibframe/Topic') { 292 | rdftype = '(rdftype:Topic OR rdftype:ComplexSubject)'; 293 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Place' || type == 'http://id.loc.gov/ontologies/bibframe/Place' || type == 'http://www.loc.gov/mads/rdf/v1#Geographic') { 294 | rdftype = 'rdftype:Geographic'; 295 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Temporal'){ 296 | rdftype= 'rdftype:Temporal'; 297 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Organization' || type == 'http://id.loc.gov/ontologies/bibframe/Organization') { 298 | rdftype = 'rdftype:CorporateName'; 299 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Family' || type == 'http://id.loc.gov/ontologies/bibframe/Family') { 300 | rdftype = "rdftype:FamilyName"; 301 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Meeting' || type == 'http://id.loc.gov/ontologies/bibframe/Meeting') { 302 | rdftype = 'rdftype:ConferenceName'; 303 | } else if (type == 'http://www.loc.gov/mads/rdf/v1#Jurisdiction' || type == 'http://id.loc.gov/ontologies/bibframe/Jurisdiction') { 304 | rdftype = 'rdftype:Geographic'; 305 | } else if (type == 'http://id.loc.gov/ontologies/bibframe/GenreForm' || type == 'http://www.loc.gov/mads/rdf/v1#GenreForm') { 306 | rdftype = 'rdftype:GenreForm'; 307 | } else if (type == 'http://id.loc.gov/ontologies/bibframe/Role') { 308 | rdftype = 'rdftype:Role'; 309 | } 310 | return rdftype; 311 | } 312 | 313 | }); -------------------------------------------------------------------------------- /src/lookups/lcshared_suggest1.js: -------------------------------------------------------------------------------- 1 | bfe.define('src/lookups/lcshared_suggest1', ['require', 'exports', 'src/bfelogging'], function (require, exports) { 2 | // require('https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js'); 3 | 4 | /* 5 | subjecturi propertyuri selected.uri 6 | selected.uri bf:label selected.value 7 | */ 8 | var bfelog = require('src/bfelogging'); 9 | 10 | var addLiteralOption = function (data, query){ 11 | data.push({uri: "_:b1", id: "literal", value: query, display: query + "(Literal Value)"}); 12 | }; 13 | 14 | processJSONLDSuggestions = function (suggestions, query, scheme) { 15 | var typeahead_source = []; 16 | if (suggestions['@graph'] !== undefined) { 17 | for (var s = 0; s < suggestions['@graph'].length; s++) { 18 | if (suggestions['@graph'][s].inScheme !== undefined) { 19 | if (suggestions['@graph'][s]['@type'] === 'Concept' && suggestions['@graph'][s].inScheme === scheme) { 20 | if (suggestions['@graph'][s].prefLabel.en.length !== undefined) { 21 | var l = suggestions['@graph'][s].prefLabel.en; 22 | // break; 23 | // var l = suggestions['@graph'][s]['prefLabel']['@value']; 24 | } 25 | var u = suggestions['@graph'][s]['@id']; 26 | typeahead_source.push({ 27 | uri: u, 28 | value: l 29 | }); 30 | } 31 | } 32 | } 33 | } 34 | if (typeahead_source.length === 0) { 35 | typeahead_source[0] = { 36 | uri: '', 37 | value: '[No suggestions found for ' + query + '.]' 38 | }; 39 | } 40 | addLiteralOption(typeahead_source, query); 41 | return typeahead_source; 42 | }; 43 | 44 | processQASuggestions = function (suggestions, query) { 45 | var typeahead_source = []; 46 | if (suggestions[1] !== undefined) { 47 | for (var s = 0; s < suggestions.length; s++) { 48 | var l = suggestions[s]["label"]; 49 | var u = suggestions[s]["uri"]; 50 | var id = suggestions[s]["id"]; 51 | var d = l + ' (' + id + ')'; 52 | 53 | typeahead_source.push({ 54 | uri: u, 55 | id: id, 56 | value: l, 57 | display: d 58 | }); 59 | } 60 | } 61 | if (typeahead_source.length === 0) { 62 | typeahead_source[0] = { 63 | uri: '', 64 | display: '[No suggestions found for ' + query + '.]' 65 | }; 66 | } 67 | addLiteralOption(typeahead_source, query); 68 | 69 | return typeahead_source; 70 | }; 71 | 72 | processNoteTypeSuggestions = function (suggestions, query) { 73 | var typeahead_source = []; 74 | var substrMatch = new RegExp('^' + query, 'i'); 75 | if (suggestions[0].json !== undefined) { 76 | for (var s = 0; s < suggestions[0].json.length; s++) { 77 | var l = suggestions[0].json[s]; 78 | 79 | if(substrMatch.test(l) || _.isEmpty(query)){ 80 | typeahead_source.push({ 81 | uri: "", 82 | id: 'literalLookup', 83 | value: l, 84 | display: l 85 | }); 86 | } 87 | } 88 | } 89 | if (typeahead_source.length === 0) { 90 | typeahead_source[0] = { 91 | uri: '', 92 | display: '[No suggestions found for ' + query + '.]' 93 | }; 94 | } 95 | addLiteralOption(typeahead_source, query); 96 | 97 | return typeahead_source; 98 | }; 99 | 100 | processSuggestions = function (suggestions, query) { 101 | var typeahead_source = []; 102 | if (suggestions[1] !== undefined) { 103 | for (var s = 0; s < suggestions[1].length; s++) { 104 | var l = suggestions[1][s]; 105 | var u = suggestions[3][s]; 106 | var id = u.replace(/.+\/(.+)/, '$1'); 107 | if (id.length==32){ 108 | var d = l; 109 | }else{ 110 | d = l + ' (' + id + ')'; 111 | } 112 | 113 | if (suggestions.length === 5) { 114 | var i = suggestions[4][s]; 115 | var li = l + ' (' + i + ')'; 116 | } else { 117 | li = l; 118 | } 119 | 120 | typeahead_source.push({ 121 | uri: u, 122 | id: id, 123 | value: li, 124 | display: d 125 | }); 126 | } 127 | } 128 | if (typeahead_source.length === 0) { 129 | typeahead_source[0] = { 130 | uri: '', 131 | display: '[No suggestions found for ' + query + '.]' 132 | }; 133 | } 134 | addLiteralOption(typeahead_source, query); 135 | 136 | return typeahead_source; 137 | }; 138 | 139 | exports.suggest1Query = function (query, cache, scheme, resultType, processSync, processAsync, formobject) { 140 | bfelog.addMsg(new Error(), 'INFO','q is ' + query); 141 | 142 | if (!_.isEmpty(formobject)){ 143 | var triples = formobject.store; 144 | 145 | var type = ''; 146 | var hits = _.where(triples, { 147 | 'p': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' 148 | }); 149 | if (hits[0] !== undefined) { 150 | type = hits[0].o; 151 | } 152 | 153 | var rdftype = exports.rdfType(type); 154 | var q = ''; 155 | if (scheme !== '' && rdftype !== '') { 156 | q = 'cs:' + scheme + ' AND ' + rdftype; 157 | } else if (rdftype !== '') { 158 | q = rdftype; 159 | } else if (scheme !== '') { 160 | q = 'cs:' + scheme; 161 | } 162 | 163 | if (q !== '') { 164 | q = q + ' AND ' + query.replace('?', '').normalize() + '*'; 165 | } else { 166 | q = query.normalize(); 167 | } 168 | } else { 169 | q = query.normalize(); 170 | } 171 | 172 | if (cache[q]) { 173 | processSync(cache[q]); 174 | return; 175 | } 176 | if (typeof this.searching !== 'undefined') { 177 | clearTimeout(this.searching); 178 | processSync([]); 179 | } 180 | this.searching = setTimeout(function () { 181 | if (resultType == "NoteType") { 182 | u = config.url + "/profile-edit/server/whichrt?uri=" + scheme; 183 | $.ajax({ 184 | url: encodeURI(u), 185 | dataType: 'json', 186 | success: function (data) { 187 | var parsedlist = processNoteTypeSuggestions(data, query); 188 | cache[q] = parsedlist; 189 | return processAsync(parsedlist); 190 | } 191 | }); 192 | } else if ((query === '' || query === ' ') && resultType == "ID" && !(scheme.match(/resources\/[works|instances]/) || scheme.match(/authorities/) || scheme.match(/entities/))) { 193 | var u = scheme + '/suggest/?count=100&q='; 194 | u = u.replace(/^(http:)/,""); 195 | $.ajax({ 196 | url: encodeURI(u), 197 | dataType: 'jsonp', 198 | success: function (data) { 199 | var parsedlist = processSuggestions(data, ''); 200 | return processAsync(parsedlist); 201 | } 202 | }); 203 | } else if (query.length > 2 && query.substr(0, 1) == '?' && resultType == "ID") { 204 | u = 'http://id.loc.gov/search/?format=jsonp&start=1&count=50&q=' + q; 205 | u = u.replace(/^(http:)/,""); 206 | $.ajax({ 207 | url: encodeURI(u), 208 | dataType: 'jsonp', 209 | success: function (data) { 210 | var parsedlist = exports.processATOM(data, query); 211 | cache[q] = parsedlist; 212 | return processAsync(parsedlist); 213 | } 214 | }); 215 | } else if (query.length >= 2 && resultType == "ID" && query.match(/^[A-Za-z\s]{0,3}[0-9]{3,}$/)) { 216 | if (query.match(/^[0-9]{3,}$/)) { 217 | u = scheme + '/suggest/lccn/' + query.replace(/\s/g,''); 218 | } else { 219 | u = scheme + '/suggest/token/' + query.replace(/\s/g,''); 220 | } 221 | u = u.replace(/^(http:)/,""); 222 | $.ajax({ 223 | url: encodeURI(u), 224 | dataType: 'json', 225 | success: function (data) { 226 | var parsedlist = processSuggestions(data, query); 227 | cache[q] = parsedlist; 228 | return processAsync(parsedlist); 229 | }, 230 | fail: function (err){ 231 | bfelog.addMsg(new Error(), 'INFO',err); 232 | } 233 | }); 234 | } else if (query.length >= 1 && !query.match(/^[A-Za-z]{0,2}[0-9]{2,}$/)) { 235 | if (resultType == "ID"){ 236 | u = scheme + '/suggest/?count=50&q=' + query; 237 | u = u.replace(/^(http:)/,""); 238 | $.ajax({ 239 | url: encodeURI(u), 240 | dataType: 'jsonp', 241 | success: function (data) { 242 | var parsedlist; 243 | 244 | if (resultType == "QA"){ 245 | parsedlist = processQASuggestions(data, query); 246 | } else if (resultType == "RDA") { 247 | parsedlist = processJSONLDSuggestions(data, query); 248 | } else { 249 | parsedlist = processSuggestions(data, query); 250 | } 251 | 252 | cache[q] = parsedlist; 253 | return processAsync(parsedlist); 254 | } 255 | }); 256 | } else { 257 | u = "/profile-edit/server/whichrt?uri=" + scheme + '?q=' + query; 258 | $.ajax({ 259 | url: encodeURI(u), 260 | dataType: 'json', 261 | success: function (data) { 262 | var parsedlist; 263 | 264 | if (resultType == "QA"){ 265 | parsedlist = processQASuggestions(data, query); 266 | } else if (resultType == "RDA") { 267 | parsedlist = processJSONLDSuggestions(data, query); 268 | } else { 269 | return []; 270 | } 271 | cache[q] = parsedlist; 272 | return processAsync(parsedlist); 273 | } 274 | }); 275 | } 276 | } 277 | }, 300); // 300 ms 278 | }; 279 | }); -------------------------------------------------------------------------------- /src/lookups/lcshared_suggest2.js: -------------------------------------------------------------------------------- 1 | bfe.define('src/lookups/lcshared_suggest2', ['require', 'exports', 'src/lookups/lcshared', 'src/bfelogging'], function (require, exports) { 2 | // require('https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js'); 3 | 4 | /* 5 | subjecturi propertyuri selected.uri 6 | selected.uri bf:label selected.value 7 | */ 8 | var bfelog = require('src/bfelogging'); 9 | 10 | var addLiteralOption = function (data, query){ 11 | data.push({uri: "_:b1", id: "literal", value: query, display: query + "(Literal Value)"}); 12 | }; 13 | 14 | exports.processSuggestions = function (suggestions, query) { 15 | bfelog.addMsg(new Error(), 'DEBUG','Processing suggestions: ', suggestions); 16 | var typeahead_source = []; 17 | if (suggestions.count !== undefined) { 18 | for (var s = 0; s < suggestions.hits.length; s++) { 19 | var hit = suggestions.hits[s]; 20 | 21 | var l = hit.suggestLabel; 22 | var al = hit.aLabel; 23 | var u = hit.uri; 24 | var id = u.replace(/.+\/(.+)/, '$1'); 25 | var d = l + ' [' + id + ']'; 26 | if (id.length==32){ 27 | d = l; 28 | } 29 | li = al; 30 | 31 | // What the heck is this? 32 | /* 33 | if (suggestions.length === 5) { 34 | var i = suggestions[4][s]; 35 | var li = l + ' (' + i + ')'; 36 | } else { 37 | li = l; 38 | } 39 | */ 40 | 41 | typeahead_source.push({ 42 | uri: u, 43 | id: id, 44 | value: li, 45 | display: d 46 | }); 47 | } 48 | } 49 | 50 | if (typeahead_source.length === 0) { 51 | typeahead_source[0] = { 52 | uri: '', 53 | display: '[No suggestions found for ' + query + '.]' 54 | }; 55 | } 56 | addLiteralOption(typeahead_source, query); 57 | return typeahead_source; 58 | }; 59 | 60 | exports.suggest2Query = function (query, cache, scheme, processSync, processAsync, formobject) { 61 | bfelog.addMsg(new Error(), 'DEBUG','Suggest2 query'); 62 | bfelog.addMsg(new Error(), 'DEBUG','q is ' + query); 63 | 64 | var lcshared = require('src/lookups/lcshared'); 65 | if (!_.isEmpty(formobject)){ 66 | var triples = formobject.store; 67 | 68 | var type = ''; 69 | var hits = _.where(triples, { 70 | 'p': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' 71 | }); 72 | if (hits[0] !== undefined) { 73 | type = hits[0].o; 74 | } 75 | 76 | var rdftype = lcshared.rdfType(type); 77 | var q = ''; 78 | if (scheme !== '' && rdftype !== '') { 79 | q = 'cs:' + scheme + ' AND ' + rdftype; 80 | } else if (rdftype !== '') { 81 | q = rdftype; 82 | } else if (scheme !== '') { 83 | q = 'cs:' + scheme; 84 | } 85 | 86 | if (q !== '') { 87 | q = q + ' AND ' + query.replace('?', '').normalize() + '*'; 88 | } else { 89 | q = query.replace('?', '').normalize(); 90 | } 91 | } else { 92 | q = query.replace('?', '').normalize(); 93 | } 94 | 95 | if (cache[q]) { 96 | processSync(cache[q]); 97 | return; 98 | } 99 | if (typeof this.searching !== 'undefined') { 100 | clearTimeout(this.searching); 101 | processSync([]); 102 | } 103 | this.searching = setTimeout(function () { 104 | if (query === '' || query === ' ') { 105 | // If the query is empty or a simple space. 106 | var u = scheme + '/suggest2/?count=50&q='; 107 | u = u.replace(/^(http:)/,""); 108 | $.ajax({ 109 | url: encodeURI(u), 110 | dataType: 'jsonp', 111 | success: function (data) { 112 | var parsedlist = exports.processSuggestions(data, ''); 113 | return processAsync(parsedlist); 114 | } 115 | }); 116 | } else if (query.length > 2 && query.substr(0, 1) == '?') { 117 | // If the search string begins with a question mark. 118 | u = scheme + '/suggest2/?q=' + q + '&searchtype=keyword&count=50'; 119 | console.log(u); 120 | u = u.replace(/^(http:)/,""); 121 | $.ajax({ 122 | url: encodeURI(u), 123 | dataType: 'jsonp', 124 | success: function (data) { 125 | var parsedlist = exports.processSuggestions(data, query); 126 | cache[q] = parsedlist; 127 | return processAsync(parsedlist); 128 | } 129 | }); 130 | } else if ( 131 | query.length >= 2 && 132 | ( query.match(/^[A-Za-z\s]{0,3}[0-9]{3,}$/) || query.match(/^[A-Za-z]{0,2}[0-9]{2,}$/) ) 133 | ) { 134 | if ( query.match(/^[0-9]{3,}$/) || query.match(/^[A-Za-z]{0,2}[0-9]{2,}$/) ) { 135 | u = scheme + '/suggest/lccn/' + query.replace(/\s/g,''); 136 | } else { 137 | u = scheme + '/suggest/token/' + query.replace(/\s/g,''); 138 | } 139 | u = u.replace(/^(http:)/,""); 140 | $.ajax({ 141 | url: encodeURI(u), 142 | dataType: 'json', 143 | success: function (data) { 144 | var parsedlist = exports.processSuggestions(data, query); 145 | cache[q] = parsedlist; 146 | return processAsync(parsedlist); 147 | }, 148 | fail: function (err){ 149 | bfelog.addMsg(new Error(), 'INFO',err); 150 | } 151 | }); 152 | } else if (query.length >= 1) { 153 | u = scheme + '/suggest2/?count=50&q=' + query; 154 | u = u.replace(/^(http:)/,""); 155 | $.ajax({ 156 | url: encodeURI(u), 157 | dataType: 'jsonp', 158 | success: function (data) { 159 | var parsedlist = exports.processSuggestions(data, query); 160 | cache[q] = parsedlist; 161 | return processAsync(parsedlist); 162 | } 163 | }); 164 | } 165 | }, 300); // 300 ms 166 | } 167 | 168 | }); -------------------------------------------------------------------------------- /src/lookups/names-preprod.js: -------------------------------------------------------------------------------- 1 | bfe.define('src/lookups/lcnames-preprod', ['require', 'exports', 'src/lookups/lcshared', 'src/lookups/lcshared_suggest2', 'src/bfelogging'], function (require, exports) { 2 | var lcshared = require('src/lookups/lcshared'); 3 | var suggest2 = require('src/lookups/lcshared_suggest2'); 4 | var bfelog = require('src/bfelogging'); 5 | var cache = {}; 6 | 7 | // This var is required because it is used as an identifier. 8 | exports.scheme = 'http://preprod.id.loc.gov/authorities/names'; 9 | 10 | exports.source = function (query, processSync, processAsync, formobject) { 11 | var triples = formobject.store; 12 | 13 | var type = ''; 14 | var hits = _.where(triples, { 15 | 's': formobject.defaulturi, 16 | 'p': 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' 17 | }); 18 | if (hits[0] !== undefined) { 19 | type = hits[0].o; 20 | } 21 | 22 | var scheme = exports.scheme; 23 | 24 | var rdftype = lcshared.rdfType(type); 25 | 26 | var q = ''; 27 | if (scheme !== '' && rdftype !== '') { 28 | q = '&cs:' + scheme + '&rdftype=' + rdftype; 29 | } else if (rdftype !== '') { 30 | q = '&rdftype=' + rdftype; 31 | } else if (scheme !== '') { 32 | q = '&cs:' + scheme; 33 | } 34 | if (q !== '') { 35 | q = '(' + query + ' OR ' + query + '* OR *' + query + '*)' + q; 36 | } else { 37 | q = '(' + query + ' OR ' + query + '* OR *' + query + '*)'; 38 | } 39 | // console.log('q is ' + q); 40 | q = encodeURI(q); 41 | 42 | if (cache[q]) { 43 | processSync(cache[q]); 44 | return; 45 | } 46 | if (typeof this.searching !== 'undefined') { 47 | clearTimeout(this.searching); 48 | processSync([]); 49 | } 50 | 51 | var schemeBaseURL = exports.scheme.split('/').slice(0,3).join('/'); 52 | 53 | this.searching = setTimeout(function () { 54 | if (query.length > 2 && query.substr(0, 1) != '?' && !query.match(/^[Nn][A-z\s]{0,1}\d/)) { 55 | var suggestquery = query.normalize(); 56 | bfelog.addMsg(new Error(), 'INFO',query); 57 | if (rdftype !== '') { suggestquery += '&rdftype=' + rdftype.replace('rdftype:', ''); } 58 | 59 | var u = exports.scheme + '/suggest2/?q=' + suggestquery + '&count=50'; 60 | u = u.replace(/^(http:)/,""); 61 | $.ajax({ 62 | url: u, 63 | dataType: 'jsonp', 64 | success: function (data) { 65 | var parsedlist = suggest2.processSuggestions(data, query); 66 | cache[q] = parsedlist; 67 | return processAsync(parsedlist); 68 | } 69 | }); 70 | } else if (query.length > 2) { 71 | q = query; 72 | if (query.match(/^[Nn][A-z\s]{0,1}\d/)){ 73 | q = query.replace(/\s+/g,'').normalize(); 74 | } 75 | u = exports.scheme + '/suggest2/?q=' + q.replace('?', '') + '&searchtype=keyword&count=50'; 76 | u = u.replace(/^(http:)/,""); 77 | $.ajax({ 78 | url: u, 79 | dataType: 'jsonp', 80 | success: function (data) { 81 | var parsedlist = suggest2.processSuggestions(data, query); 82 | cache[q] = parsedlist; 83 | return processAsync(parsedlist); 84 | } 85 | }); 86 | } else { 87 | return []; 88 | } 89 | }, 300); // 300 ms 90 | }; 91 | 92 | exports.getResource = lcshared.getResource; 93 | }); -------------------------------------------------------------------------------- /static/css/jsonld-vis.css: -------------------------------------------------------------------------------- 1 | 2 | svg { 3 | border: none; 4 | } 5 | 6 | .node { 7 | cursor: pointer; 8 | } 9 | 10 | .node text { 11 | font-size: 12px; 12 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif; 13 | fill: #333; 14 | } 15 | 16 | .d3-tip { 17 | font-size: 14px; 18 | font-family: 'Open Sans', 'Helvetica Neue', Helvetica, sans-serif; 19 | color: #333; 20 | border: 1px solid #ccc; 21 | border-radius: 5px; 22 | padding: 10px 20px; 23 | max-width: 250px; 24 | word-wrap: break-word; 25 | background-color: rgba(255, 255, 255, 0.9); 26 | text-align: left; 27 | } 28 | 29 | .link { 30 | fill: none; 31 | stroke: #dadfe1; 32 | stroke-width: 1px; 33 | } 34 | -------------------------------------------------------------------------------- /static/css/tooltipster.bundle.css: -------------------------------------------------------------------------------- 1 | 2 | .tooltipster-sidetip.tooltipster-shadow .tooltipster-box{border:none;border-radius:5px;background:#fff;box-shadow:0 0 10px 6px rgba(0,0,0,.1)}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-box{margin-top:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-box{margin-right:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-box{margin-left:6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-top .tooltipster-box{margin-bottom:6px}.tooltipster-sidetip.tooltipster-shadow .tooltipster-content{color:#333333}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow{height:6px;margin-left:-6px;width:12px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow{height:12px;margin-left:0;margin-top:-6px;width:6px}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow-background{display:none}.tooltipster-sidetip.tooltipster-shadow .tooltipster-arrow-border{border:6px solid transparent}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-left .tooltipster-arrow-border{border-left-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow-border{border-right-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-top .tooltipster-arrow-border{border-top-color:#fff}.tooltipster-sidetip.tooltipster-shadow.tooltipster-bottom .tooltipster-arrow-uncropped{top:-6px}.tooltipster-sidetip.tooltipster-shadow.tooltipster-right .tooltipster-arrow-uncropped{left:-6px} 3 | .tooltipster-sidetip.tooltipster-noir .tooltipster-box{border-radius:0;border:3px solid #000;background:#fff}.tooltipster-sidetip.tooltipster-noir .tooltipster-content{color:#000}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow{height:11px;margin-left:-11px;width:22px}.tooltipster-sidetip.tooltipster-noir.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow{height:22px;margin-left:0;margin-top:-11px;width:11px}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow-background{border:11px solid transparent}.tooltipster-sidetip.tooltipster-noir.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#fff;top:4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-left .tooltipster-arrow-background{border-left-color:#fff;left:-4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow-background{border-right-color:#fff;left:4px}.tooltipster-sidetip.tooltipster-noir.tooltipster-top .tooltipster-arrow-background{border-top-color:#fff;top:-4px}.tooltipster-sidetip.tooltipster-noir .tooltipster-arrow-border{border-width:11px}.tooltipster-sidetip.tooltipster-noir.tooltipster-bottom .tooltipster-arrow-uncropped{top:-11px}.tooltipster-sidetip.tooltipster-noir.tooltipster-right .tooltipster-arrow-uncropped{left:-11px} 4 | .tooltipster-sidetip.tooltipster-light .tooltipster-box{border-radius:3px;border:1px solid #ccc;background:#ededed}.tooltipster-sidetip.tooltipster-light .tooltipster-content{color:#666}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow{height:9px;margin-left:-9px;width:18px}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow,.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow{height:18px;margin-left:0;margin-top:-9px;width:9px}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow-background{border:9px solid transparent}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-background{border-bottom-color:#ededed;top:1px}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow-background{border-left-color:#ededed;left:-1px}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-background{border-right-color:#ededed;left:1px}.tooltipster-sidetip.tooltipster-light.tooltipster-top .tooltipster-arrow-background{border-top-color:#ededed;top:-1px}.tooltipster-sidetip.tooltipster-light .tooltipster-arrow-border{border:9px solid transparent}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-border{border-bottom-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-left .tooltipster-arrow-border{border-left-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-border{border-right-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-top .tooltipster-arrow-border{border-top-color:#ccc}.tooltipster-sidetip.tooltipster-light.tooltipster-bottom .tooltipster-arrow-uncropped{top:-9px}.tooltipster-sidetip.tooltipster-light.tooltipster-right .tooltipster-arrow-uncropped{left:-9px} 5 | 6 | /* This is the core CSS of Tooltipster */ 7 | 8 | /* GENERAL STRUCTURE RULES (do not edit this section) */ 9 | 10 | .tooltipster-base { 11 | /* this ensures that a constrained height set by functionPosition, 12 | if greater that the natural height of the tooltip, will be enforced 13 | in browsers that support display:flex */ 14 | display: flex; 15 | pointer-events: none; 16 | /* this may be overriden in JS for fixed position origins */ 17 | position: absolute; 18 | } 19 | 20 | .tooltipster-box { 21 | /* see .tooltipster-base. flex-shrink 1 is only necessary for IE10- 22 | and flex-basis auto for IE11- (at least) */ 23 | flex: 1 1 auto; 24 | } 25 | 26 | .tooltipster-content { 27 | /* prevents an overflow if the user adds padding to the div */ 28 | box-sizing: border-box; 29 | /* these make sure we'll be able to detect any overflow */ 30 | max-height: 100%; 31 | max-width: 100%; 32 | overflow: auto; 33 | } 34 | 35 | .tooltipster-ruler { 36 | /* these let us test the size of the tooltip without overflowing the window */ 37 | bottom: 0; 38 | left: 0; 39 | overflow: hidden; 40 | position: fixed; 41 | right: 0; 42 | top: 0; 43 | visibility: hidden; 44 | } 45 | 46 | /* ANIMATIONS */ 47 | 48 | /* Open/close animations */ 49 | 50 | /* fade */ 51 | 52 | .tooltipster-fade { 53 | opacity: 0; 54 | -webkit-transition-property: opacity; 55 | -moz-transition-property: opacity; 56 | -o-transition-property: opacity; 57 | -ms-transition-property: opacity; 58 | transition-property: opacity; 59 | } 60 | .tooltipster-fade.tooltipster-show { 61 | opacity: 1; 62 | } 63 | 64 | /* grow */ 65 | 66 | .tooltipster-grow { 67 | -webkit-transform: scale(0,0); 68 | -moz-transform: scale(0,0); 69 | -o-transform: scale(0,0); 70 | -ms-transform: scale(0,0); 71 | transform: scale(0,0); 72 | -webkit-transition-property: -webkit-transform; 73 | -moz-transition-property: -moz-transform; 74 | -o-transition-property: -o-transform; 75 | -ms-transition-property: -ms-transform; 76 | transition-property: transform; 77 | -webkit-backface-visibility: hidden; 78 | } 79 | .tooltipster-grow.tooltipster-show { 80 | -webkit-transform: scale(1,1); 81 | -moz-transform: scale(1,1); 82 | -o-transform: scale(1,1); 83 | -ms-transform: scale(1,1); 84 | transform: scale(1,1); 85 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 86 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 87 | -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 88 | -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 89 | -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 90 | transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 91 | } 92 | 93 | /* swing */ 94 | 95 | .tooltipster-swing { 96 | opacity: 0; 97 | -webkit-transform: rotateZ(4deg); 98 | -moz-transform: rotateZ(4deg); 99 | -o-transform: rotateZ(4deg); 100 | -ms-transform: rotateZ(4deg); 101 | transform: rotateZ(4deg); 102 | -webkit-transition-property: -webkit-transform, opacity; 103 | -moz-transition-property: -moz-transform; 104 | -o-transition-property: -o-transform; 105 | -ms-transition-property: -ms-transform; 106 | transition-property: transform; 107 | } 108 | .tooltipster-swing.tooltipster-show { 109 | opacity: 1; 110 | -webkit-transform: rotateZ(0deg); 111 | -moz-transform: rotateZ(0deg); 112 | -o-transform: rotateZ(0deg); 113 | -ms-transform: rotateZ(0deg); 114 | transform: rotateZ(0deg); 115 | -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 1); 116 | -webkit-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); 117 | -moz-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); 118 | -ms-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); 119 | -o-transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); 120 | transition-timing-function: cubic-bezier(0.230, 0.635, 0.495, 2.4); 121 | } 122 | 123 | /* fall */ 124 | 125 | .tooltipster-fall { 126 | -webkit-transition-property: top; 127 | -moz-transition-property: top; 128 | -o-transition-property: top; 129 | -ms-transition-property: top; 130 | transition-property: top; 131 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 132 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 133 | -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 134 | -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 135 | -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 136 | transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 137 | } 138 | .tooltipster-fall.tooltipster-initial { 139 | top: 0 !important; 140 | } 141 | .tooltipster-fall.tooltipster-show { 142 | } 143 | .tooltipster-fall.tooltipster-dying { 144 | -webkit-transition-property: all; 145 | -moz-transition-property: all; 146 | -o-transition-property: all; 147 | -ms-transition-property: all; 148 | transition-property: all; 149 | top: 0 !important; 150 | opacity: 0; 151 | } 152 | 153 | /* slide */ 154 | 155 | .tooltipster-slide { 156 | -webkit-transition-property: left; 157 | -moz-transition-property: left; 158 | -o-transition-property: left; 159 | -ms-transition-property: left; 160 | transition-property: left; 161 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 162 | -webkit-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 163 | -moz-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 164 | -ms-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 165 | -o-transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 166 | transition-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1.15); 167 | } 168 | .tooltipster-slide.tooltipster-initial { 169 | left: -40px !important; 170 | } 171 | .tooltipster-slide.tooltipster-show { 172 | } 173 | .tooltipster-slide.tooltipster-dying { 174 | -webkit-transition-property: all; 175 | -moz-transition-property: all; 176 | -o-transition-property: all; 177 | -ms-transition-property: all; 178 | transition-property: all; 179 | left: 0 !important; 180 | opacity: 0; 181 | } 182 | 183 | /* Update animations */ 184 | 185 | /* We use animations rather than transitions here because 186 | transition durations may be specified in the style tag due to 187 | animationDuration, and we try to avoid collisions and the use 188 | of !important */ 189 | 190 | /* fade */ 191 | 192 | @keyframes tooltipster-fading { 193 | 0% { 194 | opacity: 0; 195 | } 196 | 100% { 197 | opacity: 1; 198 | } 199 | } 200 | 201 | .tooltipster-update-fade { 202 | animation: tooltipster-fading 400ms; 203 | } 204 | 205 | /* rotate */ 206 | 207 | @keyframes tooltipster-rotating { 208 | 25% { 209 | transform: rotate(-2deg); 210 | } 211 | 75% { 212 | transform: rotate(2deg); 213 | } 214 | 100% { 215 | transform: rotate(0); 216 | } 217 | } 218 | 219 | .tooltipster-update-rotate { 220 | animation: tooltipster-rotating 600ms; 221 | } 222 | 223 | /* scale */ 224 | 225 | @keyframes tooltipster-scaling { 226 | 50% { 227 | transform: scale(1.1); 228 | } 229 | 100% { 230 | transform: scale(1); 231 | } 232 | } 233 | 234 | .tooltipster-update-scale { 235 | animation: tooltipster-scaling 600ms; 236 | } 237 | 238 | /** 239 | * DEFAULT STYLE OF THE SIDETIP PLUGIN 240 | * 241 | * All styles are "namespaced" with .tooltipster-sidetip to prevent 242 | * conflicts between plugins. 243 | */ 244 | 245 | /* .tooltipster-box */ 246 | 247 | .tooltipster-sidetip .tooltipster-box { 248 | background: #565656; 249 | border: 2px solid black; 250 | border-radius: 4px; 251 | } 252 | 253 | .tooltipster-sidetip.tooltipster-bottom .tooltipster-box { 254 | margin-top: 8px; 255 | } 256 | 257 | .tooltipster-sidetip.tooltipster-left .tooltipster-box { 258 | margin-right: 8px; 259 | } 260 | 261 | .tooltipster-sidetip.tooltipster-right .tooltipster-box { 262 | margin-left: 8px; 263 | } 264 | 265 | .tooltipster-sidetip.tooltipster-top .tooltipster-box { 266 | margin-bottom: 8px; 267 | } 268 | 269 | /* .tooltipster-content */ 270 | 271 | .tooltipster-sidetip .tooltipster-content { 272 | color: white; 273 | line-height: 18px; 274 | padding: 6px 14px; 275 | } 276 | 277 | /* .tooltipster-arrow : will keep only the zone of .tooltipster-arrow-uncropped that 278 | corresponds to the arrow we want to display */ 279 | 280 | .tooltipster-sidetip .tooltipster-arrow { 281 | overflow: hidden; 282 | position: absolute; 283 | } 284 | 285 | .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow { 286 | height: 10px; 287 | /* half the width, for centering */ 288 | margin-left: -10px; 289 | top: 0; 290 | width: 20px; 291 | } 292 | 293 | .tooltipster-sidetip.tooltipster-left .tooltipster-arrow { 294 | height: 20px; 295 | margin-top: -10px; 296 | right: 0; 297 | /* top 0 to keep the arrow from overflowing .tooltipster-base when it has not 298 | been positioned yet */ 299 | top: 0; 300 | width: 10px; 301 | } 302 | 303 | .tooltipster-sidetip.tooltipster-right .tooltipster-arrow { 304 | height: 20px; 305 | margin-top: -10px; 306 | left: 0; 307 | /* same as .tooltipster-left .tooltipster-arrow */ 308 | top: 0; 309 | width: 10px; 310 | } 311 | 312 | .tooltipster-sidetip.tooltipster-top .tooltipster-arrow { 313 | bottom: 0; 314 | height: 10px; 315 | margin-left: -10px; 316 | width: 20px; 317 | } 318 | 319 | /* common rules between .tooltipster-arrow-background and .tooltipster-arrow-border */ 320 | 321 | .tooltipster-sidetip .tooltipster-arrow-background, .tooltipster-sidetip .tooltipster-arrow-border { 322 | height: 0; 323 | position: absolute; 324 | width: 0; 325 | } 326 | 327 | /* .tooltipster-arrow-background */ 328 | 329 | .tooltipster-sidetip .tooltipster-arrow-background { 330 | border: 10px solid transparent; 331 | } 332 | 333 | .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-background { 334 | border-bottom-color: #565656; 335 | left: 0; 336 | top: 3px; 337 | } 338 | 339 | .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-background { 340 | border-left-color: #565656; 341 | left: -3px; 342 | top: 0; 343 | } 344 | 345 | .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-background { 346 | border-right-color: #565656; 347 | left: 3px; 348 | top: 0; 349 | } 350 | 351 | .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-background { 352 | border-top-color: #565656; 353 | left: 0; 354 | top: -3px; 355 | } 356 | 357 | /* .tooltipster-arrow-border */ 358 | 359 | .tooltipster-sidetip .tooltipster-arrow-border { 360 | border: 10px solid transparent; 361 | left: 0; 362 | top: 0; 363 | } 364 | 365 | .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-border { 366 | border-bottom-color: black; 367 | } 368 | 369 | .tooltipster-sidetip.tooltipster-left .tooltipster-arrow-border { 370 | border-left-color: black; 371 | } 372 | 373 | .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-border { 374 | border-right-color: black; 375 | } 376 | 377 | .tooltipster-sidetip.tooltipster-top .tooltipster-arrow-border { 378 | border-top-color: black; 379 | } 380 | 381 | /* tooltipster-arrow-uncropped */ 382 | 383 | .tooltipster-sidetip .tooltipster-arrow-uncropped { 384 | position: relative; 385 | } 386 | 387 | .tooltipster-sidetip.tooltipster-bottom .tooltipster-arrow-uncropped { 388 | top: -10px; 389 | } 390 | 391 | .tooltipster-sidetip.tooltipster-right .tooltipster-arrow-uncropped { 392 | left: -10px; 393 | } 394 | -------------------------------------------------------------------------------- /static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lcnetdev/bfe/d857ebb3864d911108ed888a1a8715257642a3de/static/images/favicon.ico -------------------------------------------------------------------------------- /static/js/config-bibframeorg.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. 10 | */ 11 | var rectobase = "http://bibframe.org"; 12 | 13 | var baseDBURI; 14 | var resourceURI; 15 | var metaproxyURI; 16 | var workContext; 17 | var loadmarc=false; 18 | var buildcontext = true; 19 | var enableusertemplates=true; 20 | 21 | var name = "config"; 22 | 23 | if (env.RECTOBASE!==undefined){ 24 | rectobase = env.RECTOBASE; 25 | } 26 | 27 | if (env.BASEDBURI!=undefined) { 28 | baseDBURI = env.BASEDBURI; 29 | resourceURI = baseDBURI + "/resources"; 30 | workContext = resourceURI + "/works/"; 31 | } 32 | 33 | if (env.LOADMARC!=undefined) { 34 | loadmarc = env.LOADMARC; 35 | } 36 | 37 | if (loadmarc){ 38 | metaproxyURI = env.METAPROXYURI; 39 | } 40 | 41 | if (env.BUILDCONTEXT!=undefined){ 42 | buildcontext = env.BUILDCONTEXT; 43 | } 44 | 45 | if (env.ENABLEUSERTEMPLATES!=undefined){ 46 | enableusertemplates=env.ENABLEUSERTEMPLATES; 47 | } 48 | 49 | if (env.VERSOBASE!==undefined){ 50 | versobase = env.VERSOBASE; 51 | } else { 52 | versobase = rectobase + "/verso"; 53 | } 54 | 55 | var config = { 56 | "name": name, 57 | "url" : rectobase, 58 | "baseURI": "http://id.loc.gov/", 59 | "basedbURI": baseDBURI, 60 | "versobase": versobase, 61 | "resourceURI": resourceURI, 62 | "metaproxyURI": metaproxyURI, 63 | "buildContext": buildcontext, 64 | "buildContextFor": ['id.loc.gov/authorities/names/','id.loc.gov/authorities/subjects/','http://id.loc.gov/authorities/childrensSubjects','id.loc.gov/vocabulary/relators/','id.loc.gov/resources/works/', 'id.loc.gov/bfentities/providers/','id.loc.gov/entities/providers/','id.loc.gov/authorities/genreForms'], 65 | "buildContextForWorksEndpoint": workContext, 66 | "enableUserTemplates" :enableusertemplates, 67 | "enableLoadMarc": loadmarc, 68 | "startingPointsUrl": versobase + "/api/configs?filter[where][configType]=startingPoints&filter[where][name]=" + name, 69 | "literalLangDataUrl": versobase + '/api/configs?filter[where][configType]=literalLangData', 70 | "profiles": [ 71 | versobase + "/api/configs?filter[where][configType]=profile" 72 | ], 73 | "api": ["save", "publish", "retrieveLDS", "retrieve", "deleteId", "setStartingPoints"], 74 | "return": { 75 | "format": "jsonld-expanded", 76 | "callback": myCB 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /static/js/config-dev.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. The "versoURL" variable is a convenience for setting the 10 | * base URL of verso in the "config" definition below. 11 | */ 12 | var rectobase = "http://localhost:3000"; 13 | var baseDBURI; 14 | var resourceURI; 15 | var workContext; 16 | var metaproxyURI; 17 | var buildcontext = true; 18 | 19 | var name = "config"; 20 | 21 | if (env.RECTOBASE!==undefined){ 22 | rectobase = env.RECTOBASE; 23 | } 24 | 25 | baseDBURI = "https://preprod-8210.id.loc.gov" 26 | if (env.BASEDBURI!=undefined) { 27 | baseDBURI = env.BASEDBURI; 28 | } 29 | resourceURI = baseDBURI + "/resources"; 30 | workContext = resourceURI + "/works/"; // This is unused? 31 | 32 | var lookups = { 33 | 'http://preprod.id.loc.gov/authorities/names': { 34 | 'name': 'LCNAF', 35 | 'require': 'src/lookups/lcnames' 36 | } 37 | }; 38 | 39 | var config = { 40 | "logging": { 41 | "level": "DEBUG", 42 | "toConsole": true 43 | }, 44 | "enviro": { 45 | "classes": "bg-danger text-dark", 46 | "text": "DEVELOPMENT" 47 | }, 48 | "name": name, 49 | "url" : rectobase, 50 | "baseURI": "http://id.loc.gov/", 51 | "basedbURI": baseDBURI, 52 | "resourceURI": resourceURI, 53 | "metaproxyURI": metaproxyURI, 54 | //"lookups": lookups, 55 | "buildContext": true, 56 | "buildContextFor": ['id.loc.gov/authorities/names','id.loc.gov/authorities/subjects/','http://id.loc.gov/authorities/childrensSubjects','id.loc.gov/vocabulary/relators/','id.loc.gov/resources/works/', 'id.loc.gov/bfentities/providers/','id.loc.gov/entities/providers/','id.loc.gov/authorities/genreForms'], 57 | "buildContextForWorksEndpoint": workContext, 58 | "enableUserTemplates": true, 59 | "enableLoadMarc": true, 60 | "startingPointsUrl": "/api/listconfigs?where=index.resourceType:startingPoints&where=index.label:" + name, 61 | "literalLangDataUrl": '/api/listconfigs?where=index.resourceType:literalLangData', 62 | "profiles": [ 63 | "/api/listconfigs?where=index.resourceType:profile" 64 | ], 65 | "api": ["save", "publish", "retrieveLDS", "retrieve", "deleteId", "setStartingPoints"], 66 | "return": { 67 | "format": "jsonld-expanded", 68 | "callback": myCB 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /static/js/config-editor-dev.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. 10 | */ 11 | var rectobase = "http://localhost:3000"; 12 | var baseDBURI; 13 | var resourceURI; 14 | var workContext; 15 | var loadmarc=false; 16 | var buildcontext = true; 17 | var enableusertemplates=true; 18 | 19 | var name = "config"; 20 | 21 | baseDBURI = "https://preprod-8231.id.loc.gov" 22 | resourceURI = baseDBURI + "/resources"; 23 | workContext = resourceURI + "/works/"; // This is unused? 24 | 25 | var versobase = "https://preprod-3001.id.loc.gov/verso"; 26 | 27 | var save = { 28 | callback: function (data, bfelog, callback) { 29 | alert("Hello there"); 30 | alert(JSON.stringify(data)); 31 | } 32 | }; 33 | 34 | var startingPoints = 35 | [ 36 | { 37 | "menuGroup":"Hub", 38 | "menuItems":[ 39 | { 40 | "label":"Hub", 41 | "type":["http://id.loc.gov/ontologies/bflc/Hub"], 42 | "useResourceTemplates":["lc:RT:bf2:Hub:Hub"] 43 | } 44 | ] 45 | }, 46 | { 47 | "menuGroup":"Monograph", 48 | "menuItems":[ 49 | { 50 | "label":"Instance", 51 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 52 | "useResourceTemplates":["lc:RT:bf2:Monograph:Instance"] 53 | }, 54 | { 55 | "label":"Work", 56 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 57 | "useResourceTemplates":["lc:RT:bf2:Monograph:Work"] 58 | } 59 | ] 60 | }, 61 | { 62 | "menuGroup":"Monograph (Non-Latin)", 63 | "menuItems":[ 64 | { 65 | "label":"Instance", 66 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 67 | "useResourceTemplates":["lc:RT:bf2:MonographNR:Instance"] 68 | }, 69 | { 70 | "label":"Work", 71 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 72 | "useResourceTemplates":["lc:RT:bf2:MonographNR:Work"] 73 | } 74 | ] 75 | }, 76 | { 77 | "menuGroup":"Notated Music", 78 | "menuItems":[ 79 | { 80 | "label":"Create Work", 81 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 82 | "useResourceTemplates":["lc:RT:bf2:NotatedMusic:Work"] 83 | }, 84 | { 85 | "label":"Create Instance", 86 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 87 | "useResourceTemplates":["lc:RT:bf2:NotatedMusic:Instance"] 88 | } 89 | ] 90 | } 91 | ]; 92 | 93 | /* 94 | removeOrphans will strip triples of the first or second template when loading 95 | multiple templates in this fashion. Probably should only permit one. 96 | */ 97 | /* 98 | var toload = { 99 | "defaulturi": "http://id.loc.gov/resources/works/5226", 100 | "templates": [ 101 | { 102 | "templateID": "lc:RT:bf2:MonographNR:Work" 103 | } 104 | ], 105 | "source": { 106 | "location": "http://id.loc.gov/resources/works/5226.json", 107 | "requestType": "json", 108 | "data": "UNUSED, BUT REMEMBER IT" 109 | } 110 | }; 111 | */ 112 | var toload = { 113 | "defaulturi": "http://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b", 114 | "templates": [ 115 | { 116 | "templateID": "lc:RT:bf2:Hub:Hub" 117 | } 118 | ], 119 | "source": { 120 | "location": "https://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b.bibframe_edit.json?test", 121 | "requestType": "json", 122 | "data": "UNUSED, BUT REMEMBER IT" 123 | } 124 | }; 125 | var toload = { 126 | "templates": [ 127 | { 128 | "templateID": "lc:RT:bf2:Monograph:Work" 129 | } 130 | ] 131 | }; 132 | //toload = {}; 133 | 134 | var config = { 135 | "logging": { 136 | "level": "DEBUG", 137 | "toConsole": true 138 | }, 139 | "name": name, 140 | "url" : rectobase, 141 | "baseURI": "http://id.loc.gov/", 142 | "basedbURI": "https://preprod-8230.id.loc.gov/", 143 | "resourceURI": "https://preprod-8288.loc.gov/", 144 | "buildContext": true, 145 | "buildContextFor": [ 146 | 'id.loc.gov/authorities/names/', 147 | 'id.loc.gov/authorities/subjects/', 148 | 'id.loc.gov/authorities/childrensSubjects', 149 | 'id.loc.gov/vocabulary/relators/', 150 | 'id.loc.gov/resources/works/', 151 | 'id.loc.gov/bfentities/providers/', 152 | 'id.loc.gov/entities/providers/', 153 | 'id.loc.gov/authorities/genreForms' 154 | ], 155 | "enableUserTemplates": false, 156 | "enableCloning": false, 157 | "enableAddProperty": false, 158 | 159 | "toload": toload, 160 | 161 | // "startingPointsUrl": versobase + "/api/configs?filter[where][configType]=startingPoints&filter[where][name]=" + name, 162 | "startingPoints": startingPoints, 163 | "literalLangDataUrl": versobase + '/api/configs?filter[where][configType]=literalLangData', 164 | "profiles": [ 165 | versobase + "/api/configs?filter[where][configType]=profile" 166 | ], 167 | "save": save, 168 | "api": ["setStartingPoints", "load"], 169 | "return": { 170 | "format": "jsonld-expanded", 171 | "callback": myCB 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /static/js/config-fulleditor-dev.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. 10 | */ 11 | var rectobase = "http://localhost:3000"; 12 | var baseDBURI; 13 | var resourceURI; 14 | var workContext; 15 | var loadmarc=false; 16 | var buildcontext = true; 17 | var enableusertemplates=true; 18 | 19 | var name = "config"; 20 | 21 | baseDBURI = "https://preprod-8231.id.loc.gov" 22 | resourceURI = baseDBURI + "/resources"; 23 | workContext = resourceURI + "/works/"; // This is unused? 24 | 25 | var versobase = "https://preprod-3001.id.loc.gov/verso"; 26 | 27 | var save = { 28 | callback: function (data, bfelog, callback) { 29 | alert("Hello there"); 30 | alert(JSON.stringify(data)); 31 | } 32 | }; 33 | 34 | var startingPoints = 35 | [ 36 | { 37 | "menuGroup":"Hub", 38 | "menuItems":[ 39 | { 40 | "label":"Hub", 41 | "type":["http://id.loc.gov/ontologies/bflc/Hub"], 42 | "useResourceTemplates":["lc:RT:bf2:Hub:Hub"] 43 | } 44 | ] 45 | }, 46 | { 47 | "menuGroup":"Monograph", 48 | "menuItems":[ 49 | { 50 | "label":"Instance", 51 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 52 | "useResourceTemplates":["lc:RT:bf2:Monograph:Instance"] 53 | }, 54 | { 55 | "label":"Work", 56 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 57 | "useResourceTemplates":["lc:RT:bf2:Monograph:Work"] 58 | } 59 | ] 60 | }, 61 | { 62 | "menuGroup":"Monograph (Non-Latin)", 63 | "menuItems":[ 64 | { 65 | "label":"Instance", 66 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 67 | "useResourceTemplates":["lc:RT:bf2:MonographNR:Instance"] 68 | }, 69 | { 70 | "label":"Work", 71 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 72 | "useResourceTemplates":["lc:RT:bf2:MonographNR:Work"] 73 | } 74 | ] 75 | }, 76 | { 77 | "menuGroup":"Notated Music", 78 | "menuItems":[ 79 | { 80 | "label":"Create Work", 81 | "type":["http://id.loc.gov/ontologies/bibframe/Work"], 82 | "useResourceTemplates":["lc:RT:bf2:NotatedMusic:Work"] 83 | }, 84 | { 85 | "label":"Create Instance", 86 | "type":["http://id.loc.gov/ontologies/bibframe/Instance"], 87 | "useResourceTemplates":["lc:RT:bf2:NotatedMusic:Instance"] 88 | } 89 | ] 90 | } 91 | ]; 92 | 93 | /* 94 | removeOrphans will strip triples of the first or second template when loading 95 | multiple templates in this fashion. Probably should only permit one. 96 | */ 97 | /* 98 | var toload = { 99 | "defaulturi": "http://id.loc.gov/resources/works/5226", 100 | "templates": [ 101 | { 102 | "templateID": "lc:RT:bf2:MonographNR:Work" 103 | } 104 | ], 105 | "source": { 106 | "location": "http://id.loc.gov/resources/works/5226.json", 107 | "requestType": "json", 108 | "data": "UNUSED, BUT REMEMBER IT" 109 | } 110 | }; 111 | */ 112 | var toload = { 113 | "defaulturi": "http://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b", 114 | "templates": [ 115 | { 116 | "templateID": "lc:RT:bf2:Hub:Hub" 117 | } 118 | ], 119 | "source": { 120 | "location": "https://id.loc.gov/resources/hubs/f60eb10317b7c78642d32f7e2851653b.bibframe_edit.json?test", 121 | "requestType": "json", 122 | "data": "UNUSED, BUT REMEMBER IT" 123 | } 124 | }; 125 | var toload = { 126 | "templates": [ 127 | { 128 | "templateID": "lc:RT:bf2:Monograph:Work" 129 | } 130 | ] 131 | }; 132 | //toload = {}; 133 | 134 | var config = { 135 | "logging": { 136 | "level": "DEBUG", 137 | "toConsole": true 138 | }, 139 | "name": name, 140 | "url" : rectobase, 141 | "baseURI": "http://id.loc.gov/", 142 | "basedbURI": "https://preprod-8230.id.loc.gov/", 143 | "resourceURI": "https://preprod-8288.loc.gov/", 144 | "buildContext": true, 145 | "buildContextFor": [ 146 | 'id.loc.gov/authorities/names/', 147 | 'id.loc.gov/authorities/subjects/', 148 | 'id.loc.gov/authorities/childrensSubjects', 149 | 'id.loc.gov/vocabulary/relators/', 150 | 'id.loc.gov/resources/works/', 151 | 'id.loc.gov/bfentities/providers/', 152 | 'id.loc.gov/entities/providers/', 153 | 'id.loc.gov/authorities/genreForms' 154 | ], 155 | "enableUserTemplates": false, 156 | "enableCloning": false, 157 | "enableAddProperty": false, 158 | 159 | "toload": toload, 160 | 161 | // "startingPointsUrl": versobase + "/api/configs?filter[where][configType]=startingPoints&filter[where][name]=" + name, 162 | "startingPoints": startingPoints, 163 | "literalLangDataUrl": '/api/listconfigs?where=index.resourceType:literalLangData', 164 | "profiles": [ 165 | "/api/listconfigs?where=index.resourceType:profile" 166 | ], 167 | 168 | "save": save, 169 | "api": ["setStartingPoints", "load"], 170 | "return": { 171 | "format": "jsonld-expanded", 172 | "callback": myCB 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /static/js/config-test.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. 10 | */ 11 | var rectobase = "http://localhost:3000"; 12 | 13 | var baseDBURI; 14 | var resourceURI; 15 | var metaproxyURI; 16 | var workContext; 17 | var loadmarc=true; 18 | var buildcontext = true; 19 | var enableusertemplates=true; 20 | 21 | var name = "config-test"; 22 | 23 | if (env.RECTOBASE!==undefined){ 24 | rectobase = env.RECTOBASE; 25 | } 26 | 27 | if (env.BASEDBURI!=undefined) { 28 | baseDBURI = env.BASEDBURI; 29 | resourceURI = baseDBURI + "/resources"; 30 | workContext = resourceURI + "/works/"; 31 | } 32 | 33 | if (env.LOADMARC!=undefined) { 34 | loadmarc = env.LOADMARC; 35 | } 36 | 37 | if (loadmarc){ 38 | metaproxyURI = env.METAPROXYURI; 39 | } 40 | 41 | if (env.BUILDCONTEXT!=undefined){ 42 | buildcontext = env.BUILDCONTEXT; 43 | } 44 | 45 | if (env.ENABLEUSERTEMPLATES!=undefined){ 46 | enableusertemplates=env.ENABLEUSERTEMPLATES; 47 | } 48 | 49 | var config = { 50 | "logging": { 51 | "level": "DEBUG", 52 | "toConsole": true 53 | }, 54 | "enviro": { 55 | "classes": "bg-warning text-dark", 56 | "text": "TEST TEST TEST" 57 | }, 58 | "name": name, 59 | "url" : rectobase, 60 | "baseURI": "http://id.loc.gov/", 61 | "basedbURI": baseDBURI, 62 | "resourceURI": resourceURI, 63 | "metaproxyURI": metaproxyURI, 64 | "buildContext": buildcontext, 65 | "buildContextFor": ['id.loc.gov/authorities/names/','id.loc.gov/authorities/subjects/','http://id.loc.gov/authorities/childrensSubjects','id.loc.gov/vocabulary/relators/','id.loc.gov/resources/works/', 'id.loc.gov/bfentities/providers/','id.loc.gov/entities/providers/','id.loc.gov/authorities/genreForms'], 66 | "buildContextForWorksEndpoint": workContext, 67 | "enableUserTemplates" :enableusertemplates, 68 | "enableLoadMarc": loadmarc, 69 | "startingPointsUrl": "/api/listconfigs?where=index.resourceType:startingPoints&where=index.label:" + name, 70 | "literalLangDataUrl": '/api/listconfigs?where=index.resourceType:literalLangData', 71 | "profiles": [ 72 | "/api/listconfigs?where=index.resourceType:profile" 73 | ], 74 | "api": ["save", "publish", "retrieveLDS", "retrieve", "deleteId", "setStartingPoints"], 75 | "return": { 76 | "format": "jsonld-expanded", 77 | "callback": myCB 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /static/js/config.js: -------------------------------------------------------------------------------- 1 | function myCB(data) { 2 | document.body.scrollTop = document.documentElement.scrollTop = 0; 3 | } 4 | 5 | /* Config object profiles 6 | * Editor profiles are read from a WS endpoint 7 | * The data are expected to be in a JSON array, with each object 8 | * in the array containing a "json" property that has the profile 9 | * itself. 10 | */ 11 | var rectobase = "https://editor.id.loc.gov"; 12 | 13 | var baseDBURI; 14 | var resourceURI; 15 | var metaproxyURI; 16 | var workContext; 17 | var loadmarc=false; 18 | var buildcontext = true; 19 | var enableusertemplates=true; 20 | 21 | var name = "config"; 22 | 23 | if (env.RECTOBASE!==undefined){ 24 | rectobase = env.RECTOBASE; 25 | } 26 | 27 | if (env.BASEDBURI!=undefined) { 28 | baseDBURI = env.BASEDBURI; 29 | resourceURI = baseDBURI + "/resources"; 30 | workContext = resourceURI + "/works/"; 31 | } 32 | 33 | if (env.LOADMARC!=undefined) { 34 | loadmarc = env.LOADMARC; 35 | } 36 | 37 | if (loadmarc){ 38 | metaproxyURI = env.METAPROXYURI; 39 | } 40 | 41 | if (env.BUILDCONTEXT!=undefined){ 42 | buildcontext = env.BUILDCONTEXT; 43 | } 44 | 45 | if (env.ENABLEUSERTEMPLATES!=undefined){ 46 | enableusertemplates=env.ENABLEUSERTEMPLATES; 47 | } 48 | 49 | var config = { 50 | "name": name, 51 | "url" : rectobase, 52 | "baseURI": "http://id.loc.gov/", 53 | "basedbURI": baseDBURI, 54 | "resourceURI": resourceURI, 55 | "metaproxyURI": metaproxyURI, 56 | "buildContext": buildcontext, 57 | "buildContextFor": ['id.loc.gov/authorities/names/','id.loc.gov/authorities/subjects/','http://id.loc.gov/authorities/childrensSubjects','id.loc.gov/vocabulary/relators/','id.loc.gov/resources/works/', 'id.loc.gov/bfentities/providers/','id.loc.gov/entities/providers/','id.loc.gov/authorities/genreForms'], 58 | "buildContextForWorksEndpoint": workContext, 59 | "enableUserTemplates" :enableusertemplates, 60 | "enableLoadMarc": loadmarc, 61 | "startingPointsUrl": "/api/listconfigs?where=index.resourceType:startingPoints&where=index.label:" + name, 62 | "literalLangDataUrl": '/api/listconfigs?where=index.resourceType:literalLangData', 63 | "profiles": [ 64 | "/api/listconfigs?where=index.resourceType:profile" 65 | ], 66 | "api": ["save", "publish", "retrieveLDS", "retrieve", "deleteId", "setStartingPoints"], 67 | "return": { 68 | "format": "jsonld-expanded", 69 | "callback": myCB 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /static/js/jsonld-vis.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | function jsonldVis(jsonld, selector, config) { 5 | if (!arguments.length) return jsonldVis; 6 | config = config || {}; 7 | 8 | var h = config.h || 600 9 | , w = config.w || 800 10 | , maxLabelWidth = config.maxLabelWidth || 250 11 | , transitionDuration = config.transitionDuration || 750 12 | , transitionEase = config.transitionEase || 'cubic-in-out' 13 | , minRadius = config.minRadius || 5 14 | , scalingFactor = config.scalingFactor || 2; 15 | 16 | var i = 0; 17 | 18 | var tree = d3.layout.tree() 19 | .size([h, w]); 20 | 21 | var diagonal = d3.svg.diagonal() 22 | .projection(function(d) { return [d.y, d.x]; }); 23 | 24 | var svg = d3.select(selector).append('svg') 25 | .attr('width', w) 26 | .attr('height', h) 27 | .append('g') 28 | .attr('transform', 'translate(' + maxLabelWidth + ',0)'); 29 | 30 | var tip = d3.tip() 31 | .direction(function(d) { 32 | return d.children || d._children ? 'w' : 'e'; 33 | }) 34 | .offset(function(d) { 35 | return d.children || d._children ? [0, -3] : [0, 3]; 36 | }) 37 | .attr('class', 'd3-tip') 38 | .html(function(d) { 39 | return '' + d.valueExtended + ''; 40 | }); 41 | 42 | svg.call(tip); 43 | 44 | var root = jsonldTree(jsonld); 45 | root.x0 = h / 2; 46 | root.y0 = 0; 47 | root.children.forEach(collapse); 48 | 49 | function changeSVGWidth(newWidth) { 50 | if (w !== newWidth) { 51 | d3.select(selector + ' > svg').attr('width', newWidth); 52 | } 53 | } 54 | 55 | function jsonldTree(source) { 56 | var tree = {}; 57 | 58 | if ('@id' in source) { 59 | tree.isIdNode = true; 60 | tree.name = source['@id']; 61 | if (tree.name.length > maxLabelWidth / 9) { 62 | tree.valueExtended = tree.name; 63 | tree.name = '...' + tree.valueExtended.slice(-Math.floor(maxLabelWidth / 9)); 64 | } 65 | } else { 66 | tree.isIdNode = true; 67 | tree.isBlankNode = true; 68 | // random id, can replace with actual uuid generator if needed 69 | tree.name = '_' + Math.random().toString(10).slice(-7); 70 | } 71 | 72 | var children = []; 73 | Object.keys(source).forEach(function(key) { 74 | if (key === '@id' || key === '@context' || source[key] === null) return; 75 | 76 | var valueExtended, value; 77 | if (typeof source[key] === 'object' && !Array.isArray(source[key])) { 78 | children.push({ 79 | name: key, 80 | children: [jsonldTree(source[key])] 81 | }); 82 | } else if (Array.isArray(source[key])) { 83 | children.push({ 84 | name: key, 85 | children: source[key].map(function(item) { 86 | if (typeof item === 'object') { 87 | return jsonldTree(item); 88 | } else { 89 | return { name: item }; 90 | } 91 | }) 92 | }); 93 | } else { 94 | valueExtended = source[key]; 95 | value = valueExtended; 96 | if (value.length > maxLabelWidth / 9) { 97 | value = value.slice(0, Math.floor(maxLabelWidth / 9)) + '...'; 98 | children.push({ 99 | name: key, 100 | value: value, 101 | valueExtended: valueExtended 102 | }); 103 | } else { 104 | children.push({ 105 | name: key, 106 | value: value 107 | }); 108 | } 109 | } 110 | }); 111 | 112 | if (children.length) { 113 | tree.children = children; 114 | } 115 | 116 | return tree; 117 | } 118 | 119 | function update(source) { 120 | var nodes = tree.nodes(root).reverse(); 121 | var links = tree.links(nodes); 122 | 123 | nodes.forEach(function(d) { d.y = d.depth * maxLabelWidth; }); 124 | 125 | var node = svg.selectAll('g.node') 126 | .data(nodes, function(d) { return d.id || (d.id = ++i); }); 127 | 128 | var nodeEnter = node.enter() 129 | .append('g') 130 | .attr('class', 'node') 131 | .attr('transform', function(d) { return 'translate(' + source.y0 + ',' + source.x0 + ')'; }) 132 | .on('click', click); 133 | 134 | nodeEnter.append('circle') 135 | .attr('r', 0) 136 | .style('stroke-width', function(d) { 137 | return d.isIdNode ? '2px' : '1px'; 138 | }) 139 | .style('stroke', function(d) { 140 | return d.isIdNode ? '#F7CA18' : '#4ECDC4'; 141 | }) 142 | .style('fill', function(d) { 143 | if (d.isIdNode) { 144 | return d._children ? '#F5D76E' : 'white'; 145 | } else { 146 | return d._children ? '#86E2D5' : 'white'; 147 | } 148 | }) 149 | .on('mouseover', function(d) { if (d.valueExtended) tip.show(d); }) 150 | .on('mouseout', tip.hide); 151 | 152 | nodeEnter.append('text') 153 | .attr('x', function(d) { 154 | var spacing = computeRadius(d) + 5; 155 | return d.children || d._children ? -spacing : spacing; 156 | }) 157 | .attr('dy', '4') 158 | .attr('text-anchor', function(d) { return d.children || d._children ? 'end' : 'start'; }) 159 | .text(function(d) { return d.name + (d.value ? ': ' + d.value : ''); }) 160 | .style('fill-opacity', 0); 161 | 162 | var maxSpan = Math.max.apply(Math, nodes.map(function(d) { return d.y + maxLabelWidth; })); 163 | if (maxSpan + maxLabelWidth + 20 > w) { 164 | changeSVGWidth(maxSpan + maxLabelWidth); 165 | d3.select(selector).node().scrollLeft = source.y0; 166 | } 167 | 168 | var nodeUpdate = node.transition() 169 | .duration(transitionDuration) 170 | .ease(transitionEase) 171 | .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; }); 172 | 173 | nodeUpdate.select('circle') 174 | .attr('r', function(d) { return computeRadius(d); }) 175 | .style('stroke-width', function(d) { 176 | return d.isIdNode ? '2px' : '1px'; 177 | }) 178 | .style('stroke', function(d) { 179 | return d.isIdNode ? '#F7CA18' : '#4ECDC4'; 180 | }) 181 | .style('fill', function(d) { 182 | if (d.isIdNode) { 183 | return d._children ? '#F5D76E' : 'white'; 184 | } else { 185 | return d._children ? '#86E2D5' : 'white'; 186 | } 187 | }); 188 | 189 | nodeUpdate.select('text').style('fill-opacity', 1); 190 | 191 | var nodeExit = node.exit().transition() 192 | .duration(transitionDuration) 193 | .ease(transitionEase) 194 | .attr('transform', function(d) { return 'translate(' + source.y + ',' + source.x + ')'; }) 195 | .remove(); 196 | 197 | nodeExit.select('circle').attr('r', 0); 198 | nodeExit.select('text').style('fill-opacity', 0); 199 | 200 | var link = svg.selectAll('path.link') 201 | .data(links, function(d) { return d.target.id; }); 202 | 203 | link.enter().insert('path', 'g') 204 | .attr('class', 'link') 205 | .attr('d', function(d) { 206 | var o = { x: source.x0, y: source.y0 }; 207 | return diagonal({ source: o, target: o }); 208 | }); 209 | 210 | link.transition() 211 | .duration(transitionDuration) 212 | .ease(transitionEase) 213 | .attr('d', diagonal); 214 | 215 | link.exit().transition() 216 | .duration(transitionDuration) 217 | .ease(transitionEase) 218 | .attr('d', function(d) { 219 | var o = { x: source.x, y: source.y }; 220 | return diagonal({ source: o, target: o }); 221 | }) 222 | .remove(); 223 | 224 | nodes.forEach(function(d) { 225 | d.x0 = d.x; 226 | d.y0 = d.y; 227 | }); 228 | } 229 | 230 | function computeRadius(d) { 231 | if (d.children || d._children) { 232 | return minRadius + (numEndNodes(d) / scalingFactor); 233 | } else { 234 | return minRadius; 235 | } 236 | } 237 | 238 | function numEndNodes(n) { 239 | var num = 0; 240 | if (n.children) { 241 | n.children.forEach(function(c) { 242 | num += numEndNodes(c); 243 | }); 244 | } else if (n._children) { 245 | n._children.forEach(function(c) { 246 | num += numEndNodes(c); 247 | }); 248 | } else { 249 | num++; 250 | } 251 | return num; 252 | } 253 | 254 | function click(d) { 255 | if (d.children) { 256 | d._children = d.children; 257 | d.children = null; 258 | } else { 259 | d.children = d._children; 260 | d._children = null; 261 | } 262 | 263 | update(d); 264 | 265 | // fast-forward blank nodes 266 | if (d.children) { 267 | d.children.forEach(function(child) { 268 | if (child.isBlankNode && child._children) { 269 | click(child); 270 | } 271 | }); 272 | } 273 | } 274 | 275 | function collapse(d) { 276 | if (d.children) { 277 | d._children = d.children; 278 | d._children.forEach(collapse); 279 | d.children = null; 280 | } 281 | } 282 | 283 | update(root); 284 | } 285 | 286 | if (typeof module !== 'undefined' && module.exports) { 287 | module.exports = jsonldVis; 288 | } else { 289 | d3.jsonldVis = jsonldVis; 290 | } 291 | })(); 292 | -------------------------------------------------------------------------------- /static/js/require.js: -------------------------------------------------------------------------------- 1 | /* 2 | RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. 3 | Available via the MIT or new BSD license. 4 | see: http://github.com/jrburke/requirejs for details 5 | */ 6 | var requirejs,require,define; 7 | (function(ca){function G(b){return"[object Function]"===M.call(b)}function H(b){return"[object Array]"===M.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(c)){if(this.events.error&&this.map.isDefine||h.onError!==da)try{f=i.execCb(b,c,e,f)}catch(d){a=d}else f=i.execCb(b,c,e,f);this.map.isDefine&&void 0===f&&((e=this.module)?f=e.exports:this.usingExports&& 19 | (f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=c;this.exports=f;if(this.map.isDefine&&!this.ignore&&(p[b]=f,h.onResourceLoad))h.onResourceLoad(i,this.map,this.depMaps);y(b);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else this.fetch()}},callPlugin:function(){var a= 20 | this.map,b=a.id,d=m(a.prefix);this.depMaps.push(d);r(d,"defined",t(this,function(f){var d,g;g=j(ba,this.map.id);var J=this.map.name,u=this.map.parentMap?this.map.parentMap.name:null,p=i.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(J=f.normalize(J,function(a){return c(a,u,!0)})||""),f=m(a.prefix+"!"+J,this.map.parentMap),r(f,"defined",t(this,function(a){this.init([],function(){return a},null,{enabled:!0,ignore:!0})})),g=j(k,f.id)){this.depMaps.push(f); 21 | if(this.events.error)g.on("error",t(this,function(a){this.emit("error",a)}));g.enable()}}else g?(this.map.url=i.nameToUrl(g),this.load()):(d=t(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),d.error=t(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];B(k,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),d.fromText=t(this,function(f,c){var g=a.name,J=m(g),k=O;c&&(f=c);k&&(O=!1);q(J);s(l.config,b)&&(l.config[g]=l.config[b]);try{h.exec(f)}catch(j){return w(C("fromtexteval", 22 | "fromText eval for "+b+" failed: "+j,j,[b]))}k&&(O=!0);this.depMaps.push(J);i.completeLoad(g);p([g],d)}),f.load(a.name,p,d,l))}));i.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){W[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,t(this,function(a,b){var c,f;if("string"===typeof a){a=m(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=j(N,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;r(a,"defined",t(this,function(a){this.defineDep(b, 23 | a);this.check()}));this.errback&&r(a,"error",t(this,this.errback))}c=a.id;f=k[c];!s(N,c)&&(f&&!f.enabled)&&i.enable(a,this)}));B(this.pluginMaps,t(this,function(a){var b=j(k,a.id);b&&!b.enabled&&i.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};i={config:l,contextName:b,registry:k,defined:p,urlFetched:T,defQueue:A,Module:$,makeModuleMap:m, 24 | nextTick:h.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=l.shim,c={paths:!0,bundles:!0,config:!0,map:!0};B(a,function(a,b){c[b]?(l[b]||(l[b]={}),V(l[b],a,!0,!0)):l[b]=a});a.bundles&&B(a.bundles,function(a,b){v(a,function(a){a!==b&&(ba[a]=b)})});a.shim&&(B(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=i.makeShimExports(a);b[c]=a}),l.shim=b);a.packages&&v(a.packages,function(a){var b, 25 | a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(l.paths[b]=a.location);l.pkgs[b]=a.name+"/"+(a.main||"main").replace(ja,"").replace(R,"")});B(k,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=m(b))});if(a.deps||a.callback)i.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ca,arguments));return b||a.exports&&ea(a.exports)}},makeRequire:function(a,e){function g(f,c,d){var j,l;e.enableBuildCallback&&(c&&G(c))&&(c.__requireJsBuild= 26 | !0);if("string"===typeof f){if(G(c))return w(C("requireargs","Invalid require call"),d);if(a&&s(N,f))return N[f](k[a.id]);if(h.get)return h.get(i,f,a,g);j=m(f,a,!1,!0);j=j.id;return!s(p,j)?w(C("notloaded",'Module name "'+j+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):p[j]}L();i.nextTick(function(){L();l=q(m(null,a));l.skipMap=e.skipMap;l.init(f,c,d,{enabled:!0});D()});return g}e=e||{};V(g,{isBrowser:z,toUrl:function(b){var e,d=b.lastIndexOf("."),g=b.split("/")[0];if(-1!== 27 | d&&(!("."===g||".."===g)||1g.attachEvent.toString().indexOf("[native code"))&&!Z?(O=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)): 34 | (g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1)),g.src=d,L=g,D?y.insertBefore(g,D):y.appendChild(g),L=null,g;if(fa)try{importScripts(d),b.completeLoad(c)}catch(j){b.onError(C("importscripts","importScripts failed for "+c+" at "+d,j,[c]))}};z&&!r.skipDataMain&&U(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(K=b.getAttribute("data-main"))return q=K,r.baseUrl||(E=q.split("/"),q=E.pop(),Q=E.length?E.join("/")+"/":"./",r.baseUrl= 35 | Q),q=q.replace(R,""),h.jsExtRegExp.test(q)&&(q=K),r.deps=r.deps?r.deps.concat(q):[q],!0});define=function(b,c,d){var g,h;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(la,"").replace(ma,function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(O){if(!(g=L))P&&"interactive"===P.readyState||U(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return P=b}),g=P;g&&(b|| 36 | (b=g.getAttribute("data-requiremodule")),h=F[g.getAttribute("data-requirecontext")])}(h?h.defQueue:S).push([b,c,d])};define.amd={jQuery:!0};h.exec=function(b){return eval(b)};h(r)}})(this); 37 | -------------------------------------------------------------------------------- /static/js/short-uuid.min.js: -------------------------------------------------------------------------------- 1 | /*! short-uuid v2.3.3 - 2017-05-22 */ 2 | 3 | !function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).ShortUUID=r()}}(function(){return function r(n,t,e){function o(u,f){if(!t[u]){if(!n[u]){var a="function"==typeof require&&require;if(!f&&a)return a(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var c=t[u]={exports:{}};n[u][0].call(c.exports,function(r){var t=n[u][1][r];return o(t||r)},c,c.exports,r,n,t,e)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;u?@[]^_`{|}~"},e.uuid=i,e}()},{"any-base":2,"uuid/v4":6}],2:[function(r,n,t){function e(r,n){var t=new o(r,n);return function(r){return t.convert(r)}}var o=r("./src/converter");e.BIN="01",e.OCT="01234567",e.DEC="0123456789",e.HEX="0123456789abcdef",n.exports=e},{"./src/converter":3}],3:[function(r,n,t){"use strict";function e(r,n){if(!(r&&n&&r.length&&n.length))throw new Error("Bad alphabet");this.srcAlphabet=r,this.dstAlphabet=n}e.prototype.convert=function(r){var n,t,e,o={},i=this.srcAlphabet.length,u=this.dstAlphabet.length,f=r.length,a="";if(this.srcAlphabet===this.dstAlphabet)return r;for(n=0;n=u?(o[e++]=parseInt(t/u,10),t%=u):e>0&&(o[e++]=0);f=e,a=this.dstAlphabet[t]+a}while(0!=e);return a},n.exports=e},{}],4:[function(r,n,t){function e(r,n){var t=n||0,e=o;return e[r[t++]]+e[r[t++]]+e[r[t++]]+e[r[t++]]+"-"+e[r[t++]]+e[r[t++]]+"-"+e[r[t++]]+e[r[t++]]+"-"+e[r[t++]]+e[r[t++]]+"-"+e[r[t++]]+e[r[t++]]+e[r[t++]]+e[r[t++]]+e[r[t++]]+e[r[t++]]}for(var o=[],i=0;i<256;++i)o[i]=(i+256).toString(16).substr(1);n.exports=e},{}],5:[function(r,n,t){var e,o=global.crypto||global.msCrypto;if(o&&o.getRandomValues){var i=new Uint8Array(16);e=function(){return o.getRandomValues(i),i}}if(!e){var u=new Array(16);e=function(){for(var r,n=0;n<16;n++)0==(3&n)&&(r=4294967296*Math.random()),u[n]=r>>>((3&n)<<3)&255;return u}}n.exports=e},{}],6:[function(r,n,t){function e(r,n,t){var e=n&&t||0;"string"==typeof r&&(n="binary"==r?new Array(16):null,r=null);var u=(r=r||{}).random||(r.rng||o)();if(u[6]=15&u[6]|64,u[8]=63&u[8]|128,n)for(var f=0;f<16;++f)n[e+f]=u[f];return n||i(u)}var o=r("./lib/rng"),i=r("./lib/bytesToUuid");n.exports=e},{"./lib/bytesToUuid":4,"./lib/rng":5}]},{},[1])(1)}); -------------------------------------------------------------------------------- /test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | (Bibliographic Framework Initiative Technical Site - BIBFRAME.ORG) 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 91 | 92 |
93 |
94 |
95 | 96 | 103 | 104 | 105 |
106 |
107 |
108 | 109 |
110 |
111 |
112 |

This is a development view of the Bibliographic Framework Initiative project's editor. For more information, 113 | go to 114 | www.loc.gov/bibframe.

115 |
116 |
117 | 118 | 121 | 122 | 123 | 124 | 125 | --------------------------------------------------------------------------------