@traqula/parser-sparql-1-1-adjust 0.0.9 → 0.0.12
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.
- package/lib/Parser.d.ts +1 -1
- package/lib/index.cjs +124 -63
- package/package.json +7 -7
package/lib/Parser.d.ts
CHANGED
|
@@ -211,7 +211,7 @@ export declare const adjustParserBuilder: ParserBuilder<import("@traqula/rules-s
|
|
|
211
211
|
builtInAdjust: import("@traqula/core").ParserRule<import("@traqula/rules-sparql-1-1").SparqlContext, "builtInAdjust", g11.ExpressionFunctionX<[import("@traqula/rules-sparql-1-1").Expression, import("@traqula/rules-sparql-1-1").Expression]>, []>;
|
|
212
212
|
}>;
|
|
213
213
|
export type Adjust11Parser = ReturnType<typeof adjustParserBuilder.build>;
|
|
214
|
-
export declare const adjustLexerBuilder: LexerBuilder<"BuiltInStr" | "BuiltInLang" | "BuiltInLangmatches" | "BuiltInDatatype" | "BuiltInBound" | "BuiltInIri" | "BuiltInUri" | "BuiltInBnode" | "BuiltInRand" | "BuiltInAbs" | "BuiltInCeil" | "BuiltInFloor" | "BuiltInRound" | "BuiltInConcat" | "BuiltInStrlen" | "BuiltInUcase" | "BuiltInLcase" | "BuiltInEncode_for_uri" | "BuiltInContains" | "BuiltInStrstarts" | "BuiltInStrends" | "BuiltInStrbefore" | "BuiltInStrafter" | "BuiltInYear" | "BuiltInMonth" | "BuiltInDay" | "BuiltInHours" | "BuiltInMinutes" | "BuiltInSeconds" | "BuiltInTimezone" | "BuiltInTz" | "BuiltInNow" | "BuiltInUuid" | "BuiltInStruuid" | "BuiltInMd5" | "BuiltInSha1" | "BuiltInSha256" | "BuiltInSha384" | "BuiltInSha512" | "BuiltInCoalesce" | "BuiltInIf" | "BuiltInStrlang" | "BuiltInStrdt" | "BuiltInSameterm" | "BuiltInIsiri" | "BuiltInIsuri" | "BuiltInIsblank" | "BuiltInIsliteral" | "BuiltInIsnumeric" | "BuiltInRegex" | "BuiltInSubstr" | "BuiltInReplace" | "BuiltInSum" | "BuiltInMin" | "BuiltInMax" | "BuiltInAvg" | "BuiltInSample" | "BuiltInExists" | "BuiltInNotexists" | "Pipe" | "Slash" | "From" | "Clear" | "Drop" | "Add" | "Copy" | "Move" | "InsertClause" | "DataClause" | "DeleteClause" | "Where" | "UsingClause" | "IriRef" | "PNameNs" | "PNameLn" | "BlankNodeLabel" | "Var1" | "Var2" | "LangTag" | "Double" | "Decimal" | "Integer" | "InterferePositive" | "DecimalPositive" | "DoublePositive" | "IntegerNegative" | "DecimalNegative" | "DoubleNegative" | "StringLiteralLong1" | "StringLiteralLong2" | "StringLiteral1" | "StringLiteral2" | "Ws" | "Comment" | "Nil" | "Anon" | "BaseDecl" | "PrefixDecl" | "Select" | "Distinct" | "Reduced" | "Construct" | "Describe" | "Ask" | "Having" | "GroupByGroup" | "By" | "Order" | "OrderAsc" | "OrderDesc" | "Limit" | "Offset" | "Values" | "Load" | "Silent" | "LoadInto" | "Create" | "To" | "ModifyWith" | "Optional" | "Service" | "Bind" | "Undef" | "Minus" | "Union" | "Filter" | "As" | "a" | "True" | "False" | "In" | "NotIn" | "Separator" | "BuiltInCount" | "BuiltInGroup_concat" | "NamedGraph" | "DefaultGraph" | "Graph" | "GraphAll" | "LogicAnd" | "LogicOr" | "NotEqual" | "LessThanEqual" | "GreaterThanEqual" | "LCurly" | "RCurly" | "Dot" | "Comma" | "Semi" | "LParen" | "RParen" | "LSquare" | "RSquare" | "Hathat" | "Hat" | "Question" | "Star" | "OpPlus" | "OpMinus" | "Exclamation" | "Equal" | "LessThan" | "GreaterThan"
|
|
214
|
+
export declare const adjustLexerBuilder: LexerBuilder<"BuiltInStr" | "BuiltInLang" | "BuiltInLangmatches" | "BuiltInDatatype" | "BuiltInBound" | "BuiltInIri" | "BuiltInUri" | "BuiltInBnode" | "BuiltInRand" | "BuiltInAbs" | "BuiltInCeil" | "BuiltInFloor" | "BuiltInRound" | "BuiltInConcat" | "BuiltInStrlen" | "BuiltInUcase" | "BuiltInLcase" | "BuiltInEncode_for_uri" | "BuiltInContains" | "BuiltInStrstarts" | "BuiltInStrends" | "BuiltInStrbefore" | "BuiltInStrafter" | "BuiltInYear" | "BuiltInMonth" | "BuiltInDay" | "BuiltInHours" | "BuiltInMinutes" | "BuiltInSeconds" | "BuiltInTimezone" | "BuiltInTz" | "BuiltInNow" | "BuiltInUuid" | "BuiltInStruuid" | "BuiltInMd5" | "BuiltInSha1" | "BuiltInSha256" | "BuiltInSha384" | "BuiltInSha512" | "BuiltInCoalesce" | "BuiltInIf" | "BuiltInStrlang" | "BuiltInStrdt" | "BuiltInSameterm" | "BuiltInIsiri" | "BuiltInIsuri" | "BuiltInIsblank" | "BuiltInIsliteral" | "BuiltInIsnumeric" | "BuiltInRegex" | "BuiltInSubstr" | "BuiltInReplace" | "BuiltInSum" | "BuiltInMin" | "BuiltInMax" | "BuiltInAvg" | "BuiltInSample" | "BuiltInExists" | "BuiltInNotexists" | "Pipe" | "Slash" | "From" | "Clear" | "Drop" | "Add" | "Copy" | "Move" | "InsertClause" | "DataClause" | "DeleteClause" | "Where" | "UsingClause" | "BuiltInAdjust" | "IriRef" | "PNameNs" | "PNameLn" | "BlankNodeLabel" | "Var1" | "Var2" | "LangTag" | "Double" | "Decimal" | "Integer" | "InterferePositive" | "DecimalPositive" | "DoublePositive" | "IntegerNegative" | "DecimalNegative" | "DoubleNegative" | "StringLiteralLong1" | "StringLiteralLong2" | "StringLiteral1" | "StringLiteral2" | "Ws" | "Comment" | "Nil" | "Anon" | "BaseDecl" | "PrefixDecl" | "Select" | "Distinct" | "Reduced" | "Construct" | "Describe" | "Ask" | "Having" | "GroupByGroup" | "By" | "Order" | "OrderAsc" | "OrderDesc" | "Limit" | "Offset" | "Values" | "Load" | "Silent" | "LoadInto" | "Create" | "To" | "ModifyWith" | "Optional" | "Service" | "Bind" | "Undef" | "Minus" | "Union" | "Filter" | "As" | "a" | "True" | "False" | "In" | "NotIn" | "Separator" | "BuiltInCount" | "BuiltInGroup_concat" | "NamedGraph" | "DefaultGraph" | "Graph" | "GraphAll" | "LogicAnd" | "LogicOr" | "NotEqual" | "LessThanEqual" | "GreaterThanEqual" | "LCurly" | "RCurly" | "Dot" | "Comma" | "Semi" | "LParen" | "RParen" | "LSquare" | "RSquare" | "Hathat" | "Hat" | "Question" | "Star" | "OpPlus" | "OpMinus" | "Exclamation" | "Equal" | "LessThan" | "GreaterThan">;
|
|
215
215
|
export declare class Parser extends MinimalSparqlParser<SparqlQuery> {
|
|
216
216
|
constructor();
|
|
217
217
|
}
|
package/lib/index.cjs
CHANGED
|
@@ -9747,58 +9747,115 @@ function createToken2(config) {
|
|
|
9747
9747
|
return createToken(config);
|
|
9748
9748
|
}
|
|
9749
9749
|
|
|
9750
|
-
// ../../packages/core/lib/
|
|
9751
|
-
var
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
|
|
9758
|
-
return patch(copy3);
|
|
9750
|
+
// ../../packages/core/lib/Transformers.ts
|
|
9751
|
+
var TransformerType = class {
|
|
9752
|
+
safeObjectVisit(value, mapper) {
|
|
9753
|
+
if (value && typeof value === "object") {
|
|
9754
|
+
if (Array.isArray(value)) {
|
|
9755
|
+
return value.map((x) => this.safeObjectVisit(x, mapper));
|
|
9756
|
+
}
|
|
9757
|
+
return mapper(value);
|
|
9759
9758
|
}
|
|
9760
|
-
return
|
|
9759
|
+
return value;
|
|
9761
9760
|
}
|
|
9762
|
-
|
|
9761
|
+
transformNode(curObject, nodeCallBacks) {
|
|
9762
|
+
let continueCheck;
|
|
9763
|
+
let transformation;
|
|
9764
|
+
const casted = curObject;
|
|
9765
|
+
if (casted.type) {
|
|
9766
|
+
continueCheck = nodeCallBacks[casted.type]?.continue;
|
|
9767
|
+
transformation = nodeCallBacks[casted.type]?.transform;
|
|
9768
|
+
}
|
|
9769
|
+
let shouldContinue = true;
|
|
9770
|
+
if (continueCheck) {
|
|
9771
|
+
shouldContinue = continueCheck(curObject);
|
|
9772
|
+
}
|
|
9773
|
+
if (!shouldContinue) {
|
|
9774
|
+
return curObject;
|
|
9775
|
+
}
|
|
9763
9776
|
const copy3 = { ...curObject };
|
|
9764
9777
|
for (const [key, value] of Object.entries(copy3)) {
|
|
9765
|
-
copy3[key] = this.safeObjectVisit(value, (obj) => this.
|
|
9778
|
+
copy3[key] = this.safeObjectVisit(value, (obj) => this.transformNode(obj, nodeCallBacks));
|
|
9766
9779
|
}
|
|
9767
|
-
if (
|
|
9768
|
-
return
|
|
9780
|
+
if (transformation) {
|
|
9781
|
+
return transformation(copy3);
|
|
9769
9782
|
}
|
|
9770
9783
|
return copy3;
|
|
9771
9784
|
}
|
|
9772
|
-
|
|
9773
|
-
|
|
9774
|
-
|
|
9785
|
+
visitNode(curObject, nodeCallBacks) {
|
|
9786
|
+
let callback;
|
|
9787
|
+
const casted = curObject;
|
|
9788
|
+
if (casted.type) {
|
|
9789
|
+
callback = nodeCallBacks[casted.type];
|
|
9775
9790
|
}
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
this.safeObjectVisit(value, (obj) => this.visitNode(obj, searchType, visitor));
|
|
9791
|
+
let shouldIterate = true;
|
|
9792
|
+
if (callback) {
|
|
9793
|
+
shouldIterate = callback(curObject);
|
|
9780
9794
|
}
|
|
9781
|
-
if (
|
|
9782
|
-
|
|
9795
|
+
if (shouldIterate) {
|
|
9796
|
+
for (const value of Object.values(curObject)) {
|
|
9797
|
+
this.safeObjectVisit(value, (obj) => this.visitNode(obj, nodeCallBacks));
|
|
9798
|
+
}
|
|
9783
9799
|
}
|
|
9784
9800
|
}
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9801
|
+
};
|
|
9802
|
+
var TransformerSubType = class extends TransformerType {
|
|
9803
|
+
// Public visitObjects(curObject: object, visitor: (current: object) => void): void {
|
|
9804
|
+
// for (const value of Object.values(curObject)) {
|
|
9805
|
+
// this.safeObjectVisit(value, obj => this.visitObjects(obj, visitor));
|
|
9806
|
+
// }
|
|
9807
|
+
// }
|
|
9808
|
+
transformNodeSpecific(curObject, nodeCallBacks, nodeSpecificCallBacks = {}) {
|
|
9809
|
+
let continueCheck;
|
|
9810
|
+
let transformation;
|
|
9811
|
+
const casted = curObject;
|
|
9812
|
+
if (casted.type && casted.subType) {
|
|
9813
|
+
const specific = nodeSpecificCallBacks[casted.type];
|
|
9814
|
+
if (specific) {
|
|
9815
|
+
continueCheck = specific[casted.subType]?.continue;
|
|
9816
|
+
transformation = specific[casted.subType]?.transform;
|
|
9817
|
+
}
|
|
9818
|
+
}
|
|
9819
|
+
let shouldContinue = true;
|
|
9820
|
+
if (continueCheck) {
|
|
9821
|
+
shouldContinue = continueCheck(curObject);
|
|
9822
|
+
}
|
|
9823
|
+
if (!shouldContinue) {
|
|
9824
|
+
return curObject;
|
|
9825
|
+
}
|
|
9826
|
+
const copy3 = { ...curObject };
|
|
9827
|
+
for (const [key, value] of Object.entries(copy3)) {
|
|
9828
|
+
copy3[key] = this.safeObjectVisit(value, (obj) => this.transformNodeSpecific(obj, nodeCallBacks, nodeSpecificCallBacks));
|
|
9788
9829
|
}
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
visitor(curObject);
|
|
9830
|
+
if (transformation) {
|
|
9831
|
+
return transformation(copy3);
|
|
9792
9832
|
}
|
|
9833
|
+
return copy3;
|
|
9793
9834
|
}
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9835
|
+
/**
|
|
9836
|
+
* When both nodeCallBack and NodeSpecific callBack are matched, will only look at nodeSpecifCallback
|
|
9837
|
+
*/
|
|
9838
|
+
visitNodeSpecific(curObject, nodeCallBacks, nodeSpecificCallBacks = {}) {
|
|
9839
|
+
let callback;
|
|
9840
|
+
const casted = curObject;
|
|
9841
|
+
if (casted.type && casted.subType) {
|
|
9842
|
+
const specific = nodeSpecificCallBacks[casted.type];
|
|
9843
|
+
if (specific) {
|
|
9844
|
+
callback = specific[casted.subType];
|
|
9845
|
+
}
|
|
9846
|
+
}
|
|
9847
|
+
if (!callback && casted.type) {
|
|
9848
|
+
callback = nodeCallBacks[curObject.type];
|
|
9849
|
+
}
|
|
9850
|
+
let shouldIterate = true;
|
|
9851
|
+
if (callback) {
|
|
9852
|
+
shouldIterate = callback(curObject) ?? true;
|
|
9853
|
+
}
|
|
9854
|
+
if (shouldIterate) {
|
|
9855
|
+
for (const value of Object.values(curObject)) {
|
|
9856
|
+
this.safeObjectVisit(value, (obj) => this.visitNodeSpecific(obj, nodeCallBacks, nodeSpecificCallBacks));
|
|
9798
9857
|
}
|
|
9799
|
-
return mapper(value);
|
|
9800
9858
|
}
|
|
9801
|
-
return value;
|
|
9802
9859
|
}
|
|
9803
9860
|
};
|
|
9804
9861
|
|
|
@@ -11448,9 +11505,34 @@ var Factory = class extends asArg(CoreFactory).call(ContextFactoryMixin).call(Ex
|
|
|
11448
11505
|
}
|
|
11449
11506
|
};
|
|
11450
11507
|
|
|
11508
|
+
// ../../packages/rules-sparql-1-1/lib/utils.ts
|
|
11509
|
+
function sparqlCodepointEscape(input) {
|
|
11510
|
+
const sanitizedInput = input.replaceAll(
|
|
11511
|
+
/\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{8})/gu,
|
|
11512
|
+
(_, unicode4, unicode8) => {
|
|
11513
|
+
if (unicode4) {
|
|
11514
|
+
const charCode2 = Number.parseInt(unicode4, 16);
|
|
11515
|
+
return String.fromCodePoint(charCode2);
|
|
11516
|
+
}
|
|
11517
|
+
const charCode = Number.parseInt(unicode8, 16);
|
|
11518
|
+
if (charCode < 65535) {
|
|
11519
|
+
return String.fromCodePoint(charCode);
|
|
11520
|
+
}
|
|
11521
|
+
const substractedCharCode = charCode - 65536;
|
|
11522
|
+
return String.fromCodePoint(55296 + (substractedCharCode >> 10), 56320 + (substractedCharCode & 1023));
|
|
11523
|
+
}
|
|
11524
|
+
);
|
|
11525
|
+
if (/[\uD800-\uDBFF](?:[^\uDC00-\uDFFF]|$)/u.test(sanitizedInput)) {
|
|
11526
|
+
throw new Error(`Invalid unicode codepoint of surrogate pair without corresponding codepoint`);
|
|
11527
|
+
}
|
|
11528
|
+
return sanitizedInput;
|
|
11529
|
+
}
|
|
11530
|
+
var TransformerSparql11 = class extends TransformerSubType {
|
|
11531
|
+
};
|
|
11532
|
+
|
|
11451
11533
|
// ../../packages/rules-sparql-1-1/lib/validation/validators.ts
|
|
11452
11534
|
var F = new Factory();
|
|
11453
|
-
var transformer = new
|
|
11535
|
+
var transformer = new TransformerSparql11();
|
|
11454
11536
|
function getAggregatesOfExpression(expression2) {
|
|
11455
11537
|
if (F.isExpressionAggregate(expression2)) {
|
|
11456
11538
|
return [expression2];
|
|
@@ -11599,7 +11681,9 @@ function checkNote13(patterns) {
|
|
|
11599
11681
|
if (F.isPatternBind(pattern) && index > 0 && F.isPatternBgp(patterns[index - 1])) {
|
|
11600
11682
|
const bgp = patterns[index - 1];
|
|
11601
11683
|
const variables = [];
|
|
11602
|
-
transformer.visitNodeSpecific(bgp,
|
|
11684
|
+
transformer.visitNodeSpecific(bgp, {}, { term: { variable: (var_2) => {
|
|
11685
|
+
variables.push(var_2);
|
|
11686
|
+
} } });
|
|
11603
11687
|
if (variables.some((var_2) => var_2.value === pattern.variable.value)) {
|
|
11604
11688
|
throw new Error(`Variable used to bind is already bound (?${pattern.variable.value})`);
|
|
11605
11689
|
}
|
|
@@ -11625,12 +11709,12 @@ function updateNoReuseBlankNodeLabels(updateQuery) {
|
|
|
11625
11709
|
const operation = update2.operation;
|
|
11626
11710
|
if (operation.subType === "insertdata") {
|
|
11627
11711
|
const blankNodesHere = /* @__PURE__ */ new Set();
|
|
11628
|
-
transformer.visitNodeSpecific(operation,
|
|
11712
|
+
transformer.visitNodeSpecific(operation, {}, { term: { blankNode: (blankNode2) => {
|
|
11629
11713
|
blankNodesHere.add(blankNode2.label);
|
|
11630
11714
|
if (blankLabelsUsedInInsertData.has(blankNode2.label)) {
|
|
11631
11715
|
throw new Error("Detected reuse blank node across different INSERT DATA clauses");
|
|
11632
11716
|
}
|
|
11633
|
-
});
|
|
11717
|
+
} } });
|
|
11634
11718
|
for (const blankNode2 of blankNodesHere) {
|
|
11635
11719
|
blankLabelsUsedInInsertData.add(blankNode2);
|
|
11636
11720
|
}
|
|
@@ -11638,29 +11722,6 @@ function updateNoReuseBlankNodeLabels(updateQuery) {
|
|
|
11638
11722
|
}
|
|
11639
11723
|
}
|
|
11640
11724
|
|
|
11641
|
-
// ../../packages/rules-sparql-1-1/lib/utils.ts
|
|
11642
|
-
function sparqlCodepointEscape(input) {
|
|
11643
|
-
const sanitizedInput = input.replaceAll(
|
|
11644
|
-
/\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{8})/gu,
|
|
11645
|
-
(_, unicode4, unicode8) => {
|
|
11646
|
-
if (unicode4) {
|
|
11647
|
-
const charCode2 = Number.parseInt(unicode4, 16);
|
|
11648
|
-
return String.fromCodePoint(charCode2);
|
|
11649
|
-
}
|
|
11650
|
-
const charCode = Number.parseInt(unicode8, 16);
|
|
11651
|
-
if (charCode < 65535) {
|
|
11652
|
-
return String.fromCodePoint(charCode);
|
|
11653
|
-
}
|
|
11654
|
-
const substractedCharCode = charCode - 65536;
|
|
11655
|
-
return String.fromCodePoint(55296 + (substractedCharCode >> 10), 56320 + (substractedCharCode & 1023));
|
|
11656
|
-
}
|
|
11657
|
-
);
|
|
11658
|
-
if (/[\uD800-\uDBFF](?:[^\uDC00-\uDFFF]|$)/u.test(sanitizedInput)) {
|
|
11659
|
-
throw new Error(`Invalid unicode codepoint of surrogate pair without corresponding codepoint`);
|
|
11660
|
-
}
|
|
11661
|
-
return sanitizedInput;
|
|
11662
|
-
}
|
|
11663
|
-
|
|
11664
11725
|
// ../../packages/rules-sparql-1-1/lib/grammar/literals.ts
|
|
11665
11726
|
function stringEscapedLexical(str2) {
|
|
11666
11727
|
const lexical = str2.replaceAll(/["\\\t\n\r\b\f]/gu, (char) => {
|
|
@@ -12488,7 +12549,7 @@ var aggregate = {
|
|
|
12488
12549
|
},
|
|
12489
12550
|
gImpl: ({ SUBRULE, PRINT_WORD }) => (ast, { factory: F2 }) => {
|
|
12490
12551
|
F2.printFilter(ast, () => {
|
|
12491
|
-
PRINT_WORD(ast.aggregation, "(");
|
|
12552
|
+
PRINT_WORD(ast.aggregation.toUpperCase(), "(");
|
|
12492
12553
|
if (ast.distinct) {
|
|
12493
12554
|
PRINT_WORD("DISTINCT");
|
|
12494
12555
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@traqula/parser-sparql-1-1-adjust",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.12",
|
|
4
4
|
"description": "SPARQL 1.1 + ADJUST parser",
|
|
5
5
|
"lsd:module": true,
|
|
6
6
|
"license": "MIT",
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"spec:earl": "yarn spec:earl:query && yarn spec:earl:update"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@traqula/core": "^0.0.
|
|
53
|
-
"@traqula/parser-sparql-1-1": "^0.0.
|
|
54
|
-
"@traqula/rules-sparql-1-1": "^0.0.
|
|
55
|
-
"@traqula/rules-sparql-1-1-adjust": "^0.0.
|
|
52
|
+
"@traqula/core": "^0.0.12",
|
|
53
|
+
"@traqula/parser-sparql-1-1": "^0.0.12",
|
|
54
|
+
"@traqula/rules-sparql-1-1": "^0.0.12",
|
|
55
|
+
"@traqula/rules-sparql-1-1-adjust": "^0.0.12"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@rdfjs/types": "^2.0.0",
|
|
59
|
-
"@traqula/test-utils": "^0.0.
|
|
59
|
+
"@traqula/test-utils": "^0.0.12",
|
|
60
60
|
"rdf-data-factory": "^2.0.1",
|
|
61
61
|
"rdf-test-suite": "^2.0.0"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "3517d5a5223c64dc61184b5f603f6d98c12bd166"
|
|
64
64
|
}
|