solid-ui 2.4.28-df3d9431 → 2.4.28-e3ba3633

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/805.solid-ui.min.js +1 -1
  2. package/dist/805.solid-ui.min.js.map +1 -1
  3. package/dist/solid-ui.js +1606 -2297
  4. package/dist/solid-ui.js.map +1 -1
  5. package/dist/solid-ui.min.js +1 -1
  6. package/dist/solid-ui.min.js.map +1 -1
  7. package/dist/vendors-node_modules_jsonld_lib_jsonld_js.solid-ui.js +1955 -1955
  8. package/dist/vendors-node_modules_jsonld_lib_jsonld_js.solid-ui.js.map +1 -1
  9. package/lib/chat/bookmarks.js +7 -6
  10. package/lib/chat/bookmarks.js.map +1 -1
  11. package/lib/chat/chatLogic.js +65 -249
  12. package/lib/chat/chatLogic.js.map +1 -1
  13. package/lib/chat/dateFolder.js +126 -129
  14. package/lib/chat/dateFolder.js.map +1 -1
  15. package/lib/chat/infinite.js +423 -637
  16. package/lib/chat/infinite.js.map +1 -1
  17. package/lib/chat/keys.d.ts +0 -3
  18. package/lib/chat/keys.d.ts.map +1 -1
  19. package/lib/chat/keys.js +80 -124
  20. package/lib/chat/keys.js.map +1 -1
  21. package/lib/chat/message.js +194 -333
  22. package/lib/chat/message.js.map +1 -1
  23. package/lib/chat/messageTools.js +277 -463
  24. package/lib/chat/messageTools.js.map +1 -1
  25. package/lib/chat/signature.d.ts +2 -0
  26. package/lib/chat/signature.d.ts.map +1 -1
  27. package/lib/chat/signature.js +70 -1
  28. package/lib/chat/signature.js.map +1 -1
  29. package/lib/chat/thread.js +209 -299
  30. package/lib/chat/thread.js.map +1 -1
  31. package/lib/header/index.js +0 -5
  32. package/lib/header/index.js.map +1 -1
  33. package/lib/log.js +5 -5
  34. package/lib/log.js.map +1 -1
  35. package/lib/login/login.d.ts.map +1 -1
  36. package/lib/login/login.js +31 -65
  37. package/lib/login/login.js.map +1 -1
  38. package/lib/media/media-capture.d.ts +2 -2
  39. package/lib/media/media-capture.d.ts.map +1 -1
  40. package/lib/media/media-capture.js +11 -15
  41. package/lib/media/media-capture.js.map +1 -1
  42. package/lib/pad.d.ts +2 -2
  43. package/lib/pad.d.ts.map +1 -1
  44. package/lib/pad.js +15 -41
  45. package/lib/pad.js.map +1 -1
  46. package/lib/participation.d.ts +5 -5
  47. package/lib/participation.d.ts.map +1 -1
  48. package/lib/participation.js +22 -23
  49. package/lib/participation.js.map +1 -1
  50. package/lib/preferences.js +0 -4
  51. package/lib/preferences.js.map +1 -1
  52. package/lib/style.js +35 -30
  53. package/lib/style.js.map +1 -1
  54. package/lib/styleConstants.js +34 -0
  55. package/lib/styleConstants.js.map +1 -0
  56. package/lib/tabs.d.ts +0 -125
  57. package/lib/tabs.d.ts.map +1 -1
  58. package/lib/tabs.js +15 -8
  59. package/lib/tabs.js.map +1 -1
  60. package/lib/utils/headerFooterHelpers.js +0 -2
  61. package/lib/utils/headerFooterHelpers.js.map +1 -1
  62. package/lib/utils/keyHelpers/accessData.d.ts +2 -2
  63. package/lib/utils/keyHelpers/accessData.d.ts.map +1 -1
  64. package/lib/utils/keyHelpers/accessData.js +131 -51
  65. package/lib/utils/keyHelpers/accessData.js.map +1 -1
  66. package/lib/versionInfo.js +6 -6
  67. package/lib/versionInfo.js.map +1 -1
  68. package/lib/widgets/buttons.js +2 -0
  69. package/lib/widgets/buttons.js.map +1 -1
  70. package/lib/widgets/dragAndDrop.js +10 -18
  71. package/lib/widgets/dragAndDrop.js.map +1 -1
  72. package/lib/widgets/error.d.ts.map +1 -1
  73. package/lib/widgets/error.js +9 -2
  74. package/lib/widgets/error.js.map +1 -1
  75. package/lib/widgets/forms/autocomplete/autocompleteBar.js +1 -8
  76. package/lib/widgets/forms/autocomplete/autocompleteBar.js.map +1 -1
  77. package/lib/widgets/forms/autocomplete/autocompletePicker.d.ts.map +1 -1
  78. package/lib/widgets/forms/autocomplete/autocompletePicker.js +5 -9
  79. package/lib/widgets/forms/autocomplete/autocompletePicker.js.map +1 -1
  80. package/lib/widgets/forms/autocomplete/language.js +0 -5
  81. package/lib/widgets/forms/autocomplete/language.js.map +1 -1
  82. package/lib/widgets/forms/basic.d.ts.map +1 -1
  83. package/lib/widgets/forms/basic.js +4 -3
  84. package/lib/widgets/forms/basic.js.map +1 -1
  85. package/lib/widgets/forms/fieldParams.js +2 -2
  86. package/lib/widgets/forms/fieldParams.js.map +1 -1
  87. package/lib/widgets/forms.js +10 -12
  88. package/lib/widgets/forms.js.map +1 -1
  89. package/lib/widgets/peoplePicker.js +0 -11
  90. package/lib/widgets/peoplePicker.js.map +1 -1
  91. package/package.json +2 -5
  92. package/lib/utils/keyHelpers/otherHelpers.d.ts +0 -3
  93. package/lib/utils/keyHelpers/otherHelpers.d.ts.map +0 -1
  94. package/lib/utils/keyHelpers/otherHelpers.js +0 -23
  95. package/lib/utils/keyHelpers/otherHelpers.js.map +0 -1
@@ -485,7 +485,7 @@ module.exports = class RequestQueue {
485
485
  */
486
486
 
487
487
 
488
- const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/jsonld/node_modules/lru-cache/index.js");
488
+ const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/lru-cache/index.js");
489
489
 
490
490
  const MAX_ACTIVE_CONTEXTS = 10;
491
491
 
@@ -6383,7 +6383,7 @@ const util = __webpack_require__(/*! ./util */ "./node_modules/jsonld/lib/util.j
6383
6383
  const ContextResolver = __webpack_require__(/*! ./ContextResolver */ "./node_modules/jsonld/lib/ContextResolver.js");
6384
6384
  const IdentifierIssuer = util.IdentifierIssuer;
6385
6385
  const JsonLdError = __webpack_require__(/*! ./JsonLdError */ "./node_modules/jsonld/lib/JsonLdError.js");
6386
- const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/jsonld/node_modules/lru-cache/index.js");
6386
+ const LRU = __webpack_require__(/*! lru-cache */ "./node_modules/lru-cache/index.js");
6387
6387
  const NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/jsonld/lib/NQuads.js");
6388
6388
 
6389
6389
  const {expand: _expand} = __webpack_require__(/*! ./expand */ "./node_modules/jsonld/lib/expand.js");
@@ -9014,17 +9014,17 @@ function _labelBlankNodes(issuer, element) {
9014
9014
 
9015
9015
  /***/ }),
9016
9016
 
9017
- /***/ "./node_modules/jsonld/node_modules/lru-cache/index.js":
9018
- /*!*************************************************************!*\
9019
- !*** ./node_modules/jsonld/node_modules/lru-cache/index.js ***!
9020
- \*************************************************************/
9017
+ /***/ "./node_modules/lru-cache/index.js":
9018
+ /*!*****************************************!*\
9019
+ !*** ./node_modules/lru-cache/index.js ***!
9020
+ \*****************************************/
9021
9021
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
9022
9022
 
9023
9023
  "use strict";
9024
9024
 
9025
9025
 
9026
9026
  // A linked list to keep track of recently-used-ness
9027
- const Yallist = __webpack_require__(/*! yallist */ "./node_modules/jsonld/node_modules/yallist/yallist.js")
9027
+ const Yallist = __webpack_require__(/*! yallist */ "./node_modules/yallist/yallist.js")
9028
9028
 
9029
9029
  const MAX = Symbol('max')
9030
9030
  const LENGTH = Symbol('length')
@@ -9359,1141 +9359,1223 @@ module.exports = LRUCache
9359
9359
 
9360
9360
  /***/ }),
9361
9361
 
9362
- /***/ "./node_modules/jsonld/node_modules/yallist/iterator.js":
9363
- /*!**************************************************************!*\
9364
- !*** ./node_modules/jsonld/node_modules/yallist/iterator.js ***!
9365
- \**************************************************************/
9366
- /***/ ((module) => {
9367
-
9368
- "use strict";
9362
+ /***/ "./node_modules/rdf-canonize/index.js":
9363
+ /*!********************************************!*\
9364
+ !*** ./node_modules/rdf-canonize/index.js ***!
9365
+ \********************************************/
9366
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
9369
9367
 
9370
- module.exports = function (Yallist) {
9371
- Yallist.prototype[Symbol.iterator] = function* () {
9372
- for (let walker = this.head; walker; walker = walker.next) {
9373
- yield walker.value
9374
- }
9375
- }
9376
- }
9368
+ /**
9369
+ * An implementation of the RDF Dataset Normalization specification.
9370
+ *
9371
+ * @author Dave Longley
9372
+ *
9373
+ * Copyright 2010-2021 Digital Bazaar, Inc.
9374
+ */
9375
+ module.exports = __webpack_require__(/*! ./lib */ "./node_modules/rdf-canonize/lib/index.js");
9377
9376
 
9378
9377
 
9379
9378
  /***/ }),
9380
9379
 
9381
- /***/ "./node_modules/jsonld/node_modules/yallist/yallist.js":
9382
- /*!*************************************************************!*\
9383
- !*** ./node_modules/jsonld/node_modules/yallist/yallist.js ***!
9384
- \*************************************************************/
9385
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
9380
+ /***/ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js":
9381
+ /*!***********************************************************!*\
9382
+ !*** ./node_modules/rdf-canonize/lib/IdentifierIssuer.js ***!
9383
+ \***********************************************************/
9384
+ /***/ ((module) => {
9386
9385
 
9387
9386
  "use strict";
9387
+ /*
9388
+ * Copyright (c) 2016-2021 Digital Bazaar, Inc. All rights reserved.
9389
+ */
9388
9390
 
9389
- module.exports = Yallist
9390
-
9391
- Yallist.Node = Node
9392
- Yallist.create = Yallist
9393
9391
 
9394
- function Yallist (list) {
9395
- var self = this
9396
- if (!(self instanceof Yallist)) {
9397
- self = new Yallist()
9392
+ module.exports = class IdentifierIssuer {
9393
+ /**
9394
+ * Creates a new IdentifierIssuer. A IdentifierIssuer issues unique
9395
+ * identifiers, keeping track of any previously issued identifiers.
9396
+ *
9397
+ * @param prefix the prefix to use ('<prefix><counter>').
9398
+ * @param existing an existing Map to use.
9399
+ * @param counter the counter to use.
9400
+ */
9401
+ constructor(prefix, existing = new Map(), counter = 0) {
9402
+ this.prefix = prefix;
9403
+ this._existing = existing;
9404
+ this.counter = counter;
9398
9405
  }
9399
9406
 
9400
- self.tail = null
9401
- self.head = null
9402
- self.length = 0
9403
-
9404
- if (list && typeof list.forEach === 'function') {
9405
- list.forEach(function (item) {
9406
- self.push(item)
9407
- })
9408
- } else if (arguments.length > 0) {
9409
- for (var i = 0, l = arguments.length; i < l; i++) {
9410
- self.push(arguments[i])
9411
- }
9407
+ /**
9408
+ * Copies this IdentifierIssuer.
9409
+ *
9410
+ * @return a copy of this IdentifierIssuer.
9411
+ */
9412
+ clone() {
9413
+ const {prefix, _existing, counter} = this;
9414
+ return new IdentifierIssuer(prefix, new Map(_existing), counter);
9412
9415
  }
9413
9416
 
9414
- return self
9415
- }
9417
+ /**
9418
+ * Gets the new identifier for the given old identifier, where if no old
9419
+ * identifier is given a new identifier will be generated.
9420
+ *
9421
+ * @param [old] the old identifier to get the new identifier for.
9422
+ *
9423
+ * @return the new identifier.
9424
+ */
9425
+ getId(old) {
9426
+ // return existing old identifier
9427
+ const existing = old && this._existing.get(old);
9428
+ if(existing) {
9429
+ return existing;
9430
+ }
9416
9431
 
9417
- Yallist.prototype.removeNode = function (node) {
9418
- if (node.list !== this) {
9419
- throw new Error('removing node which does not belong to this list')
9420
- }
9432
+ // get next identifier
9433
+ const identifier = this.prefix + this.counter;
9434
+ this.counter++;
9421
9435
 
9422
- var next = node.next
9423
- var prev = node.prev
9436
+ // save mapping
9437
+ if(old) {
9438
+ this._existing.set(old, identifier);
9439
+ }
9424
9440
 
9425
- if (next) {
9426
- next.prev = prev
9441
+ return identifier;
9427
9442
  }
9428
9443
 
9429
- if (prev) {
9430
- prev.next = next
9444
+ /**
9445
+ * Returns true if the given old identifer has already been assigned a new
9446
+ * identifier.
9447
+ *
9448
+ * @param old the old identifier to check.
9449
+ *
9450
+ * @return true if the old identifier has been assigned a new identifier,
9451
+ * false if not.
9452
+ */
9453
+ hasId(old) {
9454
+ return this._existing.has(old);
9431
9455
  }
9432
9456
 
9433
- if (node === this.head) {
9434
- this.head = next
9435
- }
9436
- if (node === this.tail) {
9437
- this.tail = prev
9457
+ /**
9458
+ * Returns all of the IDs that have been issued new IDs in the order in
9459
+ * which they were issued new IDs.
9460
+ *
9461
+ * @return the list of old IDs that has been issued new IDs in order.
9462
+ */
9463
+ getOldIds() {
9464
+ return [...this._existing.keys()];
9438
9465
  }
9466
+ };
9439
9467
 
9440
- node.list.length--
9441
- node.next = null
9442
- node.prev = null
9443
- node.list = null
9444
9468
 
9445
- return next
9446
- }
9469
+ /***/ }),
9447
9470
 
9448
- Yallist.prototype.unshiftNode = function (node) {
9449
- if (node === this.head) {
9450
- return
9451
- }
9471
+ /***/ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js":
9472
+ /*!****************************************************************!*\
9473
+ !*** ./node_modules/rdf-canonize/lib/MessageDigest-browser.js ***!
9474
+ \****************************************************************/
9475
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
9452
9476
 
9453
- if (node.list) {
9454
- node.list.removeNode(node)
9455
- }
9477
+ "use strict";
9478
+ /*!
9479
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
9480
+ */
9456
9481
 
9457
- var head = this.head
9458
- node.list = this
9459
- node.next = head
9460
- if (head) {
9461
- head.prev = node
9462
- }
9463
9482
 
9464
- this.head = node
9465
- if (!this.tail) {
9466
- this.tail = node
9467
- }
9468
- this.length++
9469
- }
9483
+ __webpack_require__(/*! setimmediate */ "./node_modules/setimmediate/setImmediate.js");
9470
9484
 
9471
- Yallist.prototype.pushNode = function (node) {
9472
- if (node === this.tail) {
9473
- return
9474
- }
9485
+ const crypto = self.crypto || self.msCrypto;
9475
9486
 
9476
- if (node.list) {
9477
- node.list.removeNode(node)
9487
+ module.exports = class MessageDigest {
9488
+ /**
9489
+ * Creates a new MessageDigest.
9490
+ *
9491
+ * @param algorithm the algorithm to use.
9492
+ */
9493
+ constructor(algorithm) {
9494
+ // check if crypto.subtle is available
9495
+ // check is here rather than top-level to only fail if class is used
9496
+ if(!(crypto && crypto.subtle)) {
9497
+ throw new Error('crypto.subtle not found.');
9498
+ }
9499
+ if(algorithm === 'sha256') {
9500
+ this.algorithm = {name: 'SHA-256'};
9501
+ } else if(algorithm === 'sha1') {
9502
+ this.algorithm = {name: 'SHA-1'};
9503
+ } else {
9504
+ throw new Error(`Unsupported algorithm "${algorithm}".`);
9505
+ }
9506
+ this._content = '';
9478
9507
  }
9479
9508
 
9480
- var tail = this.tail
9481
- node.list = this
9482
- node.prev = tail
9483
- if (tail) {
9484
- tail.next = node
9509
+ update(msg) {
9510
+ this._content += msg;
9485
9511
  }
9486
9512
 
9487
- this.tail = node
9488
- if (!this.head) {
9489
- this.head = node
9513
+ async digest() {
9514
+ const data = new TextEncoder().encode(this._content);
9515
+ const buffer = new Uint8Array(
9516
+ await crypto.subtle.digest(this.algorithm, data));
9517
+ // return digest in hex
9518
+ let hex = '';
9519
+ for(let i = 0; i < buffer.length; ++i) {
9520
+ hex += buffer[i].toString(16).padStart(2, '0');
9521
+ }
9522
+ return hex;
9490
9523
  }
9491
- this.length++
9492
- }
9524
+ };
9493
9525
 
9494
- Yallist.prototype.push = function () {
9495
- for (var i = 0, l = arguments.length; i < l; i++) {
9496
- push(this, arguments[i])
9497
- }
9498
- return this.length
9499
- }
9500
9526
 
9501
- Yallist.prototype.unshift = function () {
9502
- for (var i = 0, l = arguments.length; i < l; i++) {
9503
- unshift(this, arguments[i])
9504
- }
9505
- return this.length
9506
- }
9527
+ /***/ }),
9507
9528
 
9508
- Yallist.prototype.pop = function () {
9509
- if (!this.tail) {
9510
- return undefined
9511
- }
9529
+ /***/ "./node_modules/rdf-canonize/lib/NQuads.js":
9530
+ /*!*************************************************!*\
9531
+ !*** ./node_modules/rdf-canonize/lib/NQuads.js ***!
9532
+ \*************************************************/
9533
+ /***/ ((module) => {
9512
9534
 
9513
- var res = this.tail.value
9514
- this.tail = this.tail.prev
9515
- if (this.tail) {
9516
- this.tail.next = null
9517
- } else {
9518
- this.head = null
9519
- }
9520
- this.length--
9521
- return res
9522
- }
9535
+ "use strict";
9536
+ /*!
9537
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
9538
+ */
9523
9539
 
9524
- Yallist.prototype.shift = function () {
9525
- if (!this.head) {
9526
- return undefined
9527
- }
9528
9540
 
9529
- var res = this.head.value
9530
- this.head = this.head.next
9531
- if (this.head) {
9532
- this.head.prev = null
9533
- } else {
9534
- this.tail = null
9535
- }
9536
- this.length--
9537
- return res
9538
- }
9539
-
9540
- Yallist.prototype.forEach = function (fn, thisp) {
9541
- thisp = thisp || this
9542
- for (var walker = this.head, i = 0; walker !== null; i++) {
9543
- fn.call(thisp, walker.value, i, this)
9544
- walker = walker.next
9545
- }
9546
- }
9541
+ // eslint-disable-next-line no-unused-vars
9542
+ const TERMS = ['subject', 'predicate', 'object', 'graph'];
9543
+ const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
9544
+ const RDF_LANGSTRING = RDF + 'langString';
9545
+ const XSD_STRING = 'http://www.w3.org/2001/XMLSchema#string';
9547
9546
 
9548
- Yallist.prototype.forEachReverse = function (fn, thisp) {
9549
- thisp = thisp || this
9550
- for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
9551
- fn.call(thisp, walker.value, i, this)
9552
- walker = walker.prev
9553
- }
9554
- }
9547
+ const TYPE_NAMED_NODE = 'NamedNode';
9548
+ const TYPE_BLANK_NODE = 'BlankNode';
9549
+ const TYPE_LITERAL = 'Literal';
9550
+ const TYPE_DEFAULT_GRAPH = 'DefaultGraph';
9555
9551
 
9556
- Yallist.prototype.get = function (n) {
9557
- for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
9558
- // abort out of the list early if we hit a cycle
9559
- walker = walker.next
9560
- }
9561
- if (i === n && walker !== null) {
9562
- return walker.value
9563
- }
9564
- }
9552
+ // build regexes
9553
+ const REGEX = {};
9554
+ (() => {
9555
+ const iri = '(?:<([^:]+:[^>]*)>)';
9556
+ // https://www.w3.org/TR/turtle/#grammar-production-BLANK_NODE_LABEL
9557
+ const PN_CHARS_BASE =
9558
+ 'A-Z' + 'a-z' +
9559
+ '\u00C0-\u00D6' +
9560
+ '\u00D8-\u00F6' +
9561
+ '\u00F8-\u02FF' +
9562
+ '\u0370-\u037D' +
9563
+ '\u037F-\u1FFF' +
9564
+ '\u200C-\u200D' +
9565
+ '\u2070-\u218F' +
9566
+ '\u2C00-\u2FEF' +
9567
+ '\u3001-\uD7FF' +
9568
+ '\uF900-\uFDCF' +
9569
+ '\uFDF0-\uFFFD';
9570
+ // TODO:
9571
+ //'\u10000-\uEFFFF';
9572
+ const PN_CHARS_U =
9573
+ PN_CHARS_BASE +
9574
+ '_';
9575
+ const PN_CHARS =
9576
+ PN_CHARS_U +
9577
+ '0-9' +
9578
+ '-' +
9579
+ '\u00B7' +
9580
+ '\u0300-\u036F' +
9581
+ '\u203F-\u2040';
9582
+ const BLANK_NODE_LABEL =
9583
+ '(_:' +
9584
+ '(?:[' + PN_CHARS_U + '0-9])' +
9585
+ '(?:(?:[' + PN_CHARS + '.])*(?:[' + PN_CHARS + ']))?' +
9586
+ ')';
9587
+ const bnode = BLANK_NODE_LABEL;
9588
+ const plain = '"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"';
9589
+ const datatype = '(?:\\^\\^' + iri + ')';
9590
+ const language = '(?:@([a-zA-Z]+(?:-[a-zA-Z0-9]+)*))';
9591
+ const literal = '(?:' + plain + '(?:' + datatype + '|' + language + ')?)';
9592
+ const ws = '[ \\t]+';
9593
+ const wso = '[ \\t]*';
9565
9594
 
9566
- Yallist.prototype.getReverse = function (n) {
9567
- for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
9568
- // abort out of the list early if we hit a cycle
9569
- walker = walker.prev
9570
- }
9571
- if (i === n && walker !== null) {
9572
- return walker.value
9573
- }
9574
- }
9595
+ // define quad part regexes
9596
+ const subject = '(?:' + iri + '|' + bnode + ')' + ws;
9597
+ const property = iri + ws;
9598
+ const object = '(?:' + iri + '|' + bnode + '|' + literal + ')' + wso;
9599
+ const graphName = '(?:\\.|(?:(?:' + iri + '|' + bnode + ')' + wso + '\\.))';
9575
9600
 
9576
- Yallist.prototype.map = function (fn, thisp) {
9577
- thisp = thisp || this
9578
- var res = new Yallist()
9579
- for (var walker = this.head; walker !== null;) {
9580
- res.push(fn.call(thisp, walker.value, this))
9581
- walker = walker.next
9582
- }
9583
- return res
9584
- }
9601
+ // end of line and empty regexes
9602
+ REGEX.eoln = /(?:\r\n)|(?:\n)|(?:\r)/g;
9603
+ REGEX.empty = new RegExp('^' + wso + '$');
9585
9604
 
9586
- Yallist.prototype.mapReverse = function (fn, thisp) {
9587
- thisp = thisp || this
9588
- var res = new Yallist()
9589
- for (var walker = this.tail; walker !== null;) {
9590
- res.push(fn.call(thisp, walker.value, this))
9591
- walker = walker.prev
9592
- }
9593
- return res
9594
- }
9605
+ // full quad regex
9606
+ REGEX.quad = new RegExp(
9607
+ '^' + wso + subject + property + object + graphName + wso + '$');
9608
+ })();
9595
9609
 
9596
- Yallist.prototype.reduce = function (fn, initial) {
9597
- var acc
9598
- var walker = this.head
9599
- if (arguments.length > 1) {
9600
- acc = initial
9601
- } else if (this.head) {
9602
- walker = this.head.next
9603
- acc = this.head.value
9604
- } else {
9605
- throw new TypeError('Reduce of empty list with no initial value')
9606
- }
9610
+ module.exports = class NQuads {
9611
+ /**
9612
+ * Parses RDF in the form of N-Quads.
9613
+ *
9614
+ * @param input the N-Quads input to parse.
9615
+ *
9616
+ * @return an RDF dataset (an array of quads per http://rdf.js.org/).
9617
+ */
9618
+ static parse(input) {
9619
+ // build RDF dataset
9620
+ const dataset = [];
9607
9621
 
9608
- for (var i = 0; walker !== null; i++) {
9609
- acc = fn(acc, walker.value, i)
9610
- walker = walker.next
9611
- }
9622
+ const graphs = {};
9612
9623
 
9613
- return acc
9614
- }
9624
+ // split N-Quad input into lines
9625
+ const lines = input.split(REGEX.eoln);
9626
+ let lineNumber = 0;
9627
+ for(const line of lines) {
9628
+ lineNumber++;
9615
9629
 
9616
- Yallist.prototype.reduceReverse = function (fn, initial) {
9617
- var acc
9618
- var walker = this.tail
9619
- if (arguments.length > 1) {
9620
- acc = initial
9621
- } else if (this.tail) {
9622
- walker = this.tail.prev
9623
- acc = this.tail.value
9624
- } else {
9625
- throw new TypeError('Reduce of empty list with no initial value')
9626
- }
9630
+ // skip empty lines
9631
+ if(REGEX.empty.test(line)) {
9632
+ continue;
9633
+ }
9627
9634
 
9628
- for (var i = this.length - 1; walker !== null; i--) {
9629
- acc = fn(acc, walker.value, i)
9630
- walker = walker.prev
9631
- }
9635
+ // parse quad
9636
+ const match = line.match(REGEX.quad);
9637
+ if(match === null) {
9638
+ throw new Error('N-Quads parse error on line ' + lineNumber + '.');
9639
+ }
9632
9640
 
9633
- return acc
9634
- }
9641
+ // create RDF quad
9642
+ const quad = {subject: null, predicate: null, object: null, graph: null};
9635
9643
 
9636
- Yallist.prototype.toArray = function () {
9637
- var arr = new Array(this.length)
9638
- for (var i = 0, walker = this.head; walker !== null; i++) {
9639
- arr[i] = walker.value
9640
- walker = walker.next
9641
- }
9642
- return arr
9643
- }
9644
+ // get subject
9645
+ if(match[1] !== undefined) {
9646
+ quad.subject = {termType: TYPE_NAMED_NODE, value: match[1]};
9647
+ } else {
9648
+ quad.subject = {termType: TYPE_BLANK_NODE, value: match[2]};
9649
+ }
9644
9650
 
9645
- Yallist.prototype.toArrayReverse = function () {
9646
- var arr = new Array(this.length)
9647
- for (var i = 0, walker = this.tail; walker !== null; i++) {
9648
- arr[i] = walker.value
9649
- walker = walker.prev
9650
- }
9651
- return arr
9652
- }
9651
+ // get predicate
9652
+ quad.predicate = {termType: TYPE_NAMED_NODE, value: match[3]};
9653
9653
 
9654
- Yallist.prototype.slice = function (from, to) {
9655
- to = to || this.length
9656
- if (to < 0) {
9657
- to += this.length
9658
- }
9659
- from = from || 0
9660
- if (from < 0) {
9661
- from += this.length
9662
- }
9663
- var ret = new Yallist()
9664
- if (to < from || to < 0) {
9665
- return ret
9666
- }
9667
- if (from < 0) {
9668
- from = 0
9669
- }
9670
- if (to > this.length) {
9671
- to = this.length
9672
- }
9673
- for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
9674
- walker = walker.next
9675
- }
9676
- for (; walker !== null && i < to; i++, walker = walker.next) {
9677
- ret.push(walker.value)
9678
- }
9679
- return ret
9680
- }
9654
+ // get object
9655
+ if(match[4] !== undefined) {
9656
+ quad.object = {termType: TYPE_NAMED_NODE, value: match[4]};
9657
+ } else if(match[5] !== undefined) {
9658
+ quad.object = {termType: TYPE_BLANK_NODE, value: match[5]};
9659
+ } else {
9660
+ quad.object = {
9661
+ termType: TYPE_LITERAL,
9662
+ value: undefined,
9663
+ datatype: {
9664
+ termType: TYPE_NAMED_NODE
9665
+ }
9666
+ };
9667
+ if(match[7] !== undefined) {
9668
+ quad.object.datatype.value = match[7];
9669
+ } else if(match[8] !== undefined) {
9670
+ quad.object.datatype.value = RDF_LANGSTRING;
9671
+ quad.object.language = match[8];
9672
+ } else {
9673
+ quad.object.datatype.value = XSD_STRING;
9674
+ }
9675
+ quad.object.value = _unescape(match[6]);
9676
+ }
9681
9677
 
9682
- Yallist.prototype.sliceReverse = function (from, to) {
9683
- to = to || this.length
9684
- if (to < 0) {
9685
- to += this.length
9686
- }
9687
- from = from || 0
9688
- if (from < 0) {
9689
- from += this.length
9690
- }
9691
- var ret = new Yallist()
9692
- if (to < from || to < 0) {
9693
- return ret
9694
- }
9695
- if (from < 0) {
9696
- from = 0
9697
- }
9698
- if (to > this.length) {
9699
- to = this.length
9700
- }
9701
- for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
9702
- walker = walker.prev
9703
- }
9704
- for (; walker !== null && i > from; i--, walker = walker.prev) {
9705
- ret.push(walker.value)
9706
- }
9707
- return ret
9708
- }
9678
+ // get graph
9679
+ if(match[9] !== undefined) {
9680
+ quad.graph = {
9681
+ termType: TYPE_NAMED_NODE,
9682
+ value: match[9]
9683
+ };
9684
+ } else if(match[10] !== undefined) {
9685
+ quad.graph = {
9686
+ termType: TYPE_BLANK_NODE,
9687
+ value: match[10]
9688
+ };
9689
+ } else {
9690
+ quad.graph = {
9691
+ termType: TYPE_DEFAULT_GRAPH,
9692
+ value: ''
9693
+ };
9694
+ }
9709
9695
 
9710
- Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
9711
- if (start > this.length) {
9712
- start = this.length - 1
9713
- }
9714
- if (start < 0) {
9715
- start = this.length + start;
9716
- }
9696
+ // only add quad if it is unique in its graph
9697
+ if(!(quad.graph.value in graphs)) {
9698
+ graphs[quad.graph.value] = [quad];
9699
+ dataset.push(quad);
9700
+ } else {
9701
+ let unique = true;
9702
+ const quads = graphs[quad.graph.value];
9703
+ for(const q of quads) {
9704
+ if(_compareTriples(q, quad)) {
9705
+ unique = false;
9706
+ break;
9707
+ }
9708
+ }
9709
+ if(unique) {
9710
+ quads.push(quad);
9711
+ dataset.push(quad);
9712
+ }
9713
+ }
9714
+ }
9717
9715
 
9718
- for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
9719
- walker = walker.next
9716
+ return dataset;
9720
9717
  }
9721
9718
 
9722
- var ret = []
9723
- for (var i = 0; walker && i < deleteCount; i++) {
9724
- ret.push(walker.value)
9725
- walker = this.removeNode(walker)
9726
- }
9727
- if (walker === null) {
9728
- walker = this.tail
9719
+ /**
9720
+ * Converts an RDF dataset to N-Quads.
9721
+ *
9722
+ * @param dataset (array of quads) the RDF dataset to convert.
9723
+ *
9724
+ * @return the N-Quads string.
9725
+ */
9726
+ static serialize(dataset) {
9727
+ if(!Array.isArray(dataset)) {
9728
+ dataset = NQuads.legacyDatasetToQuads(dataset);
9729
+ }
9730
+ const quads = [];
9731
+ for(const quad of dataset) {
9732
+ quads.push(NQuads.serializeQuad(quad));
9733
+ }
9734
+ return quads.sort().join('');
9729
9735
  }
9730
9736
 
9731
- if (walker !== this.head && walker !== this.tail) {
9732
- walker = walker.prev
9733
- }
9737
+ /**
9738
+ * Converts RDF quad components to an N-Quad string (a single quad).
9739
+ *
9740
+ * @param {Object} s - N-Quad subject component.
9741
+ * @param {Object} p - N-Quad predicate component.
9742
+ * @param {Object} o - N-Quad object component.
9743
+ * @param {Object} g - N-Quad graph component.
9744
+ *
9745
+ * @return {string} the N-Quad.
9746
+ */
9747
+ static serializeQuadComponents(s, p, o, g) {
9748
+ let nquad = '';
9734
9749
 
9735
- for (var i = 0; i < nodes.length; i++) {
9736
- walker = insert(this, walker, nodes[i])
9737
- }
9738
- return ret;
9739
- }
9750
+ // subject can only be NamedNode or BlankNode
9751
+ if(s.termType === TYPE_NAMED_NODE) {
9752
+ nquad += `<${s.value}>`;
9753
+ } else {
9754
+ nquad += `${s.value}`;
9755
+ }
9740
9756
 
9741
- Yallist.prototype.reverse = function () {
9742
- var head = this.head
9743
- var tail = this.tail
9744
- for (var walker = head; walker !== null; walker = walker.prev) {
9745
- var p = walker.prev
9746
- walker.prev = walker.next
9747
- walker.next = p
9748
- }
9749
- this.head = tail
9750
- this.tail = head
9751
- return this
9752
- }
9757
+ // predicate can only be NamedNode
9758
+ nquad += ` <${p.value}> `;
9753
9759
 
9754
- function insert (self, node, value) {
9755
- var inserted = node === self.head ?
9756
- new Node(value, null, node, self) :
9757
- new Node(value, node, node.next, self)
9760
+ // object is NamedNode, BlankNode, or Literal
9761
+ if(o.termType === TYPE_NAMED_NODE) {
9762
+ nquad += `<${o.value}>`;
9763
+ } else if(o.termType === TYPE_BLANK_NODE) {
9764
+ nquad += o.value;
9765
+ } else {
9766
+ nquad += `"${_escape(o.value)}"`;
9767
+ if(o.datatype.value === RDF_LANGSTRING) {
9768
+ if(o.language) {
9769
+ nquad += `@${o.language}`;
9770
+ }
9771
+ } else if(o.datatype.value !== XSD_STRING) {
9772
+ nquad += `^^<${o.datatype.value}>`;
9773
+ }
9774
+ }
9758
9775
 
9759
- if (inserted.next === null) {
9760
- self.tail = inserted
9776
+ // graph can only be NamedNode or BlankNode (or DefaultGraph, but that
9777
+ // does not add to `nquad`)
9778
+ if(g.termType === TYPE_NAMED_NODE) {
9779
+ nquad += ` <${g.value}>`;
9780
+ } else if(g.termType === TYPE_BLANK_NODE) {
9781
+ nquad += ` ${g.value}`;
9782
+ }
9783
+
9784
+ nquad += ' .\n';
9785
+ return nquad;
9761
9786
  }
9762
- if (inserted.prev === null) {
9763
- self.head = inserted
9787
+
9788
+ /**
9789
+ * Converts an RDF quad to an N-Quad string (a single quad).
9790
+ *
9791
+ * @param quad the RDF quad convert.
9792
+ *
9793
+ * @return the N-Quad string.
9794
+ */
9795
+ static serializeQuad(quad) {
9796
+ return NQuads.serializeQuadComponents(
9797
+ quad.subject, quad.predicate, quad.object, quad.graph);
9764
9798
  }
9765
9799
 
9766
- self.length++
9800
+ /**
9801
+ * Converts a legacy-formatted dataset to an array of quads dataset per
9802
+ * http://rdf.js.org/.
9803
+ *
9804
+ * @param dataset the legacy dataset to convert.
9805
+ *
9806
+ * @return the array of quads dataset.
9807
+ */
9808
+ static legacyDatasetToQuads(dataset) {
9809
+ const quads = [];
9767
9810
 
9768
- return inserted
9769
- }
9811
+ const termTypeMap = {
9812
+ 'blank node': TYPE_BLANK_NODE,
9813
+ IRI: TYPE_NAMED_NODE,
9814
+ literal: TYPE_LITERAL
9815
+ };
9770
9816
 
9771
- function push (self, item) {
9772
- self.tail = new Node(item, self.tail, null, self)
9773
- if (!self.head) {
9774
- self.head = self.tail
9775
- }
9776
- self.length++
9777
- }
9817
+ for(const graphName in dataset) {
9818
+ const triples = dataset[graphName];
9819
+ triples.forEach(triple => {
9820
+ const quad = {};
9821
+ for(const componentName in triple) {
9822
+ const oldComponent = triple[componentName];
9823
+ const newComponent = {
9824
+ termType: termTypeMap[oldComponent.type],
9825
+ value: oldComponent.value
9826
+ };
9827
+ if(newComponent.termType === TYPE_LITERAL) {
9828
+ newComponent.datatype = {
9829
+ termType: TYPE_NAMED_NODE
9830
+ };
9831
+ if('datatype' in oldComponent) {
9832
+ newComponent.datatype.value = oldComponent.datatype;
9833
+ }
9834
+ if('language' in oldComponent) {
9835
+ if(!('datatype' in oldComponent)) {
9836
+ newComponent.datatype.value = RDF_LANGSTRING;
9837
+ }
9838
+ newComponent.language = oldComponent.language;
9839
+ } else if(!('datatype' in oldComponent)) {
9840
+ newComponent.datatype.value = XSD_STRING;
9841
+ }
9842
+ }
9843
+ quad[componentName] = newComponent;
9844
+ }
9845
+ if(graphName === '@default') {
9846
+ quad.graph = {
9847
+ termType: TYPE_DEFAULT_GRAPH,
9848
+ value: ''
9849
+ };
9850
+ } else {
9851
+ quad.graph = {
9852
+ termType: graphName.startsWith('_:') ?
9853
+ TYPE_BLANK_NODE : TYPE_NAMED_NODE,
9854
+ value: graphName
9855
+ };
9856
+ }
9857
+ quads.push(quad);
9858
+ });
9859
+ }
9778
9860
 
9779
- function unshift (self, item) {
9780
- self.head = new Node(item, null, self.head, self)
9781
- if (!self.tail) {
9782
- self.tail = self.head
9861
+ return quads;
9783
9862
  }
9784
- self.length++
9785
- }
9863
+ };
9786
9864
 
9787
- function Node (value, prev, next, list) {
9788
- if (!(this instanceof Node)) {
9789
- return new Node(value, prev, next, list)
9865
+ /**
9866
+ * Compares two RDF triples for equality.
9867
+ *
9868
+ * @param t1 the first triple.
9869
+ * @param t2 the second triple.
9870
+ *
9871
+ * @return true if the triples are the same, false if not.
9872
+ */
9873
+ function _compareTriples(t1, t2) {
9874
+ // compare subject and object types first as it is the quickest check
9875
+ if(!(t1.subject.termType === t2.subject.termType &&
9876
+ t1.object.termType === t2.object.termType)) {
9877
+ return false;
9790
9878
  }
9791
-
9792
- this.list = list
9793
- this.value = value
9794
-
9795
- if (prev) {
9796
- prev.next = this
9797
- this.prev = prev
9798
- } else {
9799
- this.prev = null
9879
+ // compare values
9880
+ if(!(t1.subject.value === t2.subject.value &&
9881
+ t1.predicate.value === t2.predicate.value &&
9882
+ t1.object.value === t2.object.value)) {
9883
+ return false;
9800
9884
  }
9801
-
9802
- if (next) {
9803
- next.prev = this
9804
- this.next = next
9805
- } else {
9806
- this.next = null
9885
+ if(t1.object.termType !== TYPE_LITERAL) {
9886
+ // no `datatype` or `language` to check
9887
+ return true;
9807
9888
  }
9889
+ return (
9890
+ (t1.object.datatype.termType === t2.object.datatype.termType) &&
9891
+ (t1.object.language === t2.object.language) &&
9892
+ (t1.object.datatype.value === t2.object.datatype.value)
9893
+ );
9808
9894
  }
9809
9895
 
9810
- try {
9811
- // add if support for Symbol.iterator is present
9812
- __webpack_require__(/*! ./iterator.js */ "./node_modules/jsonld/node_modules/yallist/iterator.js")(Yallist)
9813
- } catch (er) {}
9814
-
9815
-
9816
- /***/ }),
9817
-
9818
- /***/ "./node_modules/rdf-canonize/index.js":
9819
- /*!********************************************!*\
9820
- !*** ./node_modules/rdf-canonize/index.js ***!
9821
- \********************************************/
9822
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
9896
+ const _escapeRegex = /["\\\n\r]/g;
9897
+ /**
9898
+ * Escape string to N-Quads literal
9899
+ */
9900
+ function _escape(s) {
9901
+ return s.replace(_escapeRegex, function(match) {
9902
+ switch(match) {
9903
+ case '"': return '\\"';
9904
+ case '\\': return '\\\\';
9905
+ case '\n': return '\\n';
9906
+ case '\r': return '\\r';
9907
+ }
9908
+ });
9909
+ }
9823
9910
 
9911
+ const _unescapeRegex =
9912
+ /(?:\\([tbnrf"'\\]))|(?:\\u([0-9A-Fa-f]{4}))|(?:\\U([0-9A-Fa-f]{8}))/g;
9824
9913
  /**
9825
- * An implementation of the RDF Dataset Normalization specification.
9826
- *
9827
- * @author Dave Longley
9828
- *
9829
- * Copyright 2010-2021 Digital Bazaar, Inc.
9914
+ * Unescape N-Quads literal to string
9830
9915
  */
9831
- module.exports = __webpack_require__(/*! ./lib */ "./node_modules/rdf-canonize/lib/index.js");
9916
+ function _unescape(s) {
9917
+ return s.replace(_unescapeRegex, function(match, code, u, U) {
9918
+ if(code) {
9919
+ switch(code) {
9920
+ case 't': return '\t';
9921
+ case 'b': return '\b';
9922
+ case 'n': return '\n';
9923
+ case 'r': return '\r';
9924
+ case 'f': return '\f';
9925
+ case '"': return '"';
9926
+ case '\'': return '\'';
9927
+ case '\\': return '\\';
9928
+ }
9929
+ }
9930
+ if(u) {
9931
+ return String.fromCharCode(parseInt(u, 16));
9932
+ }
9933
+ if(U) {
9934
+ // FIXME: support larger values
9935
+ throw new Error('Unsupported U escape');
9936
+ }
9937
+ });
9938
+ }
9832
9939
 
9833
9940
 
9834
9941
  /***/ }),
9835
9942
 
9836
- /***/ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js":
9837
- /*!***********************************************************!*\
9838
- !*** ./node_modules/rdf-canonize/lib/IdentifierIssuer.js ***!
9839
- \***********************************************************/
9943
+ /***/ "./node_modules/rdf-canonize/lib/Permuter.js":
9944
+ /*!***************************************************!*\
9945
+ !*** ./node_modules/rdf-canonize/lib/Permuter.js ***!
9946
+ \***************************************************/
9840
9947
  /***/ ((module) => {
9841
9948
 
9842
9949
  "use strict";
9843
- /*
9844
- * Copyright (c) 2016-2021 Digital Bazaar, Inc. All rights reserved.
9950
+ /*!
9951
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
9845
9952
  */
9846
9953
 
9847
9954
 
9848
- module.exports = class IdentifierIssuer {
9955
+ module.exports = class Permuter {
9849
9956
  /**
9850
- * Creates a new IdentifierIssuer. A IdentifierIssuer issues unique
9851
- * identifiers, keeping track of any previously issued identifiers.
9957
+ * A Permuter iterates over all possible permutations of the given array
9958
+ * of elements.
9852
9959
  *
9853
- * @param prefix the prefix to use ('<prefix><counter>').
9854
- * @param existing an existing Map to use.
9855
- * @param counter the counter to use.
9960
+ * @param list the array of elements to iterate over.
9856
9961
  */
9857
- constructor(prefix, existing = new Map(), counter = 0) {
9858
- this.prefix = prefix;
9859
- this._existing = existing;
9860
- this.counter = counter;
9962
+ constructor(list) {
9963
+ // original array
9964
+ this.current = list.sort();
9965
+ // indicates whether there are more permutations
9966
+ this.done = false;
9967
+ // directional info for permutation algorithm
9968
+ this.dir = new Map();
9969
+ for(let i = 0; i < list.length; ++i) {
9970
+ this.dir.set(list[i], true);
9971
+ }
9861
9972
  }
9862
9973
 
9863
9974
  /**
9864
- * Copies this IdentifierIssuer.
9975
+ * Returns true if there is another permutation.
9865
9976
  *
9866
- * @return a copy of this IdentifierIssuer.
9977
+ * @return true if there is another permutation, false if not.
9867
9978
  */
9868
- clone() {
9869
- const {prefix, _existing, counter} = this;
9870
- return new IdentifierIssuer(prefix, new Map(_existing), counter);
9979
+ hasNext() {
9980
+ return !this.done;
9871
9981
  }
9872
9982
 
9873
9983
  /**
9874
- * Gets the new identifier for the given old identifier, where if no old
9875
- * identifier is given a new identifier will be generated.
9876
- *
9877
- * @param [old] the old identifier to get the new identifier for.
9984
+ * Gets the next permutation. Call hasNext() to ensure there is another one
9985
+ * first.
9878
9986
  *
9879
- * @return the new identifier.
9987
+ * @return the next permutation.
9880
9988
  */
9881
- getId(old) {
9882
- // return existing old identifier
9883
- const existing = old && this._existing.get(old);
9884
- if(existing) {
9885
- return existing;
9989
+ next() {
9990
+ // copy current permutation to return it
9991
+ const {current, dir} = this;
9992
+ const rval = current.slice();
9993
+
9994
+ /* Calculate the next permutation using the Steinhaus-Johnson-Trotter
9995
+ permutation algorithm. */
9996
+
9997
+ // get largest mobile element k
9998
+ // (mobile: element is greater than the one it is looking at)
9999
+ let k = null;
10000
+ let pos = 0;
10001
+ const length = current.length;
10002
+ for(let i = 0; i < length; ++i) {
10003
+ const element = current[i];
10004
+ const left = dir.get(element);
10005
+ if((k === null || element > k) &&
10006
+ ((left && i > 0 && element > current[i - 1]) ||
10007
+ (!left && i < (length - 1) && element > current[i + 1]))) {
10008
+ k = element;
10009
+ pos = i;
10010
+ }
9886
10011
  }
9887
10012
 
9888
- // get next identifier
9889
- const identifier = this.prefix + this.counter;
9890
- this.counter++;
10013
+ // no more permutations
10014
+ if(k === null) {
10015
+ this.done = true;
10016
+ } else {
10017
+ // swap k and the element it is looking at
10018
+ const swap = dir.get(k) ? pos - 1 : pos + 1;
10019
+ current[pos] = current[swap];
10020
+ current[swap] = k;
9891
10021
 
9892
- // save mapping
9893
- if(old) {
9894
- this._existing.set(old, identifier);
10022
+ // reverse the direction of all elements larger than k
10023
+ for(const element of current) {
10024
+ if(element > k) {
10025
+ dir.set(element, !dir.get(element));
10026
+ }
10027
+ }
9895
10028
  }
9896
10029
 
9897
- return identifier;
10030
+ return rval;
9898
10031
  }
10032
+ };
9899
10033
 
9900
- /**
9901
- * Returns true if the given old identifer has already been assigned a new
9902
- * identifier.
9903
- *
9904
- * @param old the old identifier to check.
9905
- *
9906
- * @return true if the old identifier has been assigned a new identifier,
9907
- * false if not.
9908
- */
9909
- hasId(old) {
9910
- return this._existing.has(old);
9911
- }
9912
10034
 
9913
- /**
9914
- * Returns all of the IDs that have been issued new IDs in the order in
9915
- * which they were issued new IDs.
9916
- *
9917
- * @return the list of old IDs that has been issued new IDs in order.
9918
- */
9919
- getOldIds() {
9920
- return [...this._existing.keys()];
10035
+ /***/ }),
10036
+
10037
+ /***/ "./node_modules/rdf-canonize/lib/URDNA2015.js":
10038
+ /*!****************************************************!*\
10039
+ !*** ./node_modules/rdf-canonize/lib/URDNA2015.js ***!
10040
+ \****************************************************/
10041
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
10042
+
10043
+ "use strict";
10044
+ /*!
10045
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
10046
+ */
10047
+
10048
+
10049
+ const IdentifierIssuer = __webpack_require__(/*! ./IdentifierIssuer */ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js");
10050
+ const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
10051
+ const Permuter = __webpack_require__(/*! ./Permuter */ "./node_modules/rdf-canonize/lib/Permuter.js");
10052
+ const NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/rdf-canonize/lib/NQuads.js");
10053
+
10054
+ module.exports = class URDNA2015 {
10055
+ constructor({
10056
+ createMessageDigest = () => new MessageDigest('sha256'),
10057
+ maxDeepIterations = Infinity
10058
+ } = {}) {
10059
+ this.name = 'URDNA2015';
10060
+ this.blankNodeInfo = new Map();
10061
+ this.canonicalIssuer = new IdentifierIssuer('_:c14n');
10062
+ this.createMessageDigest = createMessageDigest;
10063
+ this.maxDeepIterations = maxDeepIterations;
10064
+ this.quads = null;
10065
+ this.deepIterations = null;
9921
10066
  }
9922
- };
9923
10067
 
10068
+ // 4.4) Normalization Algorithm
10069
+ async main(dataset) {
10070
+ this.deepIterations = new Map();
10071
+ this.quads = dataset;
10072
+
10073
+ // 1) Create the normalization state.
10074
+ // 2) For every quad in input dataset:
10075
+ for(const quad of dataset) {
10076
+ // 2.1) For each blank node that occurs in the quad, add a reference
10077
+ // to the quad using the blank node identifier in the blank node to
10078
+ // quads map, creating a new entry if necessary.
10079
+ this._addBlankNodeQuadInfo({quad, component: quad.subject});
10080
+ this._addBlankNodeQuadInfo({quad, component: quad.object});
10081
+ this._addBlankNodeQuadInfo({quad, component: quad.graph});
10082
+ }
10083
+
10084
+ // 3) Create a list of non-normalized blank node identifiers
10085
+ // non-normalized identifiers and populate it using the keys from the
10086
+ // blank node to quads map.
10087
+ // Note: We use a map here and it was generated during step 2.
10088
+
10089
+ // 4) `simple` flag is skipped -- loop is optimized away. This optimization
10090
+ // is permitted because there was a typo in the hash first degree quads
10091
+ // algorithm in the URDNA2015 spec that was implemented widely making it
10092
+ // such that it could not be fixed; the result was that the loop only
10093
+ // needs to be run once and the first degree quad hashes will never change.
10094
+ // 5.1-5.2 are skipped; first degree quad hashes are generated just once
10095
+ // for all non-normalized blank nodes.
10096
+
10097
+ // 5.3) For each blank node identifier identifier in non-normalized
10098
+ // identifiers:
10099
+ const hashToBlankNodes = new Map();
10100
+ const nonNormalized = [...this.blankNodeInfo.keys()];
10101
+ let i = 0;
10102
+ for(const id of nonNormalized) {
10103
+ // Note: batch hashing first degree quads 100 at a time
10104
+ if(++i % 100 === 0) {
10105
+ await this._yield();
10106
+ }
10107
+ // steps 5.3.1 and 5.3.2:
10108
+ await this._hashAndTrackBlankNode({id, hashToBlankNodes});
10109
+ }
9924
10110
 
9925
- /***/ }),
10111
+ // 5.4) For each hash to identifier list mapping in hash to blank
10112
+ // nodes map, lexicographically-sorted by hash:
10113
+ const hashes = [...hashToBlankNodes.keys()].sort();
10114
+ // optimize away second sort, gather non-unique hashes in order as we go
10115
+ const nonUnique = [];
10116
+ for(const hash of hashes) {
10117
+ // 5.4.1) If the length of identifier list is greater than 1,
10118
+ // continue to the next mapping.
10119
+ const idList = hashToBlankNodes.get(hash);
10120
+ if(idList.length > 1) {
10121
+ nonUnique.push(idList);
10122
+ continue;
10123
+ }
9926
10124
 
9927
- /***/ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js":
9928
- /*!****************************************************************!*\
9929
- !*** ./node_modules/rdf-canonize/lib/MessageDigest-browser.js ***!
9930
- \****************************************************************/
9931
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
10125
+ // 5.4.2) Use the Issue Identifier algorithm, passing canonical
10126
+ // issuer and the single blank node identifier in identifier
10127
+ // list, identifier, to issue a canonical replacement identifier
10128
+ // for identifier.
10129
+ const id = idList[0];
10130
+ this.canonicalIssuer.getId(id);
9932
10131
 
9933
- "use strict";
9934
- /*!
9935
- * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
9936
- */
10132
+ // Note: These steps are skipped, optimized away since the loop
10133
+ // only needs to be run once.
10134
+ // 5.4.3) Remove identifier from non-normalized identifiers.
10135
+ // 5.4.4) Remove hash from the hash to blank nodes map.
10136
+ // 5.4.5) Set simple to true.
10137
+ }
9937
10138
 
10139
+ // 6) For each hash to identifier list mapping in hash to blank nodes map,
10140
+ // lexicographically-sorted by hash:
10141
+ // Note: sort optimized away, use `nonUnique`.
10142
+ for(const idList of nonUnique) {
10143
+ // 6.1) Create hash path list where each item will be a result of
10144
+ // running the Hash N-Degree Quads algorithm.
10145
+ const hashPathList = [];
9938
10146
 
9939
- __webpack_require__(/*! setimmediate */ "./node_modules/setimmediate/setImmediate.js");
10147
+ // 6.2) For each blank node identifier identifier in identifier list:
10148
+ for(const id of idList) {
10149
+ // 6.2.1) If a canonical identifier has already been issued for
10150
+ // identifier, continue to the next identifier.
10151
+ if(this.canonicalIssuer.hasId(id)) {
10152
+ continue;
10153
+ }
9940
10154
 
9941
- const crypto = self.crypto || self.msCrypto;
10155
+ // 6.2.2) Create temporary issuer, an identifier issuer
10156
+ // initialized with the prefix _:b.
10157
+ const issuer = new IdentifierIssuer('_:b');
9942
10158
 
9943
- module.exports = class MessageDigest {
9944
- /**
9945
- * Creates a new MessageDigest.
9946
- *
9947
- * @param algorithm the algorithm to use.
9948
- */
9949
- constructor(algorithm) {
9950
- // check if crypto.subtle is available
9951
- // check is here rather than top-level to only fail if class is used
9952
- if(!(crypto && crypto.subtle)) {
9953
- throw new Error('crypto.subtle not found.');
9954
- }
9955
- if(algorithm === 'sha256') {
9956
- this.algorithm = {name: 'SHA-256'};
9957
- } else if(algorithm === 'sha1') {
9958
- this.algorithm = {name: 'SHA-1'};
9959
- } else {
9960
- throw new Error(`Unsupported algorithm "${algorithm}".`);
9961
- }
9962
- this._content = '';
9963
- }
10159
+ // 6.2.3) Use the Issue Identifier algorithm, passing temporary
10160
+ // issuer and identifier, to issue a new temporary blank node
10161
+ // identifier for identifier.
10162
+ issuer.getId(id);
9964
10163
 
9965
- update(msg) {
9966
- this._content += msg;
9967
- }
10164
+ // 6.2.4) Run the Hash N-Degree Quads algorithm, passing
10165
+ // temporary issuer, and append the result to the hash path list.
10166
+ const result = await this.hashNDegreeQuads(id, issuer);
10167
+ hashPathList.push(result);
10168
+ }
9968
10169
 
9969
- async digest() {
9970
- const data = new TextEncoder().encode(this._content);
9971
- const buffer = new Uint8Array(
9972
- await crypto.subtle.digest(this.algorithm, data));
9973
- // return digest in hex
9974
- let hex = '';
9975
- for(let i = 0; i < buffer.length; ++i) {
9976
- hex += buffer[i].toString(16).padStart(2, '0');
10170
+ // 6.3) For each result in the hash path list,
10171
+ // lexicographically-sorted by the hash in result:
10172
+ hashPathList.sort(_stringHashCompare);
10173
+ for(const result of hashPathList) {
10174
+ // 6.3.1) For each blank node identifier, existing identifier,
10175
+ // that was issued a temporary identifier by identifier issuer
10176
+ // in result, issue a canonical identifier, in the same order,
10177
+ // using the Issue Identifier algorithm, passing canonical
10178
+ // issuer and existing identifier.
10179
+ const oldIds = result.issuer.getOldIds();
10180
+ for(const id of oldIds) {
10181
+ this.canonicalIssuer.getId(id);
10182
+ }
10183
+ }
9977
10184
  }
9978
- return hex;
9979
- }
9980
- };
9981
-
9982
10185
 
9983
- /***/ }),
10186
+ /* Note: At this point all blank nodes in the set of RDF quads have been
10187
+ assigned canonical identifiers, which have been stored in the canonical
10188
+ issuer. Here each quad is updated by assigning each of its blank nodes
10189
+ its new identifier. */
9984
10190
 
9985
- /***/ "./node_modules/rdf-canonize/lib/NQuads.js":
9986
- /*!*************************************************!*\
9987
- !*** ./node_modules/rdf-canonize/lib/NQuads.js ***!
9988
- \*************************************************/
9989
- /***/ ((module) => {
10191
+ // 7) For each quad, quad, in input dataset:
10192
+ const normalized = [];
10193
+ for(const quad of this.quads) {
10194
+ // 7.1) Create a copy, quad copy, of quad and replace any existing
10195
+ // blank node identifiers using the canonical identifiers
10196
+ // previously issued by canonical issuer.
10197
+ // Note: We optimize away the copy here.
10198
+ const nQuad = NQuads.serializeQuadComponents(
10199
+ this._componentWithCanonicalId(quad.subject),
10200
+ quad.predicate,
10201
+ this._componentWithCanonicalId(quad.object),
10202
+ this._componentWithCanonicalId(quad.graph)
10203
+ );
10204
+ // 7.2) Add quad copy to the normalized dataset.
10205
+ normalized.push(nQuad);
10206
+ }
9990
10207
 
9991
- "use strict";
9992
- /*!
9993
- * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
9994
- */
10208
+ // sort normalized output
10209
+ normalized.sort();
9995
10210
 
10211
+ // 8) Return the normalized dataset.
10212
+ return normalized.join('');
10213
+ }
9996
10214
 
9997
- // eslint-disable-next-line no-unused-vars
9998
- const TERMS = ['subject', 'predicate', 'object', 'graph'];
9999
- const RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';
10000
- const RDF_LANGSTRING = RDF + 'langString';
10001
- const XSD_STRING = 'http://www.w3.org/2001/XMLSchema#string';
10215
+ // 4.6) Hash First Degree Quads
10216
+ async hashFirstDegreeQuads(id) {
10217
+ // 1) Initialize nquads to an empty list. It will be used to store quads in
10218
+ // N-Quads format.
10219
+ const nquads = [];
10002
10220
 
10003
- const TYPE_NAMED_NODE = 'NamedNode';
10004
- const TYPE_BLANK_NODE = 'BlankNode';
10005
- const TYPE_LITERAL = 'Literal';
10006
- const TYPE_DEFAULT_GRAPH = 'DefaultGraph';
10221
+ // 2) Get the list of quads `quads` associated with the reference blank node
10222
+ // identifier in the blank node to quads map.
10223
+ const info = this.blankNodeInfo.get(id);
10224
+ const quads = info.quads;
10007
10225
 
10008
- // build regexes
10009
- const REGEX = {};
10010
- (() => {
10011
- const iri = '(?:<([^:]+:[^>]*)>)';
10012
- // https://www.w3.org/TR/turtle/#grammar-production-BLANK_NODE_LABEL
10013
- const PN_CHARS_BASE =
10014
- 'A-Z' + 'a-z' +
10015
- '\u00C0-\u00D6' +
10016
- '\u00D8-\u00F6' +
10017
- '\u00F8-\u02FF' +
10018
- '\u0370-\u037D' +
10019
- '\u037F-\u1FFF' +
10020
- '\u200C-\u200D' +
10021
- '\u2070-\u218F' +
10022
- '\u2C00-\u2FEF' +
10023
- '\u3001-\uD7FF' +
10024
- '\uF900-\uFDCF' +
10025
- '\uFDF0-\uFFFD';
10026
- // TODO:
10027
- //'\u10000-\uEFFFF';
10028
- const PN_CHARS_U =
10029
- PN_CHARS_BASE +
10030
- '_';
10031
- const PN_CHARS =
10032
- PN_CHARS_U +
10033
- '0-9' +
10034
- '-' +
10035
- '\u00B7' +
10036
- '\u0300-\u036F' +
10037
- '\u203F-\u2040';
10038
- const BLANK_NODE_LABEL =
10039
- '(_:' +
10040
- '(?:[' + PN_CHARS_U + '0-9])' +
10041
- '(?:(?:[' + PN_CHARS + '.])*(?:[' + PN_CHARS + ']))?' +
10042
- ')';
10043
- const bnode = BLANK_NODE_LABEL;
10044
- const plain = '"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"';
10045
- const datatype = '(?:\\^\\^' + iri + ')';
10046
- const language = '(?:@([a-zA-Z]+(?:-[a-zA-Z0-9]+)*))';
10047
- const literal = '(?:' + plain + '(?:' + datatype + '|' + language + ')?)';
10048
- const ws = '[ \\t]+';
10049
- const wso = '[ \\t]*';
10226
+ // 3) For each quad `quad` in `quads`:
10227
+ for(const quad of quads) {
10228
+ // 3.1) Serialize the quad in N-Quads format with the following special
10229
+ // rule:
10050
10230
 
10051
- // define quad part regexes
10052
- const subject = '(?:' + iri + '|' + bnode + ')' + ws;
10053
- const property = iri + ws;
10054
- const object = '(?:' + iri + '|' + bnode + '|' + literal + ')' + wso;
10055
- const graphName = '(?:\\.|(?:(?:' + iri + '|' + bnode + ')' + wso + '\\.))';
10231
+ // 3.1.1) If any component in quad is an blank node, then serialize it
10232
+ // using a special identifier as follows:
10233
+ const copy = {
10234
+ subject: null, predicate: quad.predicate, object: null, graph: null
10235
+ };
10236
+ // 3.1.2) If the blank node's existing blank node identifier matches
10237
+ // the reference blank node identifier then use the blank node
10238
+ // identifier _:a, otherwise, use the blank node identifier _:z.
10239
+ copy.subject = this.modifyFirstDegreeComponent(
10240
+ id, quad.subject, 'subject');
10241
+ copy.object = this.modifyFirstDegreeComponent(
10242
+ id, quad.object, 'object');
10243
+ copy.graph = this.modifyFirstDegreeComponent(
10244
+ id, quad.graph, 'graph');
10245
+ nquads.push(NQuads.serializeQuad(copy));
10246
+ }
10056
10247
 
10057
- // end of line and empty regexes
10058
- REGEX.eoln = /(?:\r\n)|(?:\n)|(?:\r)/g;
10059
- REGEX.empty = new RegExp('^' + wso + '$');
10248
+ // 4) Sort nquads in lexicographical order.
10249
+ nquads.sort();
10060
10250
 
10061
- // full quad regex
10062
- REGEX.quad = new RegExp(
10063
- '^' + wso + subject + property + object + graphName + wso + '$');
10064
- })();
10251
+ // 5) Return the hash that results from passing the sorted, joined nquads
10252
+ // through the hash algorithm.
10253
+ const md = this.createMessageDigest();
10254
+ for(const nquad of nquads) {
10255
+ md.update(nquad);
10256
+ }
10257
+ info.hash = await md.digest();
10258
+ return info.hash;
10259
+ }
10065
10260
 
10066
- module.exports = class NQuads {
10067
- /**
10068
- * Parses RDF in the form of N-Quads.
10069
- *
10070
- * @param input the N-Quads input to parse.
10071
- *
10072
- * @return an RDF dataset (an array of quads per http://rdf.js.org/).
10073
- */
10074
- static parse(input) {
10075
- // build RDF dataset
10076
- const dataset = [];
10261
+ // 4.7) Hash Related Blank Node
10262
+ async hashRelatedBlankNode(related, quad, issuer, position) {
10263
+ // 1) Set the identifier to use for related, preferring first the canonical
10264
+ // identifier for related if issued, second the identifier issued by issuer
10265
+ // if issued, and last, if necessary, the result of the Hash First Degree
10266
+ // Quads algorithm, passing related.
10267
+ let id;
10268
+ if(this.canonicalIssuer.hasId(related)) {
10269
+ id = this.canonicalIssuer.getId(related);
10270
+ } else if(issuer.hasId(related)) {
10271
+ id = issuer.getId(related);
10272
+ } else {
10273
+ id = this.blankNodeInfo.get(related).hash;
10274
+ }
10077
10275
 
10078
- const graphs = {};
10276
+ // 2) Initialize a string input to the value of position.
10277
+ // Note: We use a hash object instead.
10278
+ const md = this.createMessageDigest();
10279
+ md.update(position);
10079
10280
 
10080
- // split N-Quad input into lines
10081
- const lines = input.split(REGEX.eoln);
10082
- let lineNumber = 0;
10083
- for(const line of lines) {
10084
- lineNumber++;
10281
+ // 3) If position is not g, append <, the value of the predicate in quad,
10282
+ // and > to input.
10283
+ if(position !== 'g') {
10284
+ md.update(this.getRelatedPredicate(quad));
10285
+ }
10085
10286
 
10086
- // skip empty lines
10087
- if(REGEX.empty.test(line)) {
10088
- continue;
10089
- }
10287
+ // 4) Append identifier to input.
10288
+ md.update(id);
10090
10289
 
10091
- // parse quad
10092
- const match = line.match(REGEX.quad);
10093
- if(match === null) {
10094
- throw new Error('N-Quads parse error on line ' + lineNumber + '.');
10095
- }
10290
+ // 5) Return the hash that results from passing input through the hash
10291
+ // algorithm.
10292
+ return md.digest();
10293
+ }
10096
10294
 
10097
- // create RDF quad
10098
- const quad = {subject: null, predicate: null, object: null, graph: null};
10295
+ // 4.8) Hash N-Degree Quads
10296
+ async hashNDegreeQuads(id, issuer) {
10297
+ const deepIterations = this.deepIterations.get(id) || 0;
10298
+ if(deepIterations > this.maxDeepIterations) {
10299
+ throw new Error(
10300
+ `Maximum deep iterations (${this.maxDeepIterations}) exceeded.`);
10301
+ }
10302
+ this.deepIterations.set(id, deepIterations + 1);
10099
10303
 
10100
- // get subject
10101
- if(match[1] !== undefined) {
10102
- quad.subject = {termType: TYPE_NAMED_NODE, value: match[1]};
10103
- } else {
10104
- quad.subject = {termType: TYPE_BLANK_NODE, value: match[2]};
10105
- }
10304
+ // 1) Create a hash to related blank nodes map for storing hashes that
10305
+ // identify related blank nodes.
10306
+ // Note: 2) and 3) handled within `createHashToRelated`
10307
+ const md = this.createMessageDigest();
10308
+ const hashToRelated = await this.createHashToRelated(id, issuer);
10106
10309
 
10107
- // get predicate
10108
- quad.predicate = {termType: TYPE_NAMED_NODE, value: match[3]};
10310
+ // 4) Create an empty string, data to hash.
10311
+ // Note: We created a hash object `md` above instead.
10109
10312
 
10110
- // get object
10111
- if(match[4] !== undefined) {
10112
- quad.object = {termType: TYPE_NAMED_NODE, value: match[4]};
10113
- } else if(match[5] !== undefined) {
10114
- quad.object = {termType: TYPE_BLANK_NODE, value: match[5]};
10115
- } else {
10116
- quad.object = {
10117
- termType: TYPE_LITERAL,
10118
- value: undefined,
10119
- datatype: {
10120
- termType: TYPE_NAMED_NODE
10121
- }
10122
- };
10123
- if(match[7] !== undefined) {
10124
- quad.object.datatype.value = match[7];
10125
- } else if(match[8] !== undefined) {
10126
- quad.object.datatype.value = RDF_LANGSTRING;
10127
- quad.object.language = match[8];
10128
- } else {
10129
- quad.object.datatype.value = XSD_STRING;
10130
- }
10131
- quad.object.value = _unescape(match[6]);
10132
- }
10313
+ // 5) For each related hash to blank node list mapping in hash to related
10314
+ // blank nodes map, sorted lexicographically by related hash:
10315
+ const hashes = [...hashToRelated.keys()].sort();
10316
+ for(const hash of hashes) {
10317
+ // 5.1) Append the related hash to the data to hash.
10318
+ md.update(hash);
10133
10319
 
10134
- // get graph
10135
- if(match[9] !== undefined) {
10136
- quad.graph = {
10137
- termType: TYPE_NAMED_NODE,
10138
- value: match[9]
10139
- };
10140
- } else if(match[10] !== undefined) {
10141
- quad.graph = {
10142
- termType: TYPE_BLANK_NODE,
10143
- value: match[10]
10144
- };
10145
- } else {
10146
- quad.graph = {
10147
- termType: TYPE_DEFAULT_GRAPH,
10148
- value: ''
10149
- };
10150
- }
10320
+ // 5.2) Create a string chosen path.
10321
+ let chosenPath = '';
10151
10322
 
10152
- // only add quad if it is unique in its graph
10153
- if(!(quad.graph.value in graphs)) {
10154
- graphs[quad.graph.value] = [quad];
10155
- dataset.push(quad);
10156
- } else {
10157
- let unique = true;
10158
- const quads = graphs[quad.graph.value];
10159
- for(const q of quads) {
10160
- if(_compareTriples(q, quad)) {
10161
- unique = false;
10162
- break;
10163
- }
10164
- }
10165
- if(unique) {
10166
- quads.push(quad);
10167
- dataset.push(quad);
10168
- }
10169
- }
10170
- }
10323
+ // 5.3) Create an unset chosen issuer variable.
10324
+ let chosenIssuer;
10171
10325
 
10172
- return dataset;
10173
- }
10326
+ // 5.4) For each permutation of blank node list:
10327
+ const permuter = new Permuter(hashToRelated.get(hash));
10328
+ let i = 0;
10329
+ while(permuter.hasNext()) {
10330
+ const permutation = permuter.next();
10331
+ // Note: batch permutations 3 at a time
10332
+ if(++i % 3 === 0) {
10333
+ await this._yield();
10334
+ }
10174
10335
 
10175
- /**
10176
- * Converts an RDF dataset to N-Quads.
10177
- *
10178
- * @param dataset (array of quads) the RDF dataset to convert.
10179
- *
10180
- * @return the N-Quads string.
10181
- */
10182
- static serialize(dataset) {
10183
- if(!Array.isArray(dataset)) {
10184
- dataset = NQuads.legacyDatasetToQuads(dataset);
10185
- }
10186
- const quads = [];
10187
- for(const quad of dataset) {
10188
- quads.push(NQuads.serializeQuad(quad));
10189
- }
10190
- return quads.sort().join('');
10191
- }
10336
+ // 5.4.1) Create a copy of issuer, issuer copy.
10337
+ let issuerCopy = issuer.clone();
10192
10338
 
10193
- /**
10194
- * Converts RDF quad components to an N-Quad string (a single quad).
10195
- *
10196
- * @param {Object} s - N-Quad subject component.
10197
- * @param {Object} p - N-Quad predicate component.
10198
- * @param {Object} o - N-Quad object component.
10199
- * @param {Object} g - N-Quad graph component.
10200
- *
10201
- * @return {string} the N-Quad.
10202
- */
10203
- static serializeQuadComponents(s, p, o, g) {
10204
- let nquad = '';
10339
+ // 5.4.2) Create a string path.
10340
+ let path = '';
10205
10341
 
10206
- // subject can only be NamedNode or BlankNode
10207
- if(s.termType === TYPE_NAMED_NODE) {
10208
- nquad += `<${s.value}>`;
10209
- } else {
10210
- nquad += `${s.value}`;
10211
- }
10342
+ // 5.4.3) Create a recursion list, to store blank node identifiers
10343
+ // that must be recursively processed by this algorithm.
10344
+ const recursionList = [];
10212
10345
 
10213
- // predicate can only be NamedNode
10214
- nquad += ` <${p.value}> `;
10346
+ // 5.4.4) For each related in permutation:
10347
+ let nextPermutation = false;
10348
+ for(const related of permutation) {
10349
+ // 5.4.4.1) If a canonical identifier has been issued for
10350
+ // related, append it to path.
10351
+ if(this.canonicalIssuer.hasId(related)) {
10352
+ path += this.canonicalIssuer.getId(related);
10353
+ } else {
10354
+ // 5.4.4.2) Otherwise:
10355
+ // 5.4.4.2.1) If issuer copy has not issued an identifier for
10356
+ // related, append related to recursion list.
10357
+ if(!issuerCopy.hasId(related)) {
10358
+ recursionList.push(related);
10359
+ }
10360
+ // 5.4.4.2.2) Use the Issue Identifier algorithm, passing
10361
+ // issuer copy and related and append the result to path.
10362
+ path += issuerCopy.getId(related);
10363
+ }
10215
10364
 
10216
- // object is NamedNode, BlankNode, or Literal
10217
- if(o.termType === TYPE_NAMED_NODE) {
10218
- nquad += `<${o.value}>`;
10219
- } else if(o.termType === TYPE_BLANK_NODE) {
10220
- nquad += o.value;
10221
- } else {
10222
- nquad += `"${_escape(o.value)}"`;
10223
- if(o.datatype.value === RDF_LANGSTRING) {
10224
- if(o.language) {
10225
- nquad += `@${o.language}`;
10365
+ // 5.4.4.3) If chosen path is not empty and the length of path
10366
+ // is greater than or equal to the length of chosen path and
10367
+ // path is lexicographically greater than chosen path, then
10368
+ // skip to the next permutation.
10369
+ // Note: Comparing path length to chosen path length can be optimized
10370
+ // away; only compare lexicographically.
10371
+ if(chosenPath.length !== 0 && path > chosenPath) {
10372
+ nextPermutation = true;
10373
+ break;
10374
+ }
10226
10375
  }
10227
- } else if(o.datatype.value !== XSD_STRING) {
10228
- nquad += `^^<${o.datatype.value}>`;
10229
- }
10230
- }
10231
10376
 
10232
- // graph can only be NamedNode or BlankNode (or DefaultGraph, but that
10233
- // does not add to `nquad`)
10234
- if(g.termType === TYPE_NAMED_NODE) {
10235
- nquad += ` <${g.value}>`;
10236
- } else if(g.termType === TYPE_BLANK_NODE) {
10237
- nquad += ` ${g.value}`;
10238
- }
10377
+ if(nextPermutation) {
10378
+ continue;
10379
+ }
10239
10380
 
10240
- nquad += ' .\n';
10241
- return nquad;
10242
- }
10381
+ // 5.4.5) For each related in recursion list:
10382
+ for(const related of recursionList) {
10383
+ // 5.4.5.1) Set result to the result of recursively executing
10384
+ // the Hash N-Degree Quads algorithm, passing related for
10385
+ // identifier and issuer copy for path identifier issuer.
10386
+ const result = await this.hashNDegreeQuads(related, issuerCopy);
10243
10387
 
10244
- /**
10245
- * Converts an RDF quad to an N-Quad string (a single quad).
10246
- *
10247
- * @param quad the RDF quad convert.
10248
- *
10249
- * @return the N-Quad string.
10250
- */
10251
- static serializeQuad(quad) {
10252
- return NQuads.serializeQuadComponents(
10253
- quad.subject, quad.predicate, quad.object, quad.graph);
10254
- }
10388
+ // 5.4.5.2) Use the Issue Identifier algorithm, passing issuer
10389
+ // copy and related and append the result to path.
10390
+ path += issuerCopy.getId(related);
10255
10391
 
10256
- /**
10257
- * Converts a legacy-formatted dataset to an array of quads dataset per
10258
- * http://rdf.js.org/.
10259
- *
10260
- * @param dataset the legacy dataset to convert.
10261
- *
10262
- * @return the array of quads dataset.
10263
- */
10264
- static legacyDatasetToQuads(dataset) {
10265
- const quads = [];
10392
+ // 5.4.5.3) Append <, the hash in result, and > to path.
10393
+ path += `<${result.hash}>`;
10266
10394
 
10267
- const termTypeMap = {
10268
- 'blank node': TYPE_BLANK_NODE,
10269
- IRI: TYPE_NAMED_NODE,
10270
- literal: TYPE_LITERAL
10271
- };
10395
+ // 5.4.5.4) Set issuer copy to the identifier issuer in
10396
+ // result.
10397
+ issuerCopy = result.issuer;
10272
10398
 
10273
- for(const graphName in dataset) {
10274
- const triples = dataset[graphName];
10275
- triples.forEach(triple => {
10276
- const quad = {};
10277
- for(const componentName in triple) {
10278
- const oldComponent = triple[componentName];
10279
- const newComponent = {
10280
- termType: termTypeMap[oldComponent.type],
10281
- value: oldComponent.value
10282
- };
10283
- if(newComponent.termType === TYPE_LITERAL) {
10284
- newComponent.datatype = {
10285
- termType: TYPE_NAMED_NODE
10286
- };
10287
- if('datatype' in oldComponent) {
10288
- newComponent.datatype.value = oldComponent.datatype;
10289
- }
10290
- if('language' in oldComponent) {
10291
- if(!('datatype' in oldComponent)) {
10292
- newComponent.datatype.value = RDF_LANGSTRING;
10293
- }
10294
- newComponent.language = oldComponent.language;
10295
- } else if(!('datatype' in oldComponent)) {
10296
- newComponent.datatype.value = XSD_STRING;
10297
- }
10399
+ // 5.4.5.5) If chosen path is not empty and the length of path
10400
+ // is greater than or equal to the length of chosen path and
10401
+ // path is lexicographically greater than chosen path, then
10402
+ // skip to the next permutation.
10403
+ // Note: Comparing path length to chosen path length can be optimized
10404
+ // away; only compare lexicographically.
10405
+ if(chosenPath.length !== 0 && path > chosenPath) {
10406
+ nextPermutation = true;
10407
+ break;
10298
10408
  }
10299
- quad[componentName] = newComponent;
10300
10409
  }
10301
- if(graphName === '@default') {
10302
- quad.graph = {
10303
- termType: TYPE_DEFAULT_GRAPH,
10304
- value: ''
10305
- };
10306
- } else {
10307
- quad.graph = {
10308
- termType: graphName.startsWith('_:') ?
10309
- TYPE_BLANK_NODE : TYPE_NAMED_NODE,
10310
- value: graphName
10311
- };
10312
- }
10313
- quads.push(quad);
10314
- });
10315
- }
10316
10410
 
10317
- return quads;
10318
- }
10319
- };
10411
+ if(nextPermutation) {
10412
+ continue;
10413
+ }
10320
10414
 
10321
- /**
10322
- * Compares two RDF triples for equality.
10323
- *
10324
- * @param t1 the first triple.
10325
- * @param t2 the second triple.
10326
- *
10327
- * @return true if the triples are the same, false if not.
10328
- */
10329
- function _compareTriples(t1, t2) {
10330
- // compare subject and object types first as it is the quickest check
10331
- if(!(t1.subject.termType === t2.subject.termType &&
10332
- t1.object.termType === t2.object.termType)) {
10333
- return false;
10334
- }
10335
- // compare values
10336
- if(!(t1.subject.value === t2.subject.value &&
10337
- t1.predicate.value === t2.predicate.value &&
10338
- t1.object.value === t2.object.value)) {
10339
- return false;
10340
- }
10341
- if(t1.object.termType !== TYPE_LITERAL) {
10342
- // no `datatype` or `language` to check
10343
- return true;
10344
- }
10345
- return (
10346
- (t1.object.datatype.termType === t2.object.datatype.termType) &&
10347
- (t1.object.language === t2.object.language) &&
10348
- (t1.object.datatype.value === t2.object.datatype.value)
10349
- );
10350
- }
10415
+ // 5.4.6) If chosen path is empty or path is lexicographically
10416
+ // less than chosen path, set chosen path to path and chosen
10417
+ // issuer to issuer copy.
10418
+ if(chosenPath.length === 0 || path < chosenPath) {
10419
+ chosenPath = path;
10420
+ chosenIssuer = issuerCopy;
10421
+ }
10422
+ }
10351
10423
 
10352
- const _escapeRegex = /["\\\n\r]/g;
10353
- /**
10354
- * Escape string to N-Quads literal
10355
- */
10356
- function _escape(s) {
10357
- return s.replace(_escapeRegex, function(match) {
10358
- switch(match) {
10359
- case '"': return '\\"';
10360
- case '\\': return '\\\\';
10361
- case '\n': return '\\n';
10362
- case '\r': return '\\r';
10363
- }
10364
- });
10365
- }
10424
+ // 5.5) Append chosen path to data to hash.
10425
+ md.update(chosenPath);
10366
10426
 
10367
- const _unescapeRegex =
10368
- /(?:\\([tbnrf"'\\]))|(?:\\u([0-9A-Fa-f]{4}))|(?:\\U([0-9A-Fa-f]{8}))/g;
10369
- /**
10370
- * Unescape N-Quads literal to string
10371
- */
10372
- function _unescape(s) {
10373
- return s.replace(_unescapeRegex, function(match, code, u, U) {
10374
- if(code) {
10375
- switch(code) {
10376
- case 't': return '\t';
10377
- case 'b': return '\b';
10378
- case 'n': return '\n';
10379
- case 'r': return '\r';
10380
- case 'f': return '\f';
10381
- case '"': return '"';
10382
- case '\'': return '\'';
10383
- case '\\': return '\\';
10384
- }
10385
- }
10386
- if(u) {
10387
- return String.fromCharCode(parseInt(u, 16));
10388
- }
10389
- if(U) {
10390
- // FIXME: support larger values
10391
- throw new Error('Unsupported U escape');
10427
+ // 5.6) Replace issuer, by reference, with chosen issuer.
10428
+ issuer = chosenIssuer;
10392
10429
  }
10393
- });
10394
- }
10395
10430
 
10431
+ // 6) Return issuer and the hash that results from passing data to hash
10432
+ // through the hash algorithm.
10433
+ return {hash: await md.digest(), issuer};
10434
+ }
10396
10435
 
10397
- /***/ }),
10436
+ // helper for modifying component during Hash First Degree Quads
10437
+ modifyFirstDegreeComponent(id, component) {
10438
+ if(component.termType !== 'BlankNode') {
10439
+ return component;
10440
+ }
10441
+ /* Note: A mistake in the URDNA2015 spec that made its way into
10442
+ implementations (and therefore must stay to avoid interop breakage)
10443
+ resulted in an assigned canonical ID, if available for
10444
+ `component.value`, not being used in place of `_:a`/`_:z`, so
10445
+ we don't use it here. */
10446
+ return {
10447
+ termType: 'BlankNode',
10448
+ value: component.value === id ? '_:a' : '_:z'
10449
+ };
10450
+ }
10398
10451
 
10399
- /***/ "./node_modules/rdf-canonize/lib/Permuter.js":
10400
- /*!***************************************************!*\
10401
- !*** ./node_modules/rdf-canonize/lib/Permuter.js ***!
10402
- \***************************************************/
10403
- /***/ ((module) => {
10452
+ // helper for getting a related predicate
10453
+ getRelatedPredicate(quad) {
10454
+ return `<${quad.predicate.value}>`;
10455
+ }
10404
10456
 
10405
- "use strict";
10406
- /*!
10407
- * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
10408
- */
10457
+ // helper for creating hash to related blank nodes map
10458
+ async createHashToRelated(id, issuer) {
10459
+ // 1) Create a hash to related blank nodes map for storing hashes that
10460
+ // identify related blank nodes.
10461
+ const hashToRelated = new Map();
10409
10462
 
10463
+ // 2) Get a reference, quads, to the list of quads in the blank node to
10464
+ // quads map for the key identifier.
10465
+ const quads = this.blankNodeInfo.get(id).quads;
10410
10466
 
10411
- module.exports = class Permuter {
10412
- /**
10413
- * A Permuter iterates over all possible permutations of the given array
10414
- * of elements.
10415
- *
10416
- * @param list the array of elements to iterate over.
10417
- */
10418
- constructor(list) {
10419
- // original array
10420
- this.current = list.sort();
10421
- // indicates whether there are more permutations
10422
- this.done = false;
10423
- // directional info for permutation algorithm
10424
- this.dir = new Map();
10425
- for(let i = 0; i < list.length; ++i) {
10426
- this.dir.set(list[i], true);
10467
+ // 3) For each quad in quads:
10468
+ let i = 0;
10469
+ for(const quad of quads) {
10470
+ // Note: batch hashing related blank node quads 100 at a time
10471
+ if(++i % 100 === 0) {
10472
+ await this._yield();
10473
+ }
10474
+ // 3.1) For each component in quad, if component is the subject, object,
10475
+ // and graph name and it is a blank node that is not identified by
10476
+ // identifier:
10477
+ // steps 3.1.1 and 3.1.2 occur in helpers:
10478
+ await Promise.all([
10479
+ this._addRelatedBlankNodeHash({
10480
+ quad, component: quad.subject, position: 's',
10481
+ id, issuer, hashToRelated
10482
+ }),
10483
+ this._addRelatedBlankNodeHash({
10484
+ quad, component: quad.object, position: 'o',
10485
+ id, issuer, hashToRelated
10486
+ }),
10487
+ this._addRelatedBlankNodeHash({
10488
+ quad, component: quad.graph, position: 'g',
10489
+ id, issuer, hashToRelated
10490
+ })
10491
+ ]);
10427
10492
  }
10428
- }
10429
10493
 
10430
- /**
10431
- * Returns true if there is another permutation.
10432
- *
10433
- * @return true if there is another permutation, false if not.
10434
- */
10435
- hasNext() {
10436
- return !this.done;
10494
+ return hashToRelated;
10437
10495
  }
10438
10496
 
10439
- /**
10440
- * Gets the next permutation. Call hasNext() to ensure there is another one
10441
- * first.
10442
- *
10443
- * @return the next permutation.
10444
- */
10445
- next() {
10446
- // copy current permutation to return it
10447
- const {current, dir} = this;
10448
- const rval = current.slice();
10497
+ async _hashAndTrackBlankNode({id, hashToBlankNodes}) {
10498
+ // 5.3.1) Create a hash, hash, according to the Hash First Degree
10499
+ // Quads algorithm.
10500
+ const hash = await this.hashFirstDegreeQuads(id);
10449
10501
 
10450
- /* Calculate the next permutation using the Steinhaus-Johnson-Trotter
10451
- permutation algorithm. */
10502
+ // 5.3.2) Add hash and identifier to hash to blank nodes map,
10503
+ // creating a new entry if necessary.
10504
+ const idList = hashToBlankNodes.get(hash);
10505
+ if(!idList) {
10506
+ hashToBlankNodes.set(hash, [id]);
10507
+ } else {
10508
+ idList.push(id);
10509
+ }
10510
+ }
10452
10511
 
10453
- // get largest mobile element k
10454
- // (mobile: element is greater than the one it is looking at)
10455
- let k = null;
10456
- let pos = 0;
10457
- const length = current.length;
10458
- for(let i = 0; i < length; ++i) {
10459
- const element = current[i];
10460
- const left = dir.get(element);
10461
- if((k === null || element > k) &&
10462
- ((left && i > 0 && element > current[i - 1]) ||
10463
- (!left && i < (length - 1) && element > current[i + 1]))) {
10464
- k = element;
10465
- pos = i;
10466
- }
10512
+ _addBlankNodeQuadInfo({quad, component}) {
10513
+ if(component.termType !== 'BlankNode') {
10514
+ return;
10515
+ }
10516
+ const id = component.value;
10517
+ const info = this.blankNodeInfo.get(id);
10518
+ if(info) {
10519
+ info.quads.add(quad);
10520
+ } else {
10521
+ this.blankNodeInfo.set(id, {quads: new Set([quad]), hash: null});
10467
10522
  }
10523
+ }
10468
10524
 
10469
- // no more permutations
10470
- if(k === null) {
10471
- this.done = true;
10525
+ async _addRelatedBlankNodeHash(
10526
+ {quad, component, position, id, issuer, hashToRelated}) {
10527
+ if(!(component.termType === 'BlankNode' && component.value !== id)) {
10528
+ return;
10529
+ }
10530
+ // 3.1.1) Set hash to the result of the Hash Related Blank Node
10531
+ // algorithm, passing the blank node identifier for component as
10532
+ // related, quad, path identifier issuer as issuer, and position as
10533
+ // either s, o, or g based on whether component is a subject, object,
10534
+ // graph name, respectively.
10535
+ const related = component.value;
10536
+ const hash = await this.hashRelatedBlankNode(
10537
+ related, quad, issuer, position);
10538
+
10539
+ // 3.1.2) Add a mapping of hash to the blank node identifier for
10540
+ // component to hash to related blank nodes map, adding an entry as
10541
+ // necessary.
10542
+ const entries = hashToRelated.get(hash);
10543
+ if(entries) {
10544
+ entries.push(related);
10472
10545
  } else {
10473
- // swap k and the element it is looking at
10474
- const swap = dir.get(k) ? pos - 1 : pos + 1;
10475
- current[pos] = current[swap];
10476
- current[swap] = k;
10546
+ hashToRelated.set(hash, [related]);
10547
+ }
10548
+ }
10477
10549
 
10478
- // reverse the direction of all elements larger than k
10479
- for(const element of current) {
10480
- if(element > k) {
10481
- dir.set(element, !dir.get(element));
10482
- }
10483
- }
10550
+ // canonical ids for 7.1
10551
+ _componentWithCanonicalId(component) {
10552
+ if(component.termType === 'BlankNode' &&
10553
+ !component.value.startsWith(this.canonicalIssuer.prefix)) {
10554
+ // create new BlankNode
10555
+ return {
10556
+ termType: 'BlankNode',
10557
+ value: this.canonicalIssuer.getId(component.value)
10558
+ };
10484
10559
  }
10560
+ return component;
10561
+ }
10485
10562
 
10486
- return rval;
10563
+ async _yield() {
10564
+ return new Promise(resolve => setImmediate(resolve));
10487
10565
  }
10488
10566
  };
10489
10567
 
10568
+ function _stringHashCompare(a, b) {
10569
+ return a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0;
10570
+ }
10571
+
10490
10572
 
10491
10573
  /***/ }),
10492
10574
 
10493
- /***/ "./node_modules/rdf-canonize/lib/URDNA2015.js":
10494
- /*!****************************************************!*\
10495
- !*** ./node_modules/rdf-canonize/lib/URDNA2015.js ***!
10496
- \****************************************************/
10575
+ /***/ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js":
10576
+ /*!********************************************************!*\
10577
+ !*** ./node_modules/rdf-canonize/lib/URDNA2015Sync.js ***!
10578
+ \********************************************************/
10497
10579
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
10498
10580
 
10499
10581
  "use strict";
@@ -10503,11 +10585,13 @@ module.exports = class Permuter {
10503
10585
 
10504
10586
 
10505
10587
  const IdentifierIssuer = __webpack_require__(/*! ./IdentifierIssuer */ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js");
10588
+ // FIXME: do not import; convert to requiring a
10589
+ // hash factory
10506
10590
  const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
10507
10591
  const Permuter = __webpack_require__(/*! ./Permuter */ "./node_modules/rdf-canonize/lib/Permuter.js");
10508
10592
  const NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/rdf-canonize/lib/NQuads.js");
10509
10593
 
10510
- module.exports = class URDNA2015 {
10594
+ module.exports = class URDNA2015Sync {
10511
10595
  constructor({
10512
10596
  createMessageDigest = () => new MessageDigest('sha256'),
10513
10597
  maxDeepIterations = Infinity
@@ -10522,7 +10606,7 @@ module.exports = class URDNA2015 {
10522
10606
  }
10523
10607
 
10524
10608
  // 4.4) Normalization Algorithm
10525
- async main(dataset) {
10609
+ main(dataset) {
10526
10610
  this.deepIterations = new Map();
10527
10611
  this.quads = dataset;
10528
10612
 
@@ -10554,14 +10638,9 @@ module.exports = class URDNA2015 {
10554
10638
  // identifiers:
10555
10639
  const hashToBlankNodes = new Map();
10556
10640
  const nonNormalized = [...this.blankNodeInfo.keys()];
10557
- let i = 0;
10558
10641
  for(const id of nonNormalized) {
10559
- // Note: batch hashing first degree quads 100 at a time
10560
- if(++i % 100 === 0) {
10561
- await this._yield();
10562
- }
10563
10642
  // steps 5.3.1 and 5.3.2:
10564
- await this._hashAndTrackBlankNode({id, hashToBlankNodes});
10643
+ this._hashAndTrackBlankNode({id, hashToBlankNodes});
10565
10644
  }
10566
10645
 
10567
10646
  // 5.4) For each hash to identifier list mapping in hash to blank
@@ -10619,7 +10698,7 @@ module.exports = class URDNA2015 {
10619
10698
 
10620
10699
  // 6.2.4) Run the Hash N-Degree Quads algorithm, passing
10621
10700
  // temporary issuer, and append the result to the hash path list.
10622
- const result = await this.hashNDegreeQuads(id, issuer);
10701
+ const result = this.hashNDegreeQuads(id, issuer);
10623
10702
  hashPathList.push(result);
10624
10703
  }
10625
10704
 
@@ -10652,10 +10731,10 @@ module.exports = class URDNA2015 {
10652
10731
  // previously issued by canonical issuer.
10653
10732
  // Note: We optimize away the copy here.
10654
10733
  const nQuad = NQuads.serializeQuadComponents(
10655
- this._componentWithCanonicalId(quad.subject),
10734
+ this._componentWithCanonicalId({component: quad.subject}),
10656
10735
  quad.predicate,
10657
- this._componentWithCanonicalId(quad.object),
10658
- this._componentWithCanonicalId(quad.graph)
10736
+ this._componentWithCanonicalId({component: quad.object}),
10737
+ this._componentWithCanonicalId({component: quad.graph})
10659
10738
  );
10660
10739
  // 7.2) Add quad copy to the normalized dataset.
10661
10740
  normalized.push(nQuad);
@@ -10669,7 +10748,7 @@ module.exports = class URDNA2015 {
10669
10748
  }
10670
10749
 
10671
10750
  // 4.6) Hash First Degree Quads
10672
- async hashFirstDegreeQuads(id) {
10751
+ hashFirstDegreeQuads(id) {
10673
10752
  // 1) Initialize nquads to an empty list. It will be used to store quads in
10674
10753
  // N-Quads format.
10675
10754
  const nquads = [];
@@ -10710,12 +10789,12 @@ module.exports = class URDNA2015 {
10710
10789
  for(const nquad of nquads) {
10711
10790
  md.update(nquad);
10712
10791
  }
10713
- info.hash = await md.digest();
10792
+ info.hash = md.digest();
10714
10793
  return info.hash;
10715
10794
  }
10716
10795
 
10717
10796
  // 4.7) Hash Related Blank Node
10718
- async hashRelatedBlankNode(related, quad, issuer, position) {
10797
+ hashRelatedBlankNode(related, quad, issuer, position) {
10719
10798
  // 1) Set the identifier to use for related, preferring first the canonical
10720
10799
  // identifier for related if issued, second the identifier issued by issuer
10721
10800
  // if issued, and last, if necessary, the result of the Hash First Degree
@@ -10749,7 +10828,7 @@ module.exports = class URDNA2015 {
10749
10828
  }
10750
10829
 
10751
10830
  // 4.8) Hash N-Degree Quads
10752
- async hashNDegreeQuads(id, issuer) {
10831
+ hashNDegreeQuads(id, issuer) {
10753
10832
  const deepIterations = this.deepIterations.get(id) || 0;
10754
10833
  if(deepIterations > this.maxDeepIterations) {
10755
10834
  throw new Error(
@@ -10761,7 +10840,7 @@ module.exports = class URDNA2015 {
10761
10840
  // identify related blank nodes.
10762
10841
  // Note: 2) and 3) handled within `createHashToRelated`
10763
10842
  const md = this.createMessageDigest();
10764
- const hashToRelated = await this.createHashToRelated(id, issuer);
10843
+ const hashToRelated = this.createHashToRelated(id, issuer);
10765
10844
 
10766
10845
  // 4) Create an empty string, data to hash.
10767
10846
  // Note: We created a hash object `md` above instead.
@@ -10781,13 +10860,8 @@ module.exports = class URDNA2015 {
10781
10860
 
10782
10861
  // 5.4) For each permutation of blank node list:
10783
10862
  const permuter = new Permuter(hashToRelated.get(hash));
10784
- let i = 0;
10785
10863
  while(permuter.hasNext()) {
10786
10864
  const permutation = permuter.next();
10787
- // Note: batch permutations 3 at a time
10788
- if(++i % 3 === 0) {
10789
- await this._yield();
10790
- }
10791
10865
 
10792
10866
  // 5.4.1) Create a copy of issuer, issuer copy.
10793
10867
  let issuerCopy = issuer.clone();
@@ -10839,7 +10913,7 @@ module.exports = class URDNA2015 {
10839
10913
  // 5.4.5.1) Set result to the result of recursively executing
10840
10914
  // the Hash N-Degree Quads algorithm, passing related for
10841
10915
  // identifier and issuer copy for path identifier issuer.
10842
- const result = await this.hashNDegreeQuads(related, issuerCopy);
10916
+ const result = this.hashNDegreeQuads(related, issuerCopy);
10843
10917
 
10844
10918
  // 5.4.5.2) Use the Issue Identifier algorithm, passing issuer
10845
10919
  // copy and related and append the result to path.
@@ -10886,7 +10960,7 @@ module.exports = class URDNA2015 {
10886
10960
 
10887
10961
  // 6) Return issuer and the hash that results from passing data to hash
10888
10962
  // through the hash algorithm.
10889
- return {hash: await md.digest(), issuer};
10963
+ return {hash: md.digest(), issuer};
10890
10964
  }
10891
10965
 
10892
10966
  // helper for modifying component during Hash First Degree Quads
@@ -10911,7 +10985,7 @@ module.exports = class URDNA2015 {
10911
10985
  }
10912
10986
 
10913
10987
  // helper for creating hash to related blank nodes map
10914
- async createHashToRelated(id, issuer) {
10988
+ createHashToRelated(id, issuer) {
10915
10989
  // 1) Create a hash to related blank nodes map for storing hashes that
10916
10990
  // identify related blank nodes.
10917
10991
  const hashToRelated = new Map();
@@ -10921,39 +10995,32 @@ module.exports = class URDNA2015 {
10921
10995
  const quads = this.blankNodeInfo.get(id).quads;
10922
10996
 
10923
10997
  // 3) For each quad in quads:
10924
- let i = 0;
10925
10998
  for(const quad of quads) {
10926
- // Note: batch hashing related blank node quads 100 at a time
10927
- if(++i % 100 === 0) {
10928
- await this._yield();
10929
- }
10930
10999
  // 3.1) For each component in quad, if component is the subject, object,
10931
- // and graph name and it is a blank node that is not identified by
11000
+ // or graph name and it is a blank node that is not identified by
10932
11001
  // identifier:
10933
11002
  // steps 3.1.1 and 3.1.2 occur in helpers:
10934
- await Promise.all([
10935
- this._addRelatedBlankNodeHash({
10936
- quad, component: quad.subject, position: 's',
10937
- id, issuer, hashToRelated
10938
- }),
10939
- this._addRelatedBlankNodeHash({
10940
- quad, component: quad.object, position: 'o',
10941
- id, issuer, hashToRelated
10942
- }),
10943
- this._addRelatedBlankNodeHash({
10944
- quad, component: quad.graph, position: 'g',
10945
- id, issuer, hashToRelated
10946
- })
10947
- ]);
11003
+ this._addRelatedBlankNodeHash({
11004
+ quad, component: quad.subject, position: 's',
11005
+ id, issuer, hashToRelated
11006
+ });
11007
+ this._addRelatedBlankNodeHash({
11008
+ quad, component: quad.object, position: 'o',
11009
+ id, issuer, hashToRelated
11010
+ });
11011
+ this._addRelatedBlankNodeHash({
11012
+ quad, component: quad.graph, position: 'g',
11013
+ id, issuer, hashToRelated
11014
+ });
10948
11015
  }
10949
11016
 
10950
11017
  return hashToRelated;
10951
11018
  }
10952
11019
 
10953
- async _hashAndTrackBlankNode({id, hashToBlankNodes}) {
11020
+ _hashAndTrackBlankNode({id, hashToBlankNodes}) {
10954
11021
  // 5.3.1) Create a hash, hash, according to the Hash First Degree
10955
11022
  // Quads algorithm.
10956
- const hash = await this.hashFirstDegreeQuads(id);
11023
+ const hash = this.hashFirstDegreeQuads(id);
10957
11024
 
10958
11025
  // 5.3.2) Add hash and identifier to hash to blank nodes map,
10959
11026
  // creating a new entry if necessary.
@@ -10978,7 +11045,7 @@ module.exports = class URDNA2015 {
10978
11045
  }
10979
11046
  }
10980
11047
 
10981
- async _addRelatedBlankNodeHash(
11048
+ _addRelatedBlankNodeHash(
10982
11049
  {quad, component, position, id, issuer, hashToRelated}) {
10983
11050
  if(!(component.termType === 'BlankNode' && component.value !== id)) {
10984
11051
  return;
@@ -10989,8 +11056,7 @@ module.exports = class URDNA2015 {
10989
11056
  // either s, o, or g based on whether component is a subject, object,
10990
11057
  // graph name, respectively.
10991
11058
  const related = component.value;
10992
- const hash = await this.hashRelatedBlankNode(
10993
- related, quad, issuer, position);
11059
+ const hash = this.hashRelatedBlankNode(related, quad, issuer, position);
10994
11060
 
10995
11061
  // 3.1.2) Add a mapping of hash to the blank node identifier for
10996
11062
  // component to hash to related blank nodes map, adding an entry as
@@ -11004,1128 +11070,1062 @@ module.exports = class URDNA2015 {
11004
11070
  }
11005
11071
 
11006
11072
  // canonical ids for 7.1
11007
- _componentWithCanonicalId(component) {
11073
+ _componentWithCanonicalId({component}) {
11008
11074
  if(component.termType === 'BlankNode' &&
11009
11075
  !component.value.startsWith(this.canonicalIssuer.prefix)) {
11010
11076
  // create new BlankNode
11011
11077
  return {
11012
11078
  termType: 'BlankNode',
11013
- value: this.canonicalIssuer.getId(component.value)
11079
+ value: this.canonicalIssuer.getId(component.value)
11080
+ };
11081
+ }
11082
+ return component;
11083
+ }
11084
+ };
11085
+
11086
+ function _stringHashCompare(a, b) {
11087
+ return a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0;
11088
+ }
11089
+
11090
+
11091
+ /***/ }),
11092
+
11093
+ /***/ "./node_modules/rdf-canonize/lib/URGNA2012.js":
11094
+ /*!****************************************************!*\
11095
+ !*** ./node_modules/rdf-canonize/lib/URGNA2012.js ***!
11096
+ \****************************************************/
11097
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
11098
+
11099
+ "use strict";
11100
+ /*!
11101
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
11102
+ */
11103
+
11104
+
11105
+ const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
11106
+ const URDNA2015 = __webpack_require__(/*! ./URDNA2015 */ "./node_modules/rdf-canonize/lib/URDNA2015.js");
11107
+
11108
+ module.exports = class URDNA2012 extends URDNA2015 {
11109
+ constructor() {
11110
+ super();
11111
+ this.name = 'URGNA2012';
11112
+ this.createMessageDigest = () => new MessageDigest('sha1');
11113
+ }
11114
+
11115
+ // helper for modifying component during Hash First Degree Quads
11116
+ modifyFirstDegreeComponent(id, component, key) {
11117
+ if(component.termType !== 'BlankNode') {
11118
+ return component;
11119
+ }
11120
+ if(key === 'graph') {
11121
+ return {
11122
+ termType: 'BlankNode',
11123
+ value: '_:g'
11014
11124
  };
11015
11125
  }
11016
- return component;
11126
+ return {
11127
+ termType: 'BlankNode',
11128
+ value: (component.value === id ? '_:a' : '_:z')
11129
+ };
11017
11130
  }
11018
11131
 
11019
- async _yield() {
11020
- return new Promise(resolve => setImmediate(resolve));
11132
+ // helper for getting a related predicate
11133
+ getRelatedPredicate(quad) {
11134
+ return quad.predicate.value;
11021
11135
  }
11022
- };
11023
11136
 
11024
- function _stringHashCompare(a, b) {
11025
- return a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0;
11026
- }
11137
+ // helper for creating hash to related blank nodes map
11138
+ async createHashToRelated(id, issuer) {
11139
+ // 1) Create a hash to related blank nodes map for storing hashes that
11140
+ // identify related blank nodes.
11141
+ const hashToRelated = new Map();
11142
+
11143
+ // 2) Get a reference, quads, to the list of quads in the blank node to
11144
+ // quads map for the key identifier.
11145
+ const quads = this.blankNodeInfo.get(id).quads;
11146
+
11147
+ // 3) For each quad in quads:
11148
+ let i = 0;
11149
+ for(const quad of quads) {
11150
+ // 3.1) If the quad's subject is a blank node that does not match
11151
+ // identifier, set hash to the result of the Hash Related Blank Node
11152
+ // algorithm, passing the blank node identifier for subject as related,
11153
+ // quad, path identifier issuer as issuer, and p as position.
11154
+ let position;
11155
+ let related;
11156
+ if(quad.subject.termType === 'BlankNode' && quad.subject.value !== id) {
11157
+ related = quad.subject.value;
11158
+ position = 'p';
11159
+ } else if(
11160
+ quad.object.termType === 'BlankNode' && quad.object.value !== id) {
11161
+ // 3.2) Otherwise, if quad's object is a blank node that does not match
11162
+ // identifier, to the result of the Hash Related Blank Node algorithm,
11163
+ // passing the blank node identifier for object as related, quad, path
11164
+ // identifier issuer as issuer, and r as position.
11165
+ related = quad.object.value;
11166
+ position = 'r';
11167
+ } else {
11168
+ // 3.3) Otherwise, continue to the next quad.
11169
+ continue;
11170
+ }
11171
+ // Note: batch hashing related blank nodes 100 at a time
11172
+ if(++i % 100 === 0) {
11173
+ await this._yield();
11174
+ }
11175
+ // 3.4) Add a mapping of hash to the blank node identifier for the
11176
+ // component that matched (subject or object) to hash to related blank
11177
+ // nodes map, adding an entry as necessary.
11178
+ const hash = await this.hashRelatedBlankNode(
11179
+ related, quad, issuer, position);
11180
+ const entries = hashToRelated.get(hash);
11181
+ if(entries) {
11182
+ entries.push(related);
11183
+ } else {
11184
+ hashToRelated.set(hash, [related]);
11185
+ }
11186
+ }
11187
+
11188
+ return hashToRelated;
11189
+ }
11190
+ };
11027
11191
 
11028
11192
 
11029
11193
  /***/ }),
11030
11194
 
11031
- /***/ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js":
11195
+ /***/ "./node_modules/rdf-canonize/lib/URGNA2012Sync.js":
11032
11196
  /*!********************************************************!*\
11033
- !*** ./node_modules/rdf-canonize/lib/URDNA2015Sync.js ***!
11197
+ !*** ./node_modules/rdf-canonize/lib/URGNA2012Sync.js ***!
11034
11198
  \********************************************************/
11035
11199
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
11036
11200
 
11037
11201
  "use strict";
11038
11202
  /*!
11039
- * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
11203
+ * Copyright (c) 2016-2021 Digital Bazaar, Inc. All rights reserved.
11040
11204
  */
11041
11205
 
11042
11206
 
11043
- const IdentifierIssuer = __webpack_require__(/*! ./IdentifierIssuer */ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js");
11044
- // FIXME: do not import; convert to requiring a
11045
- // hash factory
11046
11207
  const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
11047
- const Permuter = __webpack_require__(/*! ./Permuter */ "./node_modules/rdf-canonize/lib/Permuter.js");
11048
- const NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/rdf-canonize/lib/NQuads.js");
11208
+ const URDNA2015Sync = __webpack_require__(/*! ./URDNA2015Sync */ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js");
11049
11209
 
11050
- module.exports = class URDNA2015Sync {
11051
- constructor({
11052
- createMessageDigest = () => new MessageDigest('sha256'),
11053
- maxDeepIterations = Infinity
11054
- } = {}) {
11055
- this.name = 'URDNA2015';
11056
- this.blankNodeInfo = new Map();
11057
- this.canonicalIssuer = new IdentifierIssuer('_:c14n');
11058
- this.createMessageDigest = createMessageDigest;
11059
- this.maxDeepIterations = maxDeepIterations;
11060
- this.quads = null;
11061
- this.deepIterations = null;
11210
+ module.exports = class URDNA2012Sync extends URDNA2015Sync {
11211
+ constructor() {
11212
+ super();
11213
+ this.name = 'URGNA2012';
11214
+ this.createMessageDigest = () => new MessageDigest('sha1');
11062
11215
  }
11063
11216
 
11064
- // 4.4) Normalization Algorithm
11065
- main(dataset) {
11066
- this.deepIterations = new Map();
11067
- this.quads = dataset;
11068
-
11069
- // 1) Create the normalization state.
11070
- // 2) For every quad in input dataset:
11071
- for(const quad of dataset) {
11072
- // 2.1) For each blank node that occurs in the quad, add a reference
11073
- // to the quad using the blank node identifier in the blank node to
11074
- // quads map, creating a new entry if necessary.
11075
- this._addBlankNodeQuadInfo({quad, component: quad.subject});
11076
- this._addBlankNodeQuadInfo({quad, component: quad.object});
11077
- this._addBlankNodeQuadInfo({quad, component: quad.graph});
11078
- }
11079
-
11080
- // 3) Create a list of non-normalized blank node identifiers
11081
- // non-normalized identifiers and populate it using the keys from the
11082
- // blank node to quads map.
11083
- // Note: We use a map here and it was generated during step 2.
11084
-
11085
- // 4) `simple` flag is skipped -- loop is optimized away. This optimization
11086
- // is permitted because there was a typo in the hash first degree quads
11087
- // algorithm in the URDNA2015 spec that was implemented widely making it
11088
- // such that it could not be fixed; the result was that the loop only
11089
- // needs to be run once and the first degree quad hashes will never change.
11090
- // 5.1-5.2 are skipped; first degree quad hashes are generated just once
11091
- // for all non-normalized blank nodes.
11092
-
11093
- // 5.3) For each blank node identifier identifier in non-normalized
11094
- // identifiers:
11095
- const hashToBlankNodes = new Map();
11096
- const nonNormalized = [...this.blankNodeInfo.keys()];
11097
- for(const id of nonNormalized) {
11098
- // steps 5.3.1 and 5.3.2:
11099
- this._hashAndTrackBlankNode({id, hashToBlankNodes});
11217
+ // helper for modifying component during Hash First Degree Quads
11218
+ modifyFirstDegreeComponent(id, component, key) {
11219
+ if(component.termType !== 'BlankNode') {
11220
+ return component;
11100
11221
  }
11101
-
11102
- // 5.4) For each hash to identifier list mapping in hash to blank
11103
- // nodes map, lexicographically-sorted by hash:
11104
- const hashes = [...hashToBlankNodes.keys()].sort();
11105
- // optimize away second sort, gather non-unique hashes in order as we go
11106
- const nonUnique = [];
11107
- for(const hash of hashes) {
11108
- // 5.4.1) If the length of identifier list is greater than 1,
11109
- // continue to the next mapping.
11110
- const idList = hashToBlankNodes.get(hash);
11111
- if(idList.length > 1) {
11112
- nonUnique.push(idList);
11113
- continue;
11114
- }
11115
-
11116
- // 5.4.2) Use the Issue Identifier algorithm, passing canonical
11117
- // issuer and the single blank node identifier in identifier
11118
- // list, identifier, to issue a canonical replacement identifier
11119
- // for identifier.
11120
- const id = idList[0];
11121
- this.canonicalIssuer.getId(id);
11122
-
11123
- // Note: These steps are skipped, optimized away since the loop
11124
- // only needs to be run once.
11125
- // 5.4.3) Remove identifier from non-normalized identifiers.
11126
- // 5.4.4) Remove hash from the hash to blank nodes map.
11127
- // 5.4.5) Set simple to true.
11222
+ if(key === 'graph') {
11223
+ return {
11224
+ termType: 'BlankNode',
11225
+ value: '_:g'
11226
+ };
11128
11227
  }
11228
+ return {
11229
+ termType: 'BlankNode',
11230
+ value: (component.value === id ? '_:a' : '_:z')
11231
+ };
11232
+ }
11129
11233
 
11130
- // 6) For each hash to identifier list mapping in hash to blank nodes map,
11131
- // lexicographically-sorted by hash:
11132
- // Note: sort optimized away, use `nonUnique`.
11133
- for(const idList of nonUnique) {
11134
- // 6.1) Create hash path list where each item will be a result of
11135
- // running the Hash N-Degree Quads algorithm.
11136
- const hashPathList = [];
11137
-
11138
- // 6.2) For each blank node identifier identifier in identifier list:
11139
- for(const id of idList) {
11140
- // 6.2.1) If a canonical identifier has already been issued for
11141
- // identifier, continue to the next identifier.
11142
- if(this.canonicalIssuer.hasId(id)) {
11143
- continue;
11144
- }
11234
+ // helper for getting a related predicate
11235
+ getRelatedPredicate(quad) {
11236
+ return quad.predicate.value;
11237
+ }
11145
11238
 
11146
- // 6.2.2) Create temporary issuer, an identifier issuer
11147
- // initialized with the prefix _:b.
11148
- const issuer = new IdentifierIssuer('_:b');
11239
+ // helper for creating hash to related blank nodes map
11240
+ createHashToRelated(id, issuer) {
11241
+ // 1) Create a hash to related blank nodes map for storing hashes that
11242
+ // identify related blank nodes.
11243
+ const hashToRelated = new Map();
11149
11244
 
11150
- // 6.2.3) Use the Issue Identifier algorithm, passing temporary
11151
- // issuer and identifier, to issue a new temporary blank node
11152
- // identifier for identifier.
11153
- issuer.getId(id);
11245
+ // 2) Get a reference, quads, to the list of quads in the blank node to
11246
+ // quads map for the key identifier.
11247
+ const quads = this.blankNodeInfo.get(id).quads;
11154
11248
 
11155
- // 6.2.4) Run the Hash N-Degree Quads algorithm, passing
11156
- // temporary issuer, and append the result to the hash path list.
11157
- const result = this.hashNDegreeQuads(id, issuer);
11158
- hashPathList.push(result);
11249
+ // 3) For each quad in quads:
11250
+ for(const quad of quads) {
11251
+ // 3.1) If the quad's subject is a blank node that does not match
11252
+ // identifier, set hash to the result of the Hash Related Blank Node
11253
+ // algorithm, passing the blank node identifier for subject as related,
11254
+ // quad, path identifier issuer as issuer, and p as position.
11255
+ let position;
11256
+ let related;
11257
+ if(quad.subject.termType === 'BlankNode' && quad.subject.value !== id) {
11258
+ related = quad.subject.value;
11259
+ position = 'p';
11260
+ } else if(
11261
+ quad.object.termType === 'BlankNode' && quad.object.value !== id) {
11262
+ // 3.2) Otherwise, if quad's object is a blank node that does not match
11263
+ // identifier, to the result of the Hash Related Blank Node algorithm,
11264
+ // passing the blank node identifier for object as related, quad, path
11265
+ // identifier issuer as issuer, and r as position.
11266
+ related = quad.object.value;
11267
+ position = 'r';
11268
+ } else {
11269
+ // 3.3) Otherwise, continue to the next quad.
11270
+ continue;
11159
11271
  }
11160
-
11161
- // 6.3) For each result in the hash path list,
11162
- // lexicographically-sorted by the hash in result:
11163
- hashPathList.sort(_stringHashCompare);
11164
- for(const result of hashPathList) {
11165
- // 6.3.1) For each blank node identifier, existing identifier,
11166
- // that was issued a temporary identifier by identifier issuer
11167
- // in result, issue a canonical identifier, in the same order,
11168
- // using the Issue Identifier algorithm, passing canonical
11169
- // issuer and existing identifier.
11170
- const oldIds = result.issuer.getOldIds();
11171
- for(const id of oldIds) {
11172
- this.canonicalIssuer.getId(id);
11173
- }
11272
+ // 3.4) Add a mapping of hash to the blank node identifier for the
11273
+ // component that matched (subject or object) to hash to related blank
11274
+ // nodes map, adding an entry as necessary.
11275
+ const hash = this.hashRelatedBlankNode(related, quad, issuer, position);
11276
+ const entries = hashToRelated.get(hash);
11277
+ if(entries) {
11278
+ entries.push(related);
11279
+ } else {
11280
+ hashToRelated.set(hash, [related]);
11174
11281
  }
11175
11282
  }
11176
11283
 
11177
- /* Note: At this point all blank nodes in the set of RDF quads have been
11178
- assigned canonical identifiers, which have been stored in the canonical
11179
- issuer. Here each quad is updated by assigning each of its blank nodes
11180
- its new identifier. */
11284
+ return hashToRelated;
11285
+ }
11286
+ };
11181
11287
 
11182
- // 7) For each quad, quad, in input dataset:
11183
- const normalized = [];
11184
- for(const quad of this.quads) {
11185
- // 7.1) Create a copy, quad copy, of quad and replace any existing
11186
- // blank node identifiers using the canonical identifiers
11187
- // previously issued by canonical issuer.
11188
- // Note: We optimize away the copy here.
11189
- const nQuad = NQuads.serializeQuadComponents(
11190
- this._componentWithCanonicalId({component: quad.subject}),
11191
- quad.predicate,
11192
- this._componentWithCanonicalId({component: quad.object}),
11193
- this._componentWithCanonicalId({component: quad.graph})
11194
- );
11195
- // 7.2) Add quad copy to the normalized dataset.
11196
- normalized.push(nQuad);
11197
- }
11198
11288
 
11199
- // sort normalized output
11200
- normalized.sort();
11289
+ /***/ }),
11201
11290
 
11202
- // 8) Return the normalized dataset.
11203
- return normalized.join('');
11204
- }
11291
+ /***/ "./node_modules/rdf-canonize/lib/index.js":
11292
+ /*!************************************************!*\
11293
+ !*** ./node_modules/rdf-canonize/lib/index.js ***!
11294
+ \************************************************/
11295
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11205
11296
 
11206
- // 4.6) Hash First Degree Quads
11207
- hashFirstDegreeQuads(id) {
11208
- // 1) Initialize nquads to an empty list. It will be used to store quads in
11209
- // N-Quads format.
11210
- const nquads = [];
11297
+ "use strict";
11298
+ /**
11299
+ * An implementation of the RDF Dataset Normalization specification.
11300
+ * This library works in the browser and node.js.
11301
+ *
11302
+ * BSD 3-Clause License
11303
+ * Copyright (c) 2016-2022 Digital Bazaar, Inc.
11304
+ * All rights reserved.
11305
+ *
11306
+ * Redistribution and use in source and binary forms, with or without
11307
+ * modification, are permitted provided that the following conditions are met:
11308
+ *
11309
+ * Redistributions of source code must retain the above copyright notice,
11310
+ * this list of conditions and the following disclaimer.
11311
+ *
11312
+ * Redistributions in binary form must reproduce the above copyright
11313
+ * notice, this list of conditions and the following disclaimer in the
11314
+ * documentation and/or other materials provided with the distribution.
11315
+ *
11316
+ * Neither the name of the Digital Bazaar, Inc. nor the names of its
11317
+ * contributors may be used to endorse or promote products derived from
11318
+ * this software without specific prior written permission.
11319
+ *
11320
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
11321
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
11322
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
11323
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
11324
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11325
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
11326
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
11327
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
11328
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
11329
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11330
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11331
+ */
11211
11332
 
11212
- // 2) Get the list of quads `quads` associated with the reference blank node
11213
- // identifier in the blank node to quads map.
11214
- const info = this.blankNodeInfo.get(id);
11215
- const quads = info.quads;
11216
11333
 
11217
- // 3) For each quad `quad` in `quads`:
11218
- for(const quad of quads) {
11219
- // 3.1) Serialize the quad in N-Quads format with the following special
11220
- // rule:
11334
+ const URDNA2015 = __webpack_require__(/*! ./URDNA2015 */ "./node_modules/rdf-canonize/lib/URDNA2015.js");
11335
+ const URGNA2012 = __webpack_require__(/*! ./URGNA2012 */ "./node_modules/rdf-canonize/lib/URGNA2012.js");
11336
+ const URDNA2015Sync = __webpack_require__(/*! ./URDNA2015Sync */ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js");
11337
+ const URGNA2012Sync = __webpack_require__(/*! ./URGNA2012Sync */ "./node_modules/rdf-canonize/lib/URGNA2012Sync.js");
11221
11338
 
11222
- // 3.1.1) If any component in quad is an blank node, then serialize it
11223
- // using a special identifier as follows:
11224
- const copy = {
11225
- subject: null, predicate: quad.predicate, object: null, graph: null
11226
- };
11227
- // 3.1.2) If the blank node's existing blank node identifier matches
11228
- // the reference blank node identifier then use the blank node
11229
- // identifier _:a, otherwise, use the blank node identifier _:z.
11230
- copy.subject = this.modifyFirstDegreeComponent(
11231
- id, quad.subject, 'subject');
11232
- copy.object = this.modifyFirstDegreeComponent(
11233
- id, quad.object, 'object');
11234
- copy.graph = this.modifyFirstDegreeComponent(
11235
- id, quad.graph, 'graph');
11236
- nquads.push(NQuads.serializeQuad(copy));
11237
- }
11339
+ // optional native support
11340
+ let rdfCanonizeNative;
11341
+ try {
11342
+ rdfCanonizeNative = __webpack_require__(/*! rdf-canonize-native */ "?2b19");
11343
+ } catch(e) {}
11238
11344
 
11239
- // 4) Sort nquads in lexicographical order.
11240
- nquads.sort();
11345
+ // expose helpers
11346
+ exports.NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/rdf-canonize/lib/NQuads.js");
11347
+ exports.IdentifierIssuer = __webpack_require__(/*! ./IdentifierIssuer */ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js");
11241
11348
 
11242
- // 5) Return the hash that results from passing the sorted, joined nquads
11243
- // through the hash algorithm.
11244
- const md = this.createMessageDigest();
11245
- for(const nquad of nquads) {
11246
- md.update(nquad);
11247
- }
11248
- info.hash = md.digest();
11249
- return info.hash;
11349
+ /**
11350
+ * Get or set native API.
11351
+ *
11352
+ * @param api the native API.
11353
+ *
11354
+ * @return the currently set native API.
11355
+ */
11356
+ exports._rdfCanonizeNative = function(api) {
11357
+ if(api) {
11358
+ rdfCanonizeNative = api;
11250
11359
  }
11360
+ return rdfCanonizeNative;
11361
+ };
11251
11362
 
11252
- // 4.7) Hash Related Blank Node
11253
- hashRelatedBlankNode(related, quad, issuer, position) {
11254
- // 1) Set the identifier to use for related, preferring first the canonical
11255
- // identifier for related if issued, second the identifier issued by issuer
11256
- // if issued, and last, if necessary, the result of the Hash First Degree
11257
- // Quads algorithm, passing related.
11258
- let id;
11259
- if(this.canonicalIssuer.hasId(related)) {
11260
- id = this.canonicalIssuer.getId(related);
11261
- } else if(issuer.hasId(related)) {
11262
- id = issuer.getId(related);
11263
- } else {
11264
- id = this.blankNodeInfo.get(related).hash;
11265
- }
11363
+ /**
11364
+ * Asynchronously canonizes an RDF dataset.
11365
+ *
11366
+ * @param {Array} dataset - The dataset to canonize.
11367
+ * @param {object} options - The options to use:
11368
+ * {string} algorithm - The canonicalization algorithm to use, `URDNA2015` or
11369
+ * `URGNA2012`.
11370
+ * {Function} [createMessageDigest] - A factory function for creating a
11371
+ * `MessageDigest` interface that overrides the built-in message digest
11372
+ * implementation used by the canonize algorithm; note that using a hash
11373
+ * algorithm (or HMAC algorithm) that differs from the one specified by
11374
+ * the canonize algorithm will result in different output.
11375
+ * {boolean} [useNative=false] - Use native implementation.
11376
+ * {number} [maxDeepIterations=Infinity] - The maximum number of times to run
11377
+ * deep comparison algorithms (such as the N-Degree Hash Quads algorithm
11378
+ * used in URDNA2015) before bailing out and throwing an error; this is a
11379
+ * useful setting for preventing wasted CPU cycles or DoS when canonizing
11380
+ * meaningless or potentially malicious datasets, a recommended value is
11381
+ * `1`.
11382
+ *
11383
+ * @return a Promise that resolves to the canonicalized RDF Dataset.
11384
+ */
11385
+ exports.canonize = async function(dataset, options) {
11386
+ // back-compat with legacy dataset
11387
+ if(!Array.isArray(dataset)) {
11388
+ dataset = exports.NQuads.legacyDatasetToQuads(dataset);
11389
+ }
11266
11390
 
11267
- // 2) Initialize a string input to the value of position.
11268
- // Note: We use a hash object instead.
11269
- const md = this.createMessageDigest();
11270
- md.update(position);
11391
+ if(options.useNative) {
11392
+ if(!rdfCanonizeNative) {
11393
+ throw new Error('rdf-canonize-native not available');
11394
+ }
11395
+ if(options.createMessageDigest) {
11396
+ throw new Error(
11397
+ '"createMessageDigest" cannot be used with "useNative".');
11398
+ }
11399
+ return new Promise((resolve, reject) =>
11400
+ rdfCanonizeNative.canonize(dataset, options, (err, canonical) =>
11401
+ err ? reject(err) : resolve(canonical)));
11402
+ }
11271
11403
 
11272
- // 3) If position is not g, append <, the value of the predicate in quad,
11273
- // and > to input.
11274
- if(position !== 'g') {
11275
- md.update(this.getRelatedPredicate(quad));
11404
+ if(options.algorithm === 'URDNA2015') {
11405
+ return new URDNA2015(options).main(dataset);
11406
+ }
11407
+ if(options.algorithm === 'URGNA2012') {
11408
+ if(options.createMessageDigest) {
11409
+ throw new Error(
11410
+ '"createMessageDigest" cannot be used with "URGNA2012".');
11276
11411
  }
11412
+ return new URGNA2012(options).main(dataset);
11413
+ }
11414
+ if(!('algorithm' in options)) {
11415
+ throw new Error('No RDF Dataset Canonicalization algorithm specified.');
11416
+ }
11417
+ throw new Error(
11418
+ 'Invalid RDF Dataset Canonicalization algorithm: ' + options.algorithm);
11419
+ };
11277
11420
 
11278
- // 4) Append identifier to input.
11279
- md.update(id);
11421
+ /**
11422
+ * This method is no longer available in the public API, it is for testing
11423
+ * only. It synchronously canonizes an RDF dataset and does not work in the
11424
+ * browser.
11425
+ *
11426
+ * @param {Array} dataset - The dataset to canonize.
11427
+ * @param {object} options - The options to use:
11428
+ * {string} algorithm - The canonicalization algorithm to use, `URDNA2015` or
11429
+ * `URGNA2012`.
11430
+ * {Function} [createMessageDigest] - A factory function for creating a
11431
+ * `MessageDigest` interface that overrides the built-in message digest
11432
+ * implementation used by the canonize algorithm; note that using a hash
11433
+ * algorithm (or HMAC algorithm) that differs from the one specified by
11434
+ * the canonize algorithm will result in different output.
11435
+ * {boolean} [useNative=false] - Use native implementation.
11436
+ * {number} [maxDeepIterations=Infinity] - The maximum number of times to run
11437
+ * deep comparison algorithms (such as the N-Degree Hash Quads algorithm
11438
+ * used in URDNA2015) before bailing out and throwing an error; this is a
11439
+ * useful setting for preventing wasted CPU cycles or DoS when canonizing
11440
+ * meaningless or potentially malicious datasets, a recommended value is
11441
+ * `1`.
11442
+ *
11443
+ * @return the RDF dataset in canonical form.
11444
+ */
11445
+ exports._canonizeSync = function(dataset, options) {
11446
+ // back-compat with legacy dataset
11447
+ if(!Array.isArray(dataset)) {
11448
+ dataset = exports.NQuads.legacyDatasetToQuads(dataset);
11449
+ }
11280
11450
 
11281
- // 5) Return the hash that results from passing input through the hash
11282
- // algorithm.
11283
- return md.digest();
11451
+ if(options.useNative) {
11452
+ if(!rdfCanonizeNative) {
11453
+ throw new Error('rdf-canonize-native not available');
11454
+ }
11455
+ if(options.createMessageDigest) {
11456
+ throw new Error(
11457
+ '"createMessageDigest" cannot be used with "useNative".');
11458
+ }
11459
+ return rdfCanonizeNative.canonizeSync(dataset, options);
11284
11460
  }
11285
-
11286
- // 4.8) Hash N-Degree Quads
11287
- hashNDegreeQuads(id, issuer) {
11288
- const deepIterations = this.deepIterations.get(id) || 0;
11289
- if(deepIterations > this.maxDeepIterations) {
11461
+ if(options.algorithm === 'URDNA2015') {
11462
+ return new URDNA2015Sync(options).main(dataset);
11463
+ }
11464
+ if(options.algorithm === 'URGNA2012') {
11465
+ if(options.createMessageDigest) {
11290
11466
  throw new Error(
11291
- `Maximum deep iterations (${this.maxDeepIterations}) exceeded.`);
11467
+ '"createMessageDigest" cannot be used with "URGNA2012".');
11292
11468
  }
11293
- this.deepIterations.set(id, deepIterations + 1);
11294
-
11295
- // 1) Create a hash to related blank nodes map for storing hashes that
11296
- // identify related blank nodes.
11297
- // Note: 2) and 3) handled within `createHashToRelated`
11298
- const md = this.createMessageDigest();
11299
- const hashToRelated = this.createHashToRelated(id, issuer);
11300
-
11301
- // 4) Create an empty string, data to hash.
11302
- // Note: We created a hash object `md` above instead.
11469
+ return new URGNA2012Sync(options).main(dataset);
11470
+ }
11471
+ if(!('algorithm' in options)) {
11472
+ throw new Error('No RDF Dataset Canonicalization algorithm specified.');
11473
+ }
11474
+ throw new Error(
11475
+ 'Invalid RDF Dataset Canonicalization algorithm: ' + options.algorithm);
11476
+ };
11303
11477
 
11304
- // 5) For each related hash to blank node list mapping in hash to related
11305
- // blank nodes map, sorted lexicographically by related hash:
11306
- const hashes = [...hashToRelated.keys()].sort();
11307
- for(const hash of hashes) {
11308
- // 5.1) Append the related hash to the data to hash.
11309
- md.update(hash);
11310
11478
 
11311
- // 5.2) Create a string chosen path.
11312
- let chosenPath = '';
11479
+ /***/ }),
11313
11480
 
11314
- // 5.3) Create an unset chosen issuer variable.
11315
- let chosenIssuer;
11481
+ /***/ "./node_modules/setimmediate/setImmediate.js":
11482
+ /*!***************************************************!*\
11483
+ !*** ./node_modules/setimmediate/setImmediate.js ***!
11484
+ \***************************************************/
11485
+ /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
11316
11486
 
11317
- // 5.4) For each permutation of blank node list:
11318
- const permuter = new Permuter(hashToRelated.get(hash));
11319
- while(permuter.hasNext()) {
11320
- const permutation = permuter.next();
11487
+ (function (global, undefined) {
11488
+ "use strict";
11321
11489
 
11322
- // 5.4.1) Create a copy of issuer, issuer copy.
11323
- let issuerCopy = issuer.clone();
11490
+ if (global.setImmediate) {
11491
+ return;
11492
+ }
11324
11493
 
11325
- // 5.4.2) Create a string path.
11326
- let path = '';
11494
+ var nextHandle = 1; // Spec says greater than zero
11495
+ var tasksByHandle = {};
11496
+ var currentlyRunningATask = false;
11497
+ var doc = global.document;
11498
+ var registerImmediate;
11327
11499
 
11328
- // 5.4.3) Create a recursion list, to store blank node identifiers
11329
- // that must be recursively processed by this algorithm.
11330
- const recursionList = [];
11500
+ function setImmediate(callback) {
11501
+ // Callback can either be a function or a string
11502
+ if (typeof callback !== "function") {
11503
+ callback = new Function("" + callback);
11504
+ }
11505
+ // Copy function arguments
11506
+ var args = new Array(arguments.length - 1);
11507
+ for (var i = 0; i < args.length; i++) {
11508
+ args[i] = arguments[i + 1];
11509
+ }
11510
+ // Store and register the task
11511
+ var task = { callback: callback, args: args };
11512
+ tasksByHandle[nextHandle] = task;
11513
+ registerImmediate(nextHandle);
11514
+ return nextHandle++;
11515
+ }
11331
11516
 
11332
- // 5.4.4) For each related in permutation:
11333
- let nextPermutation = false;
11334
- for(const related of permutation) {
11335
- // 5.4.4.1) If a canonical identifier has been issued for
11336
- // related, append it to path.
11337
- if(this.canonicalIssuer.hasId(related)) {
11338
- path += this.canonicalIssuer.getId(related);
11339
- } else {
11340
- // 5.4.4.2) Otherwise:
11341
- // 5.4.4.2.1) If issuer copy has not issued an identifier for
11342
- // related, append related to recursion list.
11343
- if(!issuerCopy.hasId(related)) {
11344
- recursionList.push(related);
11345
- }
11346
- // 5.4.4.2.2) Use the Issue Identifier algorithm, passing
11347
- // issuer copy and related and append the result to path.
11348
- path += issuerCopy.getId(related);
11349
- }
11517
+ function clearImmediate(handle) {
11518
+ delete tasksByHandle[handle];
11519
+ }
11350
11520
 
11351
- // 5.4.4.3) If chosen path is not empty and the length of path
11352
- // is greater than or equal to the length of chosen path and
11353
- // path is lexicographically greater than chosen path, then
11354
- // skip to the next permutation.
11355
- // Note: Comparing path length to chosen path length can be optimized
11356
- // away; only compare lexicographically.
11357
- if(chosenPath.length !== 0 && path > chosenPath) {
11358
- nextPermutation = true;
11521
+ function run(task) {
11522
+ var callback = task.callback;
11523
+ var args = task.args;
11524
+ switch (args.length) {
11525
+ case 0:
11526
+ callback();
11359
11527
  break;
11360
- }
11361
- }
11362
-
11363
- if(nextPermutation) {
11364
- continue;
11365
- }
11366
-
11367
- // 5.4.5) For each related in recursion list:
11368
- for(const related of recursionList) {
11369
- // 5.4.5.1) Set result to the result of recursively executing
11370
- // the Hash N-Degree Quads algorithm, passing related for
11371
- // identifier and issuer copy for path identifier issuer.
11372
- const result = this.hashNDegreeQuads(related, issuerCopy);
11373
-
11374
- // 5.4.5.2) Use the Issue Identifier algorithm, passing issuer
11375
- // copy and related and append the result to path.
11376
- path += issuerCopy.getId(related);
11377
-
11378
- // 5.4.5.3) Append <, the hash in result, and > to path.
11379
- path += `<${result.hash}>`;
11380
-
11381
- // 5.4.5.4) Set issuer copy to the identifier issuer in
11382
- // result.
11383
- issuerCopy = result.issuer;
11384
-
11385
- // 5.4.5.5) If chosen path is not empty and the length of path
11386
- // is greater than or equal to the length of chosen path and
11387
- // path is lexicographically greater than chosen path, then
11388
- // skip to the next permutation.
11389
- // Note: Comparing path length to chosen path length can be optimized
11390
- // away; only compare lexicographically.
11391
- if(chosenPath.length !== 0 && path > chosenPath) {
11392
- nextPermutation = true;
11528
+ case 1:
11529
+ callback(args[0]);
11530
+ break;
11531
+ case 2:
11532
+ callback(args[0], args[1]);
11533
+ break;
11534
+ case 3:
11535
+ callback(args[0], args[1], args[2]);
11536
+ break;
11537
+ default:
11538
+ callback.apply(undefined, args);
11393
11539
  break;
11394
- }
11395
- }
11396
-
11397
- if(nextPermutation) {
11398
- continue;
11399
- }
11400
-
11401
- // 5.4.6) If chosen path is empty or path is lexicographically
11402
- // less than chosen path, set chosen path to path and chosen
11403
- // issuer to issuer copy.
11404
- if(chosenPath.length === 0 || path < chosenPath) {
11405
- chosenPath = path;
11406
- chosenIssuer = issuerCopy;
11407
11540
  }
11408
- }
11409
-
11410
- // 5.5) Append chosen path to data to hash.
11411
- md.update(chosenPath);
11412
-
11413
- // 5.6) Replace issuer, by reference, with chosen issuer.
11414
- issuer = chosenIssuer;
11415
11541
  }
11416
11542
 
11417
- // 6) Return issuer and the hash that results from passing data to hash
11418
- // through the hash algorithm.
11419
- return {hash: md.digest(), issuer};
11420
- }
11421
-
11422
- // helper for modifying component during Hash First Degree Quads
11423
- modifyFirstDegreeComponent(id, component) {
11424
- if(component.termType !== 'BlankNode') {
11425
- return component;
11543
+ function runIfPresent(handle) {
11544
+ // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
11545
+ // So if we're currently running a task, we'll need to delay this invocation.
11546
+ if (currentlyRunningATask) {
11547
+ // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
11548
+ // "too much recursion" error.
11549
+ setTimeout(runIfPresent, 0, handle);
11550
+ } else {
11551
+ var task = tasksByHandle[handle];
11552
+ if (task) {
11553
+ currentlyRunningATask = true;
11554
+ try {
11555
+ run(task);
11556
+ } finally {
11557
+ clearImmediate(handle);
11558
+ currentlyRunningATask = false;
11559
+ }
11560
+ }
11561
+ }
11426
11562
  }
11427
- /* Note: A mistake in the URDNA2015 spec that made its way into
11428
- implementations (and therefore must stay to avoid interop breakage)
11429
- resulted in an assigned canonical ID, if available for
11430
- `component.value`, not being used in place of `_:a`/`_:z`, so
11431
- we don't use it here. */
11432
- return {
11433
- termType: 'BlankNode',
11434
- value: component.value === id ? '_:a' : '_:z'
11435
- };
11436
- }
11437
-
11438
- // helper for getting a related predicate
11439
- getRelatedPredicate(quad) {
11440
- return `<${quad.predicate.value}>`;
11441
- }
11442
-
11443
- // helper for creating hash to related blank nodes map
11444
- createHashToRelated(id, issuer) {
11445
- // 1) Create a hash to related blank nodes map for storing hashes that
11446
- // identify related blank nodes.
11447
- const hashToRelated = new Map();
11448
-
11449
- // 2) Get a reference, quads, to the list of quads in the blank node to
11450
- // quads map for the key identifier.
11451
- const quads = this.blankNodeInfo.get(id).quads;
11452
11563
 
11453
- // 3) For each quad in quads:
11454
- for(const quad of quads) {
11455
- // 3.1) For each component in quad, if component is the subject, object,
11456
- // or graph name and it is a blank node that is not identified by
11457
- // identifier:
11458
- // steps 3.1.1 and 3.1.2 occur in helpers:
11459
- this._addRelatedBlankNodeHash({
11460
- quad, component: quad.subject, position: 's',
11461
- id, issuer, hashToRelated
11462
- });
11463
- this._addRelatedBlankNodeHash({
11464
- quad, component: quad.object, position: 'o',
11465
- id, issuer, hashToRelated
11466
- });
11467
- this._addRelatedBlankNodeHash({
11468
- quad, component: quad.graph, position: 'g',
11469
- id, issuer, hashToRelated
11470
- });
11564
+ function installNextTickImplementation() {
11565
+ registerImmediate = function(handle) {
11566
+ process.nextTick(function () { runIfPresent(handle); });
11567
+ };
11471
11568
  }
11472
11569
 
11473
- return hashToRelated;
11474
- }
11570
+ function canUsePostMessage() {
11571
+ // The test against `importScripts` prevents this implementation from being installed inside a web worker,
11572
+ // where `global.postMessage` means something completely different and can't be used for this purpose.
11573
+ if (global.postMessage && !global.importScripts) {
11574
+ var postMessageIsAsynchronous = true;
11575
+ var oldOnMessage = global.onmessage;
11576
+ global.onmessage = function() {
11577
+ postMessageIsAsynchronous = false;
11578
+ };
11579
+ global.postMessage("", "*");
11580
+ global.onmessage = oldOnMessage;
11581
+ return postMessageIsAsynchronous;
11582
+ }
11583
+ }
11475
11584
 
11476
- _hashAndTrackBlankNode({id, hashToBlankNodes}) {
11477
- // 5.3.1) Create a hash, hash, according to the Hash First Degree
11478
- // Quads algorithm.
11479
- const hash = this.hashFirstDegreeQuads(id);
11585
+ function installPostMessageImplementation() {
11586
+ // Installs an event handler on `global` for the `message` event: see
11587
+ // * https://developer.mozilla.org/en/DOM/window.postMessage
11588
+ // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
11480
11589
 
11481
- // 5.3.2) Add hash and identifier to hash to blank nodes map,
11482
- // creating a new entry if necessary.
11483
- const idList = hashToBlankNodes.get(hash);
11484
- if(!idList) {
11485
- hashToBlankNodes.set(hash, [id]);
11486
- } else {
11487
- idList.push(id);
11488
- }
11489
- }
11590
+ var messagePrefix = "setImmediate$" + Math.random() + "$";
11591
+ var onGlobalMessage = function(event) {
11592
+ if (event.source === global &&
11593
+ typeof event.data === "string" &&
11594
+ event.data.indexOf(messagePrefix) === 0) {
11595
+ runIfPresent(+event.data.slice(messagePrefix.length));
11596
+ }
11597
+ };
11490
11598
 
11491
- _addBlankNodeQuadInfo({quad, component}) {
11492
- if(component.termType !== 'BlankNode') {
11493
- return;
11494
- }
11495
- const id = component.value;
11496
- const info = this.blankNodeInfo.get(id);
11497
- if(info) {
11498
- info.quads.add(quad);
11499
- } else {
11500
- this.blankNodeInfo.set(id, {quads: new Set([quad]), hash: null});
11501
- }
11502
- }
11599
+ if (global.addEventListener) {
11600
+ global.addEventListener("message", onGlobalMessage, false);
11601
+ } else {
11602
+ global.attachEvent("onmessage", onGlobalMessage);
11603
+ }
11503
11604
 
11504
- _addRelatedBlankNodeHash(
11505
- {quad, component, position, id, issuer, hashToRelated}) {
11506
- if(!(component.termType === 'BlankNode' && component.value !== id)) {
11507
- return;
11605
+ registerImmediate = function(handle) {
11606
+ global.postMessage(messagePrefix + handle, "*");
11607
+ };
11508
11608
  }
11509
- // 3.1.1) Set hash to the result of the Hash Related Blank Node
11510
- // algorithm, passing the blank node identifier for component as
11511
- // related, quad, path identifier issuer as issuer, and position as
11512
- // either s, o, or g based on whether component is a subject, object,
11513
- // graph name, respectively.
11514
- const related = component.value;
11515
- const hash = this.hashRelatedBlankNode(related, quad, issuer, position);
11516
11609
 
11517
- // 3.1.2) Add a mapping of hash to the blank node identifier for
11518
- // component to hash to related blank nodes map, adding an entry as
11519
- // necessary.
11520
- const entries = hashToRelated.get(hash);
11521
- if(entries) {
11522
- entries.push(related);
11523
- } else {
11524
- hashToRelated.set(hash, [related]);
11610
+ function installMessageChannelImplementation() {
11611
+ var channel = new MessageChannel();
11612
+ channel.port1.onmessage = function(event) {
11613
+ var handle = event.data;
11614
+ runIfPresent(handle);
11615
+ };
11616
+
11617
+ registerImmediate = function(handle) {
11618
+ channel.port2.postMessage(handle);
11619
+ };
11525
11620
  }
11526
- }
11527
11621
 
11528
- // canonical ids for 7.1
11529
- _componentWithCanonicalId({component}) {
11530
- if(component.termType === 'BlankNode' &&
11531
- !component.value.startsWith(this.canonicalIssuer.prefix)) {
11532
- // create new BlankNode
11533
- return {
11534
- termType: 'BlankNode',
11535
- value: this.canonicalIssuer.getId(component.value)
11536
- };
11622
+ function installReadyStateChangeImplementation() {
11623
+ var html = doc.documentElement;
11624
+ registerImmediate = function(handle) {
11625
+ // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
11626
+ // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
11627
+ var script = doc.createElement("script");
11628
+ script.onreadystatechange = function () {
11629
+ runIfPresent(handle);
11630
+ script.onreadystatechange = null;
11631
+ html.removeChild(script);
11632
+ script = null;
11633
+ };
11634
+ html.appendChild(script);
11635
+ };
11537
11636
  }
11538
- return component;
11539
- }
11540
- };
11541
11637
 
11542
- function _stringHashCompare(a, b) {
11543
- return a.hash < b.hash ? -1 : a.hash > b.hash ? 1 : 0;
11544
- }
11638
+ function installSetTimeoutImplementation() {
11639
+ registerImmediate = function(handle) {
11640
+ setTimeout(runIfPresent, 0, handle);
11641
+ };
11642
+ }
11545
11643
 
11644
+ // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
11645
+ var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
11646
+ attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
11546
11647
 
11547
- /***/ }),
11648
+ // Don't get fooled by e.g. browserify environments.
11649
+ if ({}.toString.call(global.process) === "[object process]") {
11650
+ // For Node.js before 0.9
11651
+ installNextTickImplementation();
11548
11652
 
11549
- /***/ "./node_modules/rdf-canonize/lib/URGNA2012.js":
11550
- /*!****************************************************!*\
11551
- !*** ./node_modules/rdf-canonize/lib/URGNA2012.js ***!
11552
- \****************************************************/
11553
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
11653
+ } else if (canUsePostMessage()) {
11654
+ // For non-IE10 modern browsers
11655
+ installPostMessageImplementation();
11554
11656
 
11555
- "use strict";
11556
- /*!
11557
- * Copyright (c) 2016-2022 Digital Bazaar, Inc. All rights reserved.
11558
- */
11657
+ } else if (global.MessageChannel) {
11658
+ // For web workers, where supported
11659
+ installMessageChannelImplementation();
11559
11660
 
11661
+ } else if (doc && "onreadystatechange" in doc.createElement("script")) {
11662
+ // For IE 6–8
11663
+ installReadyStateChangeImplementation();
11560
11664
 
11561
- const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
11562
- const URDNA2015 = __webpack_require__(/*! ./URDNA2015 */ "./node_modules/rdf-canonize/lib/URDNA2015.js");
11665
+ } else {
11666
+ // For older browsers
11667
+ installSetTimeoutImplementation();
11668
+ }
11563
11669
 
11564
- module.exports = class URDNA2012 extends URDNA2015 {
11565
- constructor() {
11566
- super();
11567
- this.name = 'URGNA2012';
11568
- this.createMessageDigest = () => new MessageDigest('sha1');
11569
- }
11670
+ attachTo.setImmediate = setImmediate;
11671
+ attachTo.clearImmediate = clearImmediate;
11672
+ }(typeof self === "undefined" ? typeof __webpack_require__.g === "undefined" ? this : __webpack_require__.g : self));
11570
11673
 
11571
- // helper for modifying component during Hash First Degree Quads
11572
- modifyFirstDegreeComponent(id, component, key) {
11573
- if(component.termType !== 'BlankNode') {
11574
- return component;
11575
- }
11576
- if(key === 'graph') {
11577
- return {
11578
- termType: 'BlankNode',
11579
- value: '_:g'
11580
- };
11581
- }
11582
- return {
11583
- termType: 'BlankNode',
11584
- value: (component.value === id ? '_:a' : '_:z')
11585
- };
11586
- }
11587
11674
 
11588
- // helper for getting a related predicate
11589
- getRelatedPredicate(quad) {
11590
- return quad.predicate.value;
11591
- }
11675
+ /***/ }),
11592
11676
 
11593
- // helper for creating hash to related blank nodes map
11594
- async createHashToRelated(id, issuer) {
11595
- // 1) Create a hash to related blank nodes map for storing hashes that
11596
- // identify related blank nodes.
11597
- const hashToRelated = new Map();
11677
+ /***/ "./node_modules/yallist/iterator.js":
11678
+ /*!******************************************!*\
11679
+ !*** ./node_modules/yallist/iterator.js ***!
11680
+ \******************************************/
11681
+ /***/ ((module) => {
11598
11682
 
11599
- // 2) Get a reference, quads, to the list of quads in the blank node to
11600
- // quads map for the key identifier.
11601
- const quads = this.blankNodeInfo.get(id).quads;
11683
+ "use strict";
11602
11684
 
11603
- // 3) For each quad in quads:
11604
- let i = 0;
11605
- for(const quad of quads) {
11606
- // 3.1) If the quad's subject is a blank node that does not match
11607
- // identifier, set hash to the result of the Hash Related Blank Node
11608
- // algorithm, passing the blank node identifier for subject as related,
11609
- // quad, path identifier issuer as issuer, and p as position.
11610
- let position;
11611
- let related;
11612
- if(quad.subject.termType === 'BlankNode' && quad.subject.value !== id) {
11613
- related = quad.subject.value;
11614
- position = 'p';
11615
- } else if(
11616
- quad.object.termType === 'BlankNode' && quad.object.value !== id) {
11617
- // 3.2) Otherwise, if quad's object is a blank node that does not match
11618
- // identifier, to the result of the Hash Related Blank Node algorithm,
11619
- // passing the blank node identifier for object as related, quad, path
11620
- // identifier issuer as issuer, and r as position.
11621
- related = quad.object.value;
11622
- position = 'r';
11623
- } else {
11624
- // 3.3) Otherwise, continue to the next quad.
11625
- continue;
11626
- }
11627
- // Note: batch hashing related blank nodes 100 at a time
11628
- if(++i % 100 === 0) {
11629
- await this._yield();
11630
- }
11631
- // 3.4) Add a mapping of hash to the blank node identifier for the
11632
- // component that matched (subject or object) to hash to related blank
11633
- // nodes map, adding an entry as necessary.
11634
- const hash = await this.hashRelatedBlankNode(
11635
- related, quad, issuer, position);
11636
- const entries = hashToRelated.get(hash);
11637
- if(entries) {
11638
- entries.push(related);
11639
- } else {
11640
- hashToRelated.set(hash, [related]);
11641
- }
11685
+ module.exports = function (Yallist) {
11686
+ Yallist.prototype[Symbol.iterator] = function* () {
11687
+ for (let walker = this.head; walker; walker = walker.next) {
11688
+ yield walker.value
11642
11689
  }
11643
-
11644
- return hashToRelated;
11645
11690
  }
11646
- };
11647
-
11691
+ }
11648
11692
 
11649
- /***/ }),
11650
11693
 
11651
- /***/ "./node_modules/rdf-canonize/lib/URGNA2012Sync.js":
11652
- /*!********************************************************!*\
11653
- !*** ./node_modules/rdf-canonize/lib/URGNA2012Sync.js ***!
11654
- \********************************************************/
11694
+ /***/ }),
11695
+
11696
+ /***/ "./node_modules/yallist/yallist.js":
11697
+ /*!*****************************************!*\
11698
+ !*** ./node_modules/yallist/yallist.js ***!
11699
+ \*****************************************/
11655
11700
  /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
11656
11701
 
11657
11702
  "use strict";
11658
- /*!
11659
- * Copyright (c) 2016-2021 Digital Bazaar, Inc. All rights reserved.
11660
- */
11661
11703
 
11704
+ module.exports = Yallist
11662
11705
 
11663
- const MessageDigest = __webpack_require__(/*! ./MessageDigest */ "./node_modules/rdf-canonize/lib/MessageDigest-browser.js");
11664
- const URDNA2015Sync = __webpack_require__(/*! ./URDNA2015Sync */ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js");
11706
+ Yallist.Node = Node
11707
+ Yallist.create = Yallist
11665
11708
 
11666
- module.exports = class URDNA2012Sync extends URDNA2015Sync {
11667
- constructor() {
11668
- super();
11669
- this.name = 'URGNA2012';
11670
- this.createMessageDigest = () => new MessageDigest('sha1');
11709
+ function Yallist (list) {
11710
+ var self = this
11711
+ if (!(self instanceof Yallist)) {
11712
+ self = new Yallist()
11671
11713
  }
11672
11714
 
11673
- // helper for modifying component during Hash First Degree Quads
11674
- modifyFirstDegreeComponent(id, component, key) {
11675
- if(component.termType !== 'BlankNode') {
11676
- return component;
11677
- }
11678
- if(key === 'graph') {
11679
- return {
11680
- termType: 'BlankNode',
11681
- value: '_:g'
11682
- };
11715
+ self.tail = null
11716
+ self.head = null
11717
+ self.length = 0
11718
+
11719
+ if (list && typeof list.forEach === 'function') {
11720
+ list.forEach(function (item) {
11721
+ self.push(item)
11722
+ })
11723
+ } else if (arguments.length > 0) {
11724
+ for (var i = 0, l = arguments.length; i < l; i++) {
11725
+ self.push(arguments[i])
11683
11726
  }
11684
- return {
11685
- termType: 'BlankNode',
11686
- value: (component.value === id ? '_:a' : '_:z')
11687
- };
11688
11727
  }
11689
11728
 
11690
- // helper for getting a related predicate
11691
- getRelatedPredicate(quad) {
11692
- return quad.predicate.value;
11729
+ return self
11730
+ }
11731
+
11732
+ Yallist.prototype.removeNode = function (node) {
11733
+ if (node.list !== this) {
11734
+ throw new Error('removing node which does not belong to this list')
11693
11735
  }
11694
11736
 
11695
- // helper for creating hash to related blank nodes map
11696
- createHashToRelated(id, issuer) {
11697
- // 1) Create a hash to related blank nodes map for storing hashes that
11698
- // identify related blank nodes.
11699
- const hashToRelated = new Map();
11737
+ var next = node.next
11738
+ var prev = node.prev
11700
11739
 
11701
- // 2) Get a reference, quads, to the list of quads in the blank node to
11702
- // quads map for the key identifier.
11703
- const quads = this.blankNodeInfo.get(id).quads;
11740
+ if (next) {
11741
+ next.prev = prev
11742
+ }
11704
11743
 
11705
- // 3) For each quad in quads:
11706
- for(const quad of quads) {
11707
- // 3.1) If the quad's subject is a blank node that does not match
11708
- // identifier, set hash to the result of the Hash Related Blank Node
11709
- // algorithm, passing the blank node identifier for subject as related,
11710
- // quad, path identifier issuer as issuer, and p as position.
11711
- let position;
11712
- let related;
11713
- if(quad.subject.termType === 'BlankNode' && quad.subject.value !== id) {
11714
- related = quad.subject.value;
11715
- position = 'p';
11716
- } else if(
11717
- quad.object.termType === 'BlankNode' && quad.object.value !== id) {
11718
- // 3.2) Otherwise, if quad's object is a blank node that does not match
11719
- // identifier, to the result of the Hash Related Blank Node algorithm,
11720
- // passing the blank node identifier for object as related, quad, path
11721
- // identifier issuer as issuer, and r as position.
11722
- related = quad.object.value;
11723
- position = 'r';
11724
- } else {
11725
- // 3.3) Otherwise, continue to the next quad.
11726
- continue;
11727
- }
11728
- // 3.4) Add a mapping of hash to the blank node identifier for the
11729
- // component that matched (subject or object) to hash to related blank
11730
- // nodes map, adding an entry as necessary.
11731
- const hash = this.hashRelatedBlankNode(related, quad, issuer, position);
11732
- const entries = hashToRelated.get(hash);
11733
- if(entries) {
11734
- entries.push(related);
11735
- } else {
11736
- hashToRelated.set(hash, [related]);
11737
- }
11738
- }
11744
+ if (prev) {
11745
+ prev.next = next
11746
+ }
11739
11747
 
11740
- return hashToRelated;
11748
+ if (node === this.head) {
11749
+ this.head = next
11750
+ }
11751
+ if (node === this.tail) {
11752
+ this.tail = prev
11741
11753
  }
11742
- };
11743
11754
 
11755
+ node.list.length--
11756
+ node.next = null
11757
+ node.prev = null
11758
+ node.list = null
11744
11759
 
11745
- /***/ }),
11760
+ return next
11761
+ }
11746
11762
 
11747
- /***/ "./node_modules/rdf-canonize/lib/index.js":
11748
- /*!************************************************!*\
11749
- !*** ./node_modules/rdf-canonize/lib/index.js ***!
11750
- \************************************************/
11751
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
11763
+ Yallist.prototype.unshiftNode = function (node) {
11764
+ if (node === this.head) {
11765
+ return
11766
+ }
11752
11767
 
11753
- "use strict";
11754
- /**
11755
- * An implementation of the RDF Dataset Normalization specification.
11756
- * This library works in the browser and node.js.
11757
- *
11758
- * BSD 3-Clause License
11759
- * Copyright (c) 2016-2022 Digital Bazaar, Inc.
11760
- * All rights reserved.
11761
- *
11762
- * Redistribution and use in source and binary forms, with or without
11763
- * modification, are permitted provided that the following conditions are met:
11764
- *
11765
- * Redistributions of source code must retain the above copyright notice,
11766
- * this list of conditions and the following disclaimer.
11767
- *
11768
- * Redistributions in binary form must reproduce the above copyright
11769
- * notice, this list of conditions and the following disclaimer in the
11770
- * documentation and/or other materials provided with the distribution.
11771
- *
11772
- * Neither the name of the Digital Bazaar, Inc. nor the names of its
11773
- * contributors may be used to endorse or promote products derived from
11774
- * this software without specific prior written permission.
11775
- *
11776
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
11777
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
11778
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
11779
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
11780
- * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11781
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
11782
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
11783
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
11784
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
11785
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
11786
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
11787
- */
11768
+ if (node.list) {
11769
+ node.list.removeNode(node)
11770
+ }
11788
11771
 
11772
+ var head = this.head
11773
+ node.list = this
11774
+ node.next = head
11775
+ if (head) {
11776
+ head.prev = node
11777
+ }
11789
11778
 
11790
- const URDNA2015 = __webpack_require__(/*! ./URDNA2015 */ "./node_modules/rdf-canonize/lib/URDNA2015.js");
11791
- const URGNA2012 = __webpack_require__(/*! ./URGNA2012 */ "./node_modules/rdf-canonize/lib/URGNA2012.js");
11792
- const URDNA2015Sync = __webpack_require__(/*! ./URDNA2015Sync */ "./node_modules/rdf-canonize/lib/URDNA2015Sync.js");
11793
- const URGNA2012Sync = __webpack_require__(/*! ./URGNA2012Sync */ "./node_modules/rdf-canonize/lib/URGNA2012Sync.js");
11779
+ this.head = node
11780
+ if (!this.tail) {
11781
+ this.tail = node
11782
+ }
11783
+ this.length++
11784
+ }
11794
11785
 
11795
- // optional native support
11796
- let rdfCanonizeNative;
11797
- try {
11798
- rdfCanonizeNative = __webpack_require__(/*! rdf-canonize-native */ "?2b19");
11799
- } catch(e) {}
11786
+ Yallist.prototype.pushNode = function (node) {
11787
+ if (node === this.tail) {
11788
+ return
11789
+ }
11800
11790
 
11801
- // expose helpers
11802
- exports.NQuads = __webpack_require__(/*! ./NQuads */ "./node_modules/rdf-canonize/lib/NQuads.js");
11803
- exports.IdentifierIssuer = __webpack_require__(/*! ./IdentifierIssuer */ "./node_modules/rdf-canonize/lib/IdentifierIssuer.js");
11791
+ if (node.list) {
11792
+ node.list.removeNode(node)
11793
+ }
11804
11794
 
11805
- /**
11806
- * Get or set native API.
11807
- *
11808
- * @param api the native API.
11809
- *
11810
- * @return the currently set native API.
11811
- */
11812
- exports._rdfCanonizeNative = function(api) {
11813
- if(api) {
11814
- rdfCanonizeNative = api;
11795
+ var tail = this.tail
11796
+ node.list = this
11797
+ node.prev = tail
11798
+ if (tail) {
11799
+ tail.next = node
11815
11800
  }
11816
- return rdfCanonizeNative;
11817
- };
11818
11801
 
11819
- /**
11820
- * Asynchronously canonizes an RDF dataset.
11821
- *
11822
- * @param {Array} dataset - The dataset to canonize.
11823
- * @param {object} options - The options to use:
11824
- * {string} algorithm - The canonicalization algorithm to use, `URDNA2015` or
11825
- * `URGNA2012`.
11826
- * {Function} [createMessageDigest] - A factory function for creating a
11827
- * `MessageDigest` interface that overrides the built-in message digest
11828
- * implementation used by the canonize algorithm; note that using a hash
11829
- * algorithm (or HMAC algorithm) that differs from the one specified by
11830
- * the canonize algorithm will result in different output.
11831
- * {boolean} [useNative=false] - Use native implementation.
11832
- * {number} [maxDeepIterations=Infinity] - The maximum number of times to run
11833
- * deep comparison algorithms (such as the N-Degree Hash Quads algorithm
11834
- * used in URDNA2015) before bailing out and throwing an error; this is a
11835
- * useful setting for preventing wasted CPU cycles or DoS when canonizing
11836
- * meaningless or potentially malicious datasets, a recommended value is
11837
- * `1`.
11838
- *
11839
- * @return a Promise that resolves to the canonicalized RDF Dataset.
11840
- */
11841
- exports.canonize = async function(dataset, options) {
11842
- // back-compat with legacy dataset
11843
- if(!Array.isArray(dataset)) {
11844
- dataset = exports.NQuads.legacyDatasetToQuads(dataset);
11802
+ this.tail = node
11803
+ if (!this.head) {
11804
+ this.head = node
11805
+ }
11806
+ this.length++
11807
+ }
11808
+
11809
+ Yallist.prototype.push = function () {
11810
+ for (var i = 0, l = arguments.length; i < l; i++) {
11811
+ push(this, arguments[i])
11812
+ }
11813
+ return this.length
11814
+ }
11815
+
11816
+ Yallist.prototype.unshift = function () {
11817
+ for (var i = 0, l = arguments.length; i < l; i++) {
11818
+ unshift(this, arguments[i])
11845
11819
  }
11820
+ return this.length
11821
+ }
11846
11822
 
11847
- if(options.useNative) {
11848
- if(!rdfCanonizeNative) {
11849
- throw new Error('rdf-canonize-native not available');
11850
- }
11851
- if(options.createMessageDigest) {
11852
- throw new Error(
11853
- '"createMessageDigest" cannot be used with "useNative".');
11854
- }
11855
- return new Promise((resolve, reject) =>
11856
- rdfCanonizeNative.canonize(dataset, options, (err, canonical) =>
11857
- err ? reject(err) : resolve(canonical)));
11823
+ Yallist.prototype.pop = function () {
11824
+ if (!this.tail) {
11825
+ return undefined
11858
11826
  }
11859
11827
 
11860
- if(options.algorithm === 'URDNA2015') {
11861
- return new URDNA2015(options).main(dataset);
11828
+ var res = this.tail.value
11829
+ this.tail = this.tail.prev
11830
+ if (this.tail) {
11831
+ this.tail.next = null
11832
+ } else {
11833
+ this.head = null
11862
11834
  }
11863
- if(options.algorithm === 'URGNA2012') {
11864
- if(options.createMessageDigest) {
11865
- throw new Error(
11866
- '"createMessageDigest" cannot be used with "URGNA2012".');
11867
- }
11868
- return new URGNA2012(options).main(dataset);
11835
+ this.length--
11836
+ return res
11837
+ }
11838
+
11839
+ Yallist.prototype.shift = function () {
11840
+ if (!this.head) {
11841
+ return undefined
11869
11842
  }
11870
- if(!('algorithm' in options)) {
11871
- throw new Error('No RDF Dataset Canonicalization algorithm specified.');
11843
+
11844
+ var res = this.head.value
11845
+ this.head = this.head.next
11846
+ if (this.head) {
11847
+ this.head.prev = null
11848
+ } else {
11849
+ this.tail = null
11872
11850
  }
11873
- throw new Error(
11874
- 'Invalid RDF Dataset Canonicalization algorithm: ' + options.algorithm);
11875
- };
11851
+ this.length--
11852
+ return res
11853
+ }
11876
11854
 
11877
- /**
11878
- * This method is no longer available in the public API, it is for testing
11879
- * only. It synchronously canonizes an RDF dataset and does not work in the
11880
- * browser.
11881
- *
11882
- * @param {Array} dataset - The dataset to canonize.
11883
- * @param {object} options - The options to use:
11884
- * {string} algorithm - The canonicalization algorithm to use, `URDNA2015` or
11885
- * `URGNA2012`.
11886
- * {Function} [createMessageDigest] - A factory function for creating a
11887
- * `MessageDigest` interface that overrides the built-in message digest
11888
- * implementation used by the canonize algorithm; note that using a hash
11889
- * algorithm (or HMAC algorithm) that differs from the one specified by
11890
- * the canonize algorithm will result in different output.
11891
- * {boolean} [useNative=false] - Use native implementation.
11892
- * {number} [maxDeepIterations=Infinity] - The maximum number of times to run
11893
- * deep comparison algorithms (such as the N-Degree Hash Quads algorithm
11894
- * used in URDNA2015) before bailing out and throwing an error; this is a
11895
- * useful setting for preventing wasted CPU cycles or DoS when canonizing
11896
- * meaningless or potentially malicious datasets, a recommended value is
11897
- * `1`.
11898
- *
11899
- * @return the RDF dataset in canonical form.
11900
- */
11901
- exports._canonizeSync = function(dataset, options) {
11902
- // back-compat with legacy dataset
11903
- if(!Array.isArray(dataset)) {
11904
- dataset = exports.NQuads.legacyDatasetToQuads(dataset);
11855
+ Yallist.prototype.forEach = function (fn, thisp) {
11856
+ thisp = thisp || this
11857
+ for (var walker = this.head, i = 0; walker !== null; i++) {
11858
+ fn.call(thisp, walker.value, i, this)
11859
+ walker = walker.next
11905
11860
  }
11861
+ }
11906
11862
 
11907
- if(options.useNative) {
11908
- if(!rdfCanonizeNative) {
11909
- throw new Error('rdf-canonize-native not available');
11910
- }
11911
- if(options.createMessageDigest) {
11912
- throw new Error(
11913
- '"createMessageDigest" cannot be used with "useNative".');
11914
- }
11915
- return rdfCanonizeNative.canonizeSync(dataset, options);
11863
+ Yallist.prototype.forEachReverse = function (fn, thisp) {
11864
+ thisp = thisp || this
11865
+ for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {
11866
+ fn.call(thisp, walker.value, i, this)
11867
+ walker = walker.prev
11916
11868
  }
11917
- if(options.algorithm === 'URDNA2015') {
11918
- return new URDNA2015Sync(options).main(dataset);
11869
+ }
11870
+
11871
+ Yallist.prototype.get = function (n) {
11872
+ for (var i = 0, walker = this.head; walker !== null && i < n; i++) {
11873
+ // abort out of the list early if we hit a cycle
11874
+ walker = walker.next
11919
11875
  }
11920
- if(options.algorithm === 'URGNA2012') {
11921
- if(options.createMessageDigest) {
11922
- throw new Error(
11923
- '"createMessageDigest" cannot be used with "URGNA2012".');
11924
- }
11925
- return new URGNA2012Sync(options).main(dataset);
11876
+ if (i === n && walker !== null) {
11877
+ return walker.value
11926
11878
  }
11927
- if(!('algorithm' in options)) {
11928
- throw new Error('No RDF Dataset Canonicalization algorithm specified.');
11879
+ }
11880
+
11881
+ Yallist.prototype.getReverse = function (n) {
11882
+ for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {
11883
+ // abort out of the list early if we hit a cycle
11884
+ walker = walker.prev
11929
11885
  }
11930
- throw new Error(
11931
- 'Invalid RDF Dataset Canonicalization algorithm: ' + options.algorithm);
11932
- };
11886
+ if (i === n && walker !== null) {
11887
+ return walker.value
11888
+ }
11889
+ }
11933
11890
 
11891
+ Yallist.prototype.map = function (fn, thisp) {
11892
+ thisp = thisp || this
11893
+ var res = new Yallist()
11894
+ for (var walker = this.head; walker !== null;) {
11895
+ res.push(fn.call(thisp, walker.value, this))
11896
+ walker = walker.next
11897
+ }
11898
+ return res
11899
+ }
11934
11900
 
11935
- /***/ }),
11901
+ Yallist.prototype.mapReverse = function (fn, thisp) {
11902
+ thisp = thisp || this
11903
+ var res = new Yallist()
11904
+ for (var walker = this.tail; walker !== null;) {
11905
+ res.push(fn.call(thisp, walker.value, this))
11906
+ walker = walker.prev
11907
+ }
11908
+ return res
11909
+ }
11936
11910
 
11937
- /***/ "./node_modules/setimmediate/setImmediate.js":
11938
- /*!***************************************************!*\
11939
- !*** ./node_modules/setimmediate/setImmediate.js ***!
11940
- \***************************************************/
11941
- /***/ (function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
11911
+ Yallist.prototype.reduce = function (fn, initial) {
11912
+ var acc
11913
+ var walker = this.head
11914
+ if (arguments.length > 1) {
11915
+ acc = initial
11916
+ } else if (this.head) {
11917
+ walker = this.head.next
11918
+ acc = this.head.value
11919
+ } else {
11920
+ throw new TypeError('Reduce of empty list with no initial value')
11921
+ }
11942
11922
 
11943
- (function (global, undefined) {
11944
- "use strict";
11923
+ for (var i = 0; walker !== null; i++) {
11924
+ acc = fn(acc, walker.value, i)
11925
+ walker = walker.next
11926
+ }
11945
11927
 
11946
- if (global.setImmediate) {
11947
- return;
11948
- }
11928
+ return acc
11929
+ }
11949
11930
 
11950
- var nextHandle = 1; // Spec says greater than zero
11951
- var tasksByHandle = {};
11952
- var currentlyRunningATask = false;
11953
- var doc = global.document;
11954
- var registerImmediate;
11931
+ Yallist.prototype.reduceReverse = function (fn, initial) {
11932
+ var acc
11933
+ var walker = this.tail
11934
+ if (arguments.length > 1) {
11935
+ acc = initial
11936
+ } else if (this.tail) {
11937
+ walker = this.tail.prev
11938
+ acc = this.tail.value
11939
+ } else {
11940
+ throw new TypeError('Reduce of empty list with no initial value')
11941
+ }
11955
11942
 
11956
- function setImmediate(callback) {
11957
- // Callback can either be a function or a string
11958
- if (typeof callback !== "function") {
11959
- callback = new Function("" + callback);
11960
- }
11961
- // Copy function arguments
11962
- var args = new Array(arguments.length - 1);
11963
- for (var i = 0; i < args.length; i++) {
11964
- args[i] = arguments[i + 1];
11965
- }
11966
- // Store and register the task
11967
- var task = { callback: callback, args: args };
11968
- tasksByHandle[nextHandle] = task;
11969
- registerImmediate(nextHandle);
11970
- return nextHandle++;
11971
- }
11943
+ for (var i = this.length - 1; walker !== null; i--) {
11944
+ acc = fn(acc, walker.value, i)
11945
+ walker = walker.prev
11946
+ }
11972
11947
 
11973
- function clearImmediate(handle) {
11974
- delete tasksByHandle[handle];
11975
- }
11948
+ return acc
11949
+ }
11976
11950
 
11977
- function run(task) {
11978
- var callback = task.callback;
11979
- var args = task.args;
11980
- switch (args.length) {
11981
- case 0:
11982
- callback();
11983
- break;
11984
- case 1:
11985
- callback(args[0]);
11986
- break;
11987
- case 2:
11988
- callback(args[0], args[1]);
11989
- break;
11990
- case 3:
11991
- callback(args[0], args[1], args[2]);
11992
- break;
11993
- default:
11994
- callback.apply(undefined, args);
11995
- break;
11996
- }
11997
- }
11951
+ Yallist.prototype.toArray = function () {
11952
+ var arr = new Array(this.length)
11953
+ for (var i = 0, walker = this.head; walker !== null; i++) {
11954
+ arr[i] = walker.value
11955
+ walker = walker.next
11956
+ }
11957
+ return arr
11958
+ }
11959
+
11960
+ Yallist.prototype.toArrayReverse = function () {
11961
+ var arr = new Array(this.length)
11962
+ for (var i = 0, walker = this.tail; walker !== null; i++) {
11963
+ arr[i] = walker.value
11964
+ walker = walker.prev
11965
+ }
11966
+ return arr
11967
+ }
11998
11968
 
11999
- function runIfPresent(handle) {
12000
- // From the spec: "Wait until any invocations of this algorithm started before this one have completed."
12001
- // So if we're currently running a task, we'll need to delay this invocation.
12002
- if (currentlyRunningATask) {
12003
- // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a
12004
- // "too much recursion" error.
12005
- setTimeout(runIfPresent, 0, handle);
12006
- } else {
12007
- var task = tasksByHandle[handle];
12008
- if (task) {
12009
- currentlyRunningATask = true;
12010
- try {
12011
- run(task);
12012
- } finally {
12013
- clearImmediate(handle);
12014
- currentlyRunningATask = false;
12015
- }
12016
- }
12017
- }
12018
- }
11969
+ Yallist.prototype.slice = function (from, to) {
11970
+ to = to || this.length
11971
+ if (to < 0) {
11972
+ to += this.length
11973
+ }
11974
+ from = from || 0
11975
+ if (from < 0) {
11976
+ from += this.length
11977
+ }
11978
+ var ret = new Yallist()
11979
+ if (to < from || to < 0) {
11980
+ return ret
11981
+ }
11982
+ if (from < 0) {
11983
+ from = 0
11984
+ }
11985
+ if (to > this.length) {
11986
+ to = this.length
11987
+ }
11988
+ for (var i = 0, walker = this.head; walker !== null && i < from; i++) {
11989
+ walker = walker.next
11990
+ }
11991
+ for (; walker !== null && i < to; i++, walker = walker.next) {
11992
+ ret.push(walker.value)
11993
+ }
11994
+ return ret
11995
+ }
12019
11996
 
12020
- function installNextTickImplementation() {
12021
- registerImmediate = function(handle) {
12022
- process.nextTick(function () { runIfPresent(handle); });
12023
- };
12024
- }
11997
+ Yallist.prototype.sliceReverse = function (from, to) {
11998
+ to = to || this.length
11999
+ if (to < 0) {
12000
+ to += this.length
12001
+ }
12002
+ from = from || 0
12003
+ if (from < 0) {
12004
+ from += this.length
12005
+ }
12006
+ var ret = new Yallist()
12007
+ if (to < from || to < 0) {
12008
+ return ret
12009
+ }
12010
+ if (from < 0) {
12011
+ from = 0
12012
+ }
12013
+ if (to > this.length) {
12014
+ to = this.length
12015
+ }
12016
+ for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {
12017
+ walker = walker.prev
12018
+ }
12019
+ for (; walker !== null && i > from; i--, walker = walker.prev) {
12020
+ ret.push(walker.value)
12021
+ }
12022
+ return ret
12023
+ }
12025
12024
 
12026
- function canUsePostMessage() {
12027
- // The test against `importScripts` prevents this implementation from being installed inside a web worker,
12028
- // where `global.postMessage` means something completely different and can't be used for this purpose.
12029
- if (global.postMessage && !global.importScripts) {
12030
- var postMessageIsAsynchronous = true;
12031
- var oldOnMessage = global.onmessage;
12032
- global.onmessage = function() {
12033
- postMessageIsAsynchronous = false;
12034
- };
12035
- global.postMessage("", "*");
12036
- global.onmessage = oldOnMessage;
12037
- return postMessageIsAsynchronous;
12038
- }
12039
- }
12025
+ Yallist.prototype.splice = function (start, deleteCount, ...nodes) {
12026
+ if (start > this.length) {
12027
+ start = this.length - 1
12028
+ }
12029
+ if (start < 0) {
12030
+ start = this.length + start;
12031
+ }
12040
12032
 
12041
- function installPostMessageImplementation() {
12042
- // Installs an event handler on `global` for the `message` event: see
12043
- // * https://developer.mozilla.org/en/DOM/window.postMessage
12044
- // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages
12033
+ for (var i = 0, walker = this.head; walker !== null && i < start; i++) {
12034
+ walker = walker.next
12035
+ }
12045
12036
 
12046
- var messagePrefix = "setImmediate$" + Math.random() + "$";
12047
- var onGlobalMessage = function(event) {
12048
- if (event.source === global &&
12049
- typeof event.data === "string" &&
12050
- event.data.indexOf(messagePrefix) === 0) {
12051
- runIfPresent(+event.data.slice(messagePrefix.length));
12052
- }
12053
- };
12037
+ var ret = []
12038
+ for (var i = 0; walker && i < deleteCount; i++) {
12039
+ ret.push(walker.value)
12040
+ walker = this.removeNode(walker)
12041
+ }
12042
+ if (walker === null) {
12043
+ walker = this.tail
12044
+ }
12054
12045
 
12055
- if (global.addEventListener) {
12056
- global.addEventListener("message", onGlobalMessage, false);
12057
- } else {
12058
- global.attachEvent("onmessage", onGlobalMessage);
12059
- }
12046
+ if (walker !== this.head && walker !== this.tail) {
12047
+ walker = walker.prev
12048
+ }
12060
12049
 
12061
- registerImmediate = function(handle) {
12062
- global.postMessage(messagePrefix + handle, "*");
12063
- };
12064
- }
12050
+ for (var i = 0; i < nodes.length; i++) {
12051
+ walker = insert(this, walker, nodes[i])
12052
+ }
12053
+ return ret;
12054
+ }
12065
12055
 
12066
- function installMessageChannelImplementation() {
12067
- var channel = new MessageChannel();
12068
- channel.port1.onmessage = function(event) {
12069
- var handle = event.data;
12070
- runIfPresent(handle);
12071
- };
12056
+ Yallist.prototype.reverse = function () {
12057
+ var head = this.head
12058
+ var tail = this.tail
12059
+ for (var walker = head; walker !== null; walker = walker.prev) {
12060
+ var p = walker.prev
12061
+ walker.prev = walker.next
12062
+ walker.next = p
12063
+ }
12064
+ this.head = tail
12065
+ this.tail = head
12066
+ return this
12067
+ }
12072
12068
 
12073
- registerImmediate = function(handle) {
12074
- channel.port2.postMessage(handle);
12075
- };
12076
- }
12069
+ function insert (self, node, value) {
12070
+ var inserted = node === self.head ?
12071
+ new Node(value, null, node, self) :
12072
+ new Node(value, node, node.next, self)
12077
12073
 
12078
- function installReadyStateChangeImplementation() {
12079
- var html = doc.documentElement;
12080
- registerImmediate = function(handle) {
12081
- // Create a <script> element; its readystatechange event will be fired asynchronously once it is inserted
12082
- // into the document. Do so, thus queuing up the task. Remember to clean up once it's been called.
12083
- var script = doc.createElement("script");
12084
- script.onreadystatechange = function () {
12085
- runIfPresent(handle);
12086
- script.onreadystatechange = null;
12087
- html.removeChild(script);
12088
- script = null;
12089
- };
12090
- html.appendChild(script);
12091
- };
12092
- }
12074
+ if (inserted.next === null) {
12075
+ self.tail = inserted
12076
+ }
12077
+ if (inserted.prev === null) {
12078
+ self.head = inserted
12079
+ }
12093
12080
 
12094
- function installSetTimeoutImplementation() {
12095
- registerImmediate = function(handle) {
12096
- setTimeout(runIfPresent, 0, handle);
12097
- };
12098
- }
12081
+ self.length++
12099
12082
 
12100
- // If supported, we should attach to the prototype of global, since that is where setTimeout et al. live.
12101
- var attachTo = Object.getPrototypeOf && Object.getPrototypeOf(global);
12102
- attachTo = attachTo && attachTo.setTimeout ? attachTo : global;
12083
+ return inserted
12084
+ }
12103
12085
 
12104
- // Don't get fooled by e.g. browserify environments.
12105
- if ({}.toString.call(global.process) === "[object process]") {
12106
- // For Node.js before 0.9
12107
- installNextTickImplementation();
12086
+ function push (self, item) {
12087
+ self.tail = new Node(item, self.tail, null, self)
12088
+ if (!self.head) {
12089
+ self.head = self.tail
12090
+ }
12091
+ self.length++
12092
+ }
12108
12093
 
12109
- } else if (canUsePostMessage()) {
12110
- // For non-IE10 modern browsers
12111
- installPostMessageImplementation();
12094
+ function unshift (self, item) {
12095
+ self.head = new Node(item, null, self.head, self)
12096
+ if (!self.tail) {
12097
+ self.tail = self.head
12098
+ }
12099
+ self.length++
12100
+ }
12112
12101
 
12113
- } else if (global.MessageChannel) {
12114
- // For web workers, where supported
12115
- installMessageChannelImplementation();
12102
+ function Node (value, prev, next, list) {
12103
+ if (!(this instanceof Node)) {
12104
+ return new Node(value, prev, next, list)
12105
+ }
12116
12106
 
12117
- } else if (doc && "onreadystatechange" in doc.createElement("script")) {
12118
- // For IE 6–8
12119
- installReadyStateChangeImplementation();
12107
+ this.list = list
12108
+ this.value = value
12120
12109
 
12121
- } else {
12122
- // For older browsers
12123
- installSetTimeoutImplementation();
12124
- }
12110
+ if (prev) {
12111
+ prev.next = this
12112
+ this.prev = prev
12113
+ } else {
12114
+ this.prev = null
12115
+ }
12125
12116
 
12126
- attachTo.setImmediate = setImmediate;
12127
- attachTo.clearImmediate = clearImmediate;
12128
- }(typeof self === "undefined" ? typeof __webpack_require__.g === "undefined" ? this : __webpack_require__.g : self));
12117
+ if (next) {
12118
+ next.prev = this
12119
+ this.next = next
12120
+ } else {
12121
+ this.next = null
12122
+ }
12123
+ }
12124
+
12125
+ try {
12126
+ // add if support for Symbol.iterator is present
12127
+ __webpack_require__(/*! ./iterator.js */ "./node_modules/yallist/iterator.js")(Yallist)
12128
+ } catch (er) {}
12129
12129
 
12130
12130
 
12131
12131
  /***/ })