cspell-lib 7.3.8 → 8.0.0
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/dist/esm/FeatureFlags/FeatureFlags.js +3 -1
- package/dist/esm/LanguageIds.js +2 -2
- package/dist/esm/Models/TextDocument.js +4 -0
- package/dist/esm/Settings/Controller/ImportError.js +1 -0
- package/dist/esm/Settings/Controller/SettingsController.js +1 -0
- package/dist/esm/Settings/Controller/configLoader/configLoader.js +8 -6
- package/dist/esm/Settings/Controller/pnpLoader.js +2 -0
- package/dist/esm/Settings/DictionaryReferenceCollection.js +2 -0
- package/dist/esm/Settings/DictionarySettings.js +14 -0
- package/dist/esm/SpellingDictionary/DictionaryController/DictionaryLoader.js +5 -3
- package/dist/esm/SpellingDictionary/SpellingDictionaryError.js +4 -0
- package/dist/esm/SpellingDictionary/SuggestExperimental/SuggestionCollector.js +3 -1
- package/dist/esm/SpellingDictionary/SuggestExperimental/helpers.js +1 -1
- package/dist/esm/suggestions.js +1 -0
- package/dist/esm/textValidation/docValidator.js +9 -4
- package/dist/esm/util/AutoResolve.js +2 -6
- package/dist/esm/util/AutoResolveLRUCache.js +8 -6
- package/dist/esm/util/FreqCounter.js +2 -4
- package/dist/esm/util/MinHeapQueue.js +2 -1
- package/dist/esm/util/PairingHeap.js +3 -1
- package/dist/esm/util/Uri.js +5 -0
- package/dist/esm/util/errors.js +1 -0
- package/dist/esm/util/resolveFile.js +0 -1
- package/dist/esm/util/simpleCache.js +11 -7
- package/package.json +18 -18
|
@@ -4,8 +4,9 @@ let systemFeatureFlags;
|
|
|
4
4
|
* These are primarily used before a feature has been fully released.
|
|
5
5
|
*/
|
|
6
6
|
export class FeatureFlags {
|
|
7
|
+
flags;
|
|
8
|
+
flagValues = new Map();
|
|
7
9
|
constructor(flags = []) {
|
|
8
|
-
this.flagValues = new Map();
|
|
9
10
|
this.flags = new Map(flags.map((f) => [f.name, f]));
|
|
10
11
|
}
|
|
11
12
|
register(flagOrName, description) {
|
|
@@ -43,6 +44,7 @@ export class FeatureFlags {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
export class UnknownFeatureFlagError extends Error {
|
|
47
|
+
flag;
|
|
46
48
|
constructor(flag) {
|
|
47
49
|
super(`Unknown feature flag: ${flag}`);
|
|
48
50
|
this.flag = flag;
|
package/dist/esm/LanguageIds.js
CHANGED
|
@@ -24,7 +24,7 @@ export const languageExtensionDefinitions = [
|
|
|
24
24
|
{ id: 'css', extensions: ['.css'] },
|
|
25
25
|
{ id: 'dhall', extensions: ['.dhall'] },
|
|
26
26
|
{ id: 'diff', extensions: ['.diff', '.patch', '.rej'] },
|
|
27
|
-
{ id: 'dockerfile', extensions: ['.dockerfile'], filenames: ['Dockerfile'] },
|
|
27
|
+
{ id: 'dockerfile', extensions: ['.dockerfile'], filenames: ['Dockerfile', 'dockerfile'] },
|
|
28
28
|
{ id: 'elixir', extensions: ['.ex', '.exs'] },
|
|
29
29
|
{ id: 'fsharp', extensions: ['.fs', '.fsi', '.fsx', '.fsscript'] },
|
|
30
30
|
{ id: 'go', extensions: ['.go'] },
|
|
@@ -51,7 +51,7 @@ export const languageExtensionDefinitions = [
|
|
|
51
51
|
{ id: 'less', extensions: ['.less'] },
|
|
52
52
|
{ id: 'literate haskell', extensions: ['.lhs'] },
|
|
53
53
|
{ id: 'lua', extensions: ['.lua'] },
|
|
54
|
-
{ id: 'makefile', extensions: ['.mk'] },
|
|
54
|
+
{ id: 'makefile', extensions: ['.mk'], filenames: ['makefile'] },
|
|
55
55
|
{ id: 'markdown', extensions: ['.md', '.mdown', '.markdown', '.markdn'] },
|
|
56
56
|
{ id: 'mdx', extensions: ['.mdx'] },
|
|
57
57
|
{ id: 'monkeyc', extensions: ['.mc', '.mb'] },
|
|
@@ -4,6 +4,10 @@ import { TextDocument as VsTextDocument } from 'vscode-languageserver-textdocume
|
|
|
4
4
|
import { getLanguagesForBasename } from '../LanguageIds.js';
|
|
5
5
|
import * as Uri from '../util/Uri.js';
|
|
6
6
|
class TextDocumentImpl {
|
|
7
|
+
uri;
|
|
8
|
+
languageId;
|
|
9
|
+
locale;
|
|
10
|
+
vsTextDoc;
|
|
7
11
|
constructor(uri, text, languageId, locale, version) {
|
|
8
12
|
this.uri = uri;
|
|
9
13
|
this.languageId = languageId;
|
|
@@ -88,17 +88,18 @@ function parseJson(_filename, content) {
|
|
|
88
88
|
export const defaultConfigFilenames = Object.freeze(searchPlaces.concat());
|
|
89
89
|
let defaultConfigLoader = undefined;
|
|
90
90
|
export class ConfigLoader {
|
|
91
|
+
cspellIO;
|
|
91
92
|
/**
|
|
92
93
|
* Use `createConfigLoader`
|
|
93
94
|
* @param cspellIO - CSpellIO interface for reading files.
|
|
94
95
|
*/
|
|
95
96
|
constructor(cspellIO) {
|
|
96
97
|
this.cspellIO = cspellIO;
|
|
97
|
-
this.cachedFiles = new Map();
|
|
98
|
-
this.cspellConfigExplorer = cosmiconfig('cspell', cspellCosmiconfig);
|
|
99
|
-
this.cspellConfigExplorerSync = cosmiconfigSync('cspell', cspellCosmiconfig);
|
|
100
|
-
this.searchConfigLRU = new AutoResolveLRUCache(CACHE_SIZE_SEARCH_CONFIG, (a, b) => a.searchFrom === b.searchFrom && a.pnpSettings === b.pnpSettings);
|
|
101
98
|
}
|
|
99
|
+
cachedFiles = new Map();
|
|
100
|
+
cspellConfigExplorer = cosmiconfig('cspell', cspellCosmiconfig);
|
|
101
|
+
cspellConfigExplorerSync = cosmiconfigSync('cspell', cspellCosmiconfig);
|
|
102
|
+
globalSettings;
|
|
102
103
|
readSettings(filename, relativeToOrDefault, defaultValue) {
|
|
103
104
|
// console.log('Read Settings: %o', { filename, relativeToOrDefault });
|
|
104
105
|
const relativeTo = (typeof relativeToOrDefault === 'string' ? relativeToOrDefault : '') || process.cwd();
|
|
@@ -120,6 +121,7 @@ export class ConfigLoader {
|
|
|
120
121
|
pnpSettings = normalizePnPSettings(pnpSettings);
|
|
121
122
|
return this.searchConfigLRU.get({ searchFrom, pnpSettings }, (p) => this._searchForConfig(p));
|
|
122
123
|
}
|
|
124
|
+
searchConfigLRU = new AutoResolveLRUCache(CACHE_SIZE_SEARCH_CONFIG, (a, b) => a.searchFrom === b.searchFrom && a.pnpSettings === b.pnpSettings);
|
|
123
125
|
_searchForConfig(params) {
|
|
124
126
|
// console.log('_searchForConfig: %o', { params, stats: this.searchConfigLRU.stats() });
|
|
125
127
|
return gcl()
|
|
@@ -257,8 +259,6 @@ export class ConfigLoader {
|
|
|
257
259
|
class ConfigLoaderInternal extends ConfigLoader {
|
|
258
260
|
constructor(cspellIO) {
|
|
259
261
|
super(cspellIO);
|
|
260
|
-
this._readConfig = this.readConfig.bind(this);
|
|
261
|
-
this._normalizeSettings = this.normalizeSettings.bind(this);
|
|
262
262
|
}
|
|
263
263
|
get _cachedFiles() {
|
|
264
264
|
return this.cachedFiles;
|
|
@@ -269,6 +269,8 @@ class ConfigLoaderInternal extends ConfigLoader {
|
|
|
269
269
|
get _cspellConfigExplorerSync() {
|
|
270
270
|
return this.cspellConfigExplorerSync;
|
|
271
271
|
}
|
|
272
|
+
_readConfig = this.readConfig.bind(this);
|
|
273
|
+
_normalizeSettings = this.normalizeSettings.bind(this);
|
|
272
274
|
async normalizeSearchForConfigResultAsync(searchPath, searchResult, pnpSettings) {
|
|
273
275
|
let result;
|
|
274
276
|
try {
|
|
@@ -13,6 +13,8 @@ let lock = undefined;
|
|
|
13
13
|
const cachedPnpImportsSync = new Map();
|
|
14
14
|
const cachedRequestsSync = new Map();
|
|
15
15
|
export class PnpLoader {
|
|
16
|
+
pnpFiles;
|
|
17
|
+
cacheKeySuffix;
|
|
16
18
|
constructor(pnpFiles = defaultPnpFiles) {
|
|
17
19
|
this.pnpFiles = pnpFiles;
|
|
18
20
|
this.cacheKeySuffix = ':' + pnpFiles.join();
|
|
@@ -2,6 +2,8 @@ export function createDictionaryReferenceCollection(dictionaries) {
|
|
|
2
2
|
return new _DictionaryReferenceCollection(dictionaries);
|
|
3
3
|
}
|
|
4
4
|
class _DictionaryReferenceCollection {
|
|
5
|
+
dictionaries;
|
|
6
|
+
collection;
|
|
5
7
|
constructor(dictionaries) {
|
|
6
8
|
this.dictionaries = dictionaries;
|
|
7
9
|
this.collection = collect(dictionaries);
|
|
@@ -80,6 +80,20 @@ export function isDictionaryDefinitionInlineInternalWithSource(def) {
|
|
|
80
80
|
return isDictionaryDefinitionInlineInternal(def) && !!def.__source;
|
|
81
81
|
}
|
|
82
82
|
class _DictionaryDefinitionInternalWithSource {
|
|
83
|
+
__source;
|
|
84
|
+
_weightMap;
|
|
85
|
+
name;
|
|
86
|
+
path;
|
|
87
|
+
addWords;
|
|
88
|
+
description;
|
|
89
|
+
dictionaryInformation;
|
|
90
|
+
type;
|
|
91
|
+
file;
|
|
92
|
+
repMap;
|
|
93
|
+
useCompounds;
|
|
94
|
+
noSuggest;
|
|
95
|
+
scope;
|
|
96
|
+
ddi;
|
|
83
97
|
constructor(def, __source) {
|
|
84
98
|
this.__source = __source;
|
|
85
99
|
// this bit of assignment is to have the compiler help use if any new fields are added.
|
|
@@ -26,11 +26,13 @@ var LoadingState;
|
|
|
26
26
|
LoadingState[LoadingState["Loading"] = 1] = "Loading";
|
|
27
27
|
})(LoadingState || (LoadingState = {}));
|
|
28
28
|
export class DictionaryLoader {
|
|
29
|
+
cspellIO;
|
|
30
|
+
dictionaryCache = new StrongWeakMap();
|
|
31
|
+
inlineDictionaryCache = new AutoResolveWeakCache();
|
|
32
|
+
dictionaryCacheByDef = new StrongWeakMap();
|
|
33
|
+
reader;
|
|
29
34
|
constructor(cspellIO) {
|
|
30
35
|
this.cspellIO = cspellIO;
|
|
31
|
-
this.dictionaryCache = new StrongWeakMap();
|
|
32
|
-
this.inlineDictionaryCache = new AutoResolveWeakCache();
|
|
33
|
-
this.dictionaryCacheByDef = new StrongWeakMap();
|
|
34
36
|
this.reader = toReader(cspellIO);
|
|
35
37
|
}
|
|
36
38
|
loadDictionary(def) {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { compareResults } from './helpers.js';
|
|
2
2
|
export class SuggestionCollector {
|
|
3
|
+
size;
|
|
4
|
+
minScore;
|
|
5
|
+
results = [];
|
|
3
6
|
constructor(size, minScore) {
|
|
4
7
|
this.size = size;
|
|
5
8
|
this.minScore = minScore;
|
|
6
|
-
this.results = [];
|
|
7
9
|
}
|
|
8
10
|
get collection() {
|
|
9
11
|
return this.results.concat();
|
package/dist/esm/suggestions.js
CHANGED
|
@@ -22,16 +22,21 @@ import { calcTextInclusionRanges } from './textValidator.js';
|
|
|
22
22
|
const ERROR_NOT_PREPARED = 'Validator Must be prepared before calling this function.';
|
|
23
23
|
const skipValidation = false;
|
|
24
24
|
export class DocumentValidator {
|
|
25
|
+
settings;
|
|
26
|
+
_document;
|
|
27
|
+
_ready = false;
|
|
28
|
+
errors = [];
|
|
29
|
+
_prepared;
|
|
30
|
+
_preparations;
|
|
31
|
+
_preparationTime = -1;
|
|
32
|
+
_suggestions = new AutoCache((text) => this.genSuggestions(text), 1000);
|
|
33
|
+
options;
|
|
25
34
|
/**
|
|
26
35
|
* @param doc - Document to validate
|
|
27
36
|
* @param config - configuration to use (not finalized).
|
|
28
37
|
*/
|
|
29
38
|
constructor(doc, options, settings) {
|
|
30
39
|
this.settings = settings;
|
|
31
|
-
this._ready = false;
|
|
32
|
-
this.errors = [];
|
|
33
|
-
this._preparationTime = -1;
|
|
34
|
-
this._suggestions = new AutoCache((text) => this.genSuggestions(text), 1000);
|
|
35
40
|
this._document = doc;
|
|
36
41
|
this.options = { ...options };
|
|
37
42
|
const numSuggestions = this.options.numSuggestions ?? settings.numSuggestions;
|
|
@@ -7,9 +7,7 @@ export function autoResolve(map, key, resolve) {
|
|
|
7
7
|
return value;
|
|
8
8
|
}
|
|
9
9
|
export class AutoResolveCache {
|
|
10
|
-
|
|
11
|
-
this.map = new Map();
|
|
12
|
-
}
|
|
10
|
+
map = new Map();
|
|
13
11
|
get(k, resolve) {
|
|
14
12
|
return resolve ? autoResolve(this.map, k, resolve) : this.map.get(k);
|
|
15
13
|
}
|
|
@@ -33,9 +31,7 @@ export function autoResolveWeak(map, key, resolve) {
|
|
|
33
31
|
return value;
|
|
34
32
|
}
|
|
35
33
|
export class AutoResolveWeakCache {
|
|
36
|
-
|
|
37
|
-
this.map = new WeakMap();
|
|
38
|
-
}
|
|
34
|
+
map = new WeakMap();
|
|
39
35
|
get(k, resolve) {
|
|
40
36
|
return resolve ? autoResolveWeak(this.map, k, resolve) : this.map.get(k);
|
|
41
37
|
}
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
2
|
import { isArrayEqual } from './util.js';
|
|
3
3
|
export class AutoResolveLRUCache {
|
|
4
|
+
maxSize;
|
|
5
|
+
isEqual;
|
|
6
|
+
list = {};
|
|
7
|
+
count = 0;
|
|
8
|
+
_misses = 0;
|
|
9
|
+
_hits = 0;
|
|
10
|
+
_added = 0;
|
|
11
|
+
_removed = 0;
|
|
4
12
|
constructor(maxSize, isEqual) {
|
|
5
13
|
this.maxSize = maxSize;
|
|
6
14
|
this.isEqual = isEqual;
|
|
7
|
-
this.list = {};
|
|
8
|
-
this.count = 0;
|
|
9
|
-
this._misses = 0;
|
|
10
|
-
this._hits = 0;
|
|
11
|
-
this._added = 0;
|
|
12
|
-
this._removed = 0;
|
|
13
15
|
assert(maxSize > 0);
|
|
14
16
|
}
|
|
15
17
|
get(params, fn) {
|
|
@@ -46,9 +46,10 @@ function takeFromHeap(t, compare) {
|
|
|
46
46
|
* MinHeapQueue - based upon a minHeap array.
|
|
47
47
|
*/
|
|
48
48
|
export class MinHeapQueue {
|
|
49
|
+
compare;
|
|
50
|
+
values = [];
|
|
49
51
|
constructor(compare) {
|
|
50
52
|
this.compare = compare;
|
|
51
|
-
this.values = [];
|
|
52
53
|
}
|
|
53
54
|
add(t) {
|
|
54
55
|
addToHeap(this.values, t, this.compare);
|
package/dist/esm/util/Uri.js
CHANGED
|
@@ -72,6 +72,11 @@ export function from(uri, ...parts) {
|
|
|
72
72
|
}
|
|
73
73
|
const keys = ['scheme', 'authority', 'path', 'query', 'fragment'];
|
|
74
74
|
class UriImpl {
|
|
75
|
+
scheme;
|
|
76
|
+
authority;
|
|
77
|
+
path;
|
|
78
|
+
query;
|
|
79
|
+
fragment;
|
|
75
80
|
constructor(uri) {
|
|
76
81
|
this.scheme = uri.scheme || '';
|
|
77
82
|
uri.authority && (this.authority = uri.authority);
|
package/dist/esm/util/errors.js
CHANGED
|
@@ -14,7 +14,6 @@ const testNodeModules = /^node_modules\//;
|
|
|
14
14
|
* @param relativeTo absolute path
|
|
15
15
|
*/
|
|
16
16
|
export function resolveFile(filename, relativeTo) {
|
|
17
|
-
filename.startsWith('@cspell/cspell-json') && console.warn('%o', { filename, relativeTo });
|
|
18
17
|
filename = filename.replace(/^~/, os.homedir());
|
|
19
18
|
const steps = [
|
|
20
19
|
{ filename, fn: tryUrl },
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export class SimpleWeakCache {
|
|
2
|
+
size;
|
|
3
|
+
L0 = new WeakMap();
|
|
4
|
+
L1 = new WeakMap();
|
|
5
|
+
L2 = new WeakMap();
|
|
6
|
+
sizeL0 = 0;
|
|
2
7
|
constructor(size) {
|
|
3
8
|
this.size = size;
|
|
4
|
-
this.L0 = new WeakMap();
|
|
5
|
-
this.L1 = new WeakMap();
|
|
6
|
-
this.L2 = new WeakMap();
|
|
7
|
-
this.sizeL0 = 0;
|
|
8
9
|
}
|
|
9
10
|
has(key) {
|
|
10
11
|
for (const c of this.caches()) {
|
|
@@ -50,6 +51,7 @@ export class SimpleWeakCache {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
export class AutoWeakCache extends SimpleWeakCache {
|
|
54
|
+
factory;
|
|
53
55
|
constructor(factory, size) {
|
|
54
56
|
super(size);
|
|
55
57
|
this.factory = factory;
|
|
@@ -72,11 +74,12 @@ export class AutoWeakCache extends SimpleWeakCache {
|
|
|
72
74
|
* promoted to L0.
|
|
73
75
|
*/
|
|
74
76
|
export class SimpleCache {
|
|
77
|
+
size;
|
|
78
|
+
L0 = new Map();
|
|
79
|
+
L1 = new Map();
|
|
80
|
+
L2 = new Map();
|
|
75
81
|
constructor(size) {
|
|
76
82
|
this.size = size;
|
|
77
|
-
this.L0 = new Map();
|
|
78
|
-
this.L1 = new Map();
|
|
79
|
-
this.L2 = new Map();
|
|
80
83
|
}
|
|
81
84
|
has(key) {
|
|
82
85
|
for (const c of this.caches()) {
|
|
@@ -120,6 +123,7 @@ export class SimpleCache {
|
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
export class AutoCache extends SimpleCache {
|
|
126
|
+
factory;
|
|
123
127
|
constructor(factory, size) {
|
|
124
128
|
super(size);
|
|
125
129
|
this.factory = factory;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cspell-lib",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "8.0.0",
|
|
4
4
|
"description": "A library of useful functions used across various cspell tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "dist/esm/index.d.ts",
|
|
@@ -56,21 +56,21 @@
|
|
|
56
56
|
},
|
|
57
57
|
"homepage": "https://github.com/streetsidesoftware/cspell#readme",
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@cspell/cspell-bundled-dicts": "
|
|
60
|
-
"@cspell/cspell-pipe": "
|
|
61
|
-
"@cspell/cspell-resolver": "
|
|
62
|
-
"@cspell/cspell-types": "
|
|
63
|
-
"@cspell/dynamic-import": "
|
|
64
|
-
"@cspell/strong-weak-map": "
|
|
59
|
+
"@cspell/cspell-bundled-dicts": "8.0.0",
|
|
60
|
+
"@cspell/cspell-pipe": "8.0.0",
|
|
61
|
+
"@cspell/cspell-resolver": "8.0.0",
|
|
62
|
+
"@cspell/cspell-types": "8.0.0",
|
|
63
|
+
"@cspell/dynamic-import": "8.0.0",
|
|
64
|
+
"@cspell/strong-weak-map": "8.0.0",
|
|
65
65
|
"clear-module": "^4.1.2",
|
|
66
66
|
"comment-json": "^4.2.3",
|
|
67
67
|
"configstore": "^6.0.0",
|
|
68
68
|
"cosmiconfig": "8.0.0",
|
|
69
|
-
"cspell-dictionary": "
|
|
70
|
-
"cspell-glob": "
|
|
71
|
-
"cspell-grammar": "
|
|
72
|
-
"cspell-io": "
|
|
73
|
-
"cspell-trie-lib": "
|
|
69
|
+
"cspell-dictionary": "8.0.0",
|
|
70
|
+
"cspell-glob": "8.0.0",
|
|
71
|
+
"cspell-grammar": "8.0.0",
|
|
72
|
+
"cspell-io": "8.0.0",
|
|
73
|
+
"cspell-trie-lib": "8.0.0",
|
|
74
74
|
"fast-equals": "^5.0.1",
|
|
75
75
|
"find-up": "^6.3.0",
|
|
76
76
|
"gensequence": "^6.0.0",
|
|
@@ -80,20 +80,20 @@
|
|
|
80
80
|
"vscode-uri": "^3.0.8"
|
|
81
81
|
},
|
|
82
82
|
"engines": {
|
|
83
|
-
"node": ">=
|
|
83
|
+
"node": ">=18"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@cspell/dict-cpp": "^5.0.
|
|
86
|
+
"@cspell/dict-cpp": "^5.0.9",
|
|
87
87
|
"@cspell/dict-csharp": "^4.0.2",
|
|
88
88
|
"@cspell/dict-css": "^4.0.12",
|
|
89
89
|
"@cspell/dict-fa-ir": "^3.0.0",
|
|
90
90
|
"@cspell/dict-fr-fr": "^2.2.2",
|
|
91
91
|
"@cspell/dict-html": "^4.0.5",
|
|
92
|
-
"@cspell/dict-nl-nl": "^2.
|
|
93
|
-
"@cspell/dict-python": "^4.1.
|
|
94
|
-
"@types/configstore": "^6.0.
|
|
92
|
+
"@cspell/dict-nl-nl": "^2.3.0",
|
|
93
|
+
"@cspell/dict-python": "^4.1.10",
|
|
94
|
+
"@types/configstore": "^6.0.2",
|
|
95
95
|
"cspell-dict-nl-nl": "^1.1.2",
|
|
96
96
|
"lorem-ipsum": "^2.0.8"
|
|
97
97
|
},
|
|
98
|
-
"gitHead": "
|
|
98
|
+
"gitHead": "67c22bf98baed1c17bbc658fba8656262d17e370"
|
|
99
99
|
}
|