solid-ui 2.4.31 → 2.4.32

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