@wdio/cli 8.8.1 → 8.8.3

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.
@@ -0,0 +1,15 @@
1
+ import type { RunCommandArguments } from '../types.js';
2
+ export declare class Launcher {
3
+ #private;
4
+ private configFilePath;
5
+ private args;
6
+ private isWatchMode;
7
+ constructor(configFilePath: string, args?: Partial<RunCommandArguments>, isWatchMode?: boolean);
8
+ /**
9
+ * run sequence
10
+ * @return {Promise} that only gets resolved with either an exitCode or an error
11
+ */
12
+ run(): Promise<undefined | number>;
13
+ }
14
+ export declare function run(): Promise<false | void>;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cjs/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEtD,qBAAa,QAAQ;;IAKb,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,WAAW;gBAFX,cAAc,EAAE,MAAM,EACtB,IAAI,GAAE,OAAO,CAAC,mBAAmB,CAAM,EACvC,WAAW,UAAQ;IAK/B;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;CAG3C;AAED,wBAAsB,GAAG,IAAI,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAGjD"}
@@ -0,0 +1,23 @@
1
+ export class Launcher {
2
+ configFilePath;
3
+ args;
4
+ isWatchMode;
5
+ #esmLauncher;
6
+ constructor(configFilePath, args = {}, isWatchMode = false) {
7
+ this.configFilePath = configFilePath;
8
+ this.args = args;
9
+ this.isWatchMode = isWatchMode;
10
+ import('../launcher.js').then(launcher => this.#esmLauncher = new launcher.default(this.configFilePath, this.args, this.isWatchMode));
11
+ }
12
+ /**
13
+ * run sequence
14
+ * @return {Promise} that only gets resolved with either an exitCode or an error
15
+ */
16
+ async run() {
17
+ return this.#esmLauncher.run();
18
+ }
19
+ }
20
+ export async function run() {
21
+ const { run } = await import('../index.js');
22
+ return run();
23
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -1,8 +1,8 @@
1
1
  import { ConfigParser } from '@wdio/config';
2
- import type { Options, Capabilities, Services } from '@wdio/types';
2
+ import type { Services } from '@wdio/types';
3
3
  import CLInterface from './interface.js';
4
4
  import type { RunCommandArguments } from './types.js';
5
- interface EndMessage {
5
+ export interface EndMessage {
6
6
  cid: string;
7
7
  exitCode: number;
8
8
  specs: string[];
@@ -27,35 +27,32 @@ declare class Launcher {
27
27
  constructor(_configFilePath: string, _args?: Partial<RunCommandArguments>, _isWatchMode?: boolean);
28
28
  /**
29
29
  * run sequence
30
- * @return {Promise} that only gets resolves with either an exitCode or an error
30
+ * @return {Promise} that only gets resolved with either an exitCode or an error
31
31
  */
32
- run(): Promise<number>;
32
+ run(): Promise<undefined | number>;
33
33
  /**
34
34
  * run without triggering onPrepare/onComplete hooks
35
35
  */
36
- runMode(config: Required<Options.Testrunner>, caps: Capabilities.RemoteCapabilities): Promise<number>;
36
+ private _runMode;
37
37
  /**
38
38
  * Format the specs into an array of objects with files and retries
39
39
  */
40
- formatSpecs(capabilities: (Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities | Capabilities.RemoteCapabilities), specFileRetries: number): {
41
- files: string[];
42
- retries: number;
43
- }[];
40
+ private _formatSpecs;
44
41
  /**
45
42
  * run multiple single remote tests
46
43
  * @return {Boolean} true if all specs have been run and all instances have finished
47
44
  */
48
- runSpecs(): boolean;
45
+ private _runSpecs;
49
46
  /**
50
47
  * gets number of all running instances
51
48
  * @return {number} number of running instances
52
49
  */
53
- getNumberOfRunningInstances(): number;
50
+ private _getNumberOfRunningInstances;
54
51
  /**
55
52
  * get number of total specs left to complete whole suites
56
53
  * @return {number} specs left to complete suite
57
54
  */
58
- getNumberOfSpecsLeft(): number;
55
+ private _getNumberOfSpecsLeft;
59
56
  /**
60
57
  * Start instance in a child process.
61
58
  * @param {Array} specs Specs to run
@@ -63,14 +60,14 @@ declare class Launcher {
63
60
  * @param {String} rid Runner ID override
64
61
  * @param {Number} retries Number of retries remaining
65
62
  */
66
- startInstance(specs: string[], caps: Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities | Capabilities.MultiRemoteCapabilities, cid: number, rid: string | undefined, retries: number): Promise<void>;
63
+ private _startInstance;
67
64
  private _workerHookError;
68
65
  /**
69
66
  * generates a runner id
70
67
  * @param {Number} cid capability id (unique identifier for a capability)
71
68
  * @return {String} runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
72
69
  */
73
- getRunnerId(cid: number): string;
70
+ private _getRunnerId;
74
71
  /**
75
72
  * Close test runner process once all child processes have exited
76
73
  * @param {Number} cid Capabilities ID
@@ -78,14 +75,14 @@ declare class Launcher {
78
75
  * @param {Array} specs Specs that were run
79
76
  * @param {Number} retries Number or retries remaining
80
77
  */
81
- endHandler({ cid: rid, exitCode, specs, retries }: EndMessage): Promise<void>;
78
+ private _endHandler;
82
79
  /**
83
80
  * We need exitHandler to catch SIGINT / SIGTERM events.
84
81
  * Make sure all started selenium sessions get closed properly and prevent
85
82
  * having dead driver processes. To do so let the runner end its Selenium
86
83
  * session first before killing
87
84
  */
88
- exitHandler(callback?: (value: boolean) => void): void | Promise<void>;
85
+ private _exitHandler;
89
86
  /**
90
87
  * returns true if user stopped watch mode, ex with ctrl+c
91
88
  * @returns {boolean}
@@ -1 +1 @@
1
- {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,WAAW,MAAM,gBAAgB,CAAA;AAGxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAkBrD,UAAU,UAAU;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,cAAM,QAAQ;IAiBN,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IAlBjB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,UAAQ;IACrB,MAAM,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAA;IAChC,SAAS,CAAC,EAAE,WAAW,CAAA;IAE9B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,wBAAwB,CAAQ;IACxC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,SAAS,CAAC,CAA4B;IAC9C,OAAO,CAAC,QAAQ,CAAC,CAAU;gBAGf,eAAe,EAAE,MAAM,EACvB,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,EACxC,YAAY,UAAQ;IAKhC;;;OAGG;IACG,GAAG;IAiGT;;OAEG;IACH,OAAO,CAAE,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC;IAyEtG;;OAEG;IACH,WAAW,CAAC,YAAY,EAAE,CAAC,YAAY,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,GAAG,YAAY,CAAC,kBAAkB,CAAC,EAAE,eAAe,EAAE,MAAM;;;;IAetJ;;;OAGG;IACH,QAAQ;IAmER;;;OAGG;IACH,2BAA2B;IAI3B;;;OAGG;IACH,oBAAoB;IAIpB;;;;;;OAMG;IACG,aAAa,CACf,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,YAAY,CAAC,mBAAmB,GAAG,YAAY,CAAC,eAAe,GAAG,YAAY,CAAC,uBAAuB,EAC5G,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,OAAO,EAAE,MAAM;IAyFnB,OAAO,CAAC,gBAAgB;IAWxB;;;;OAIG;IACH,WAAW,CAAE,GAAG,EAAE,MAAM;IAOxB;;;;;;OAMG;IACG,UAAU,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,UAAU;IA0DnE;;;;;OAKG;IACH,WAAW,CAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI;IAchD;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAG7B;AAED,eAAe,QAAQ,CAAA"}
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../src/launcher.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,aAAa,CAAA;AAElE,OAAO,WAAW,MAAM,gBAAgB,CAAA;AAGxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAkBrD,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,cAAM,QAAQ;IAiBN,OAAO,CAAC,eAAe;IACvB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,YAAY;IAlBjB,YAAY,EAAE,YAAY,CAAA;IAC1B,aAAa,UAAQ;IACrB,MAAM,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAA;IAChC,SAAS,CAAC,EAAE,WAAW,CAAA;IAE9B,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,wBAAwB,CAAQ;IACxC,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,aAAa,CAAI;IAEzB,OAAO,CAAC,SAAS,CAAC,CAA4B;IAC9C,OAAO,CAAC,QAAQ,CAAC,CAAU;gBAGf,eAAe,EAAE,MAAM,EACvB,KAAK,GAAE,OAAO,CAAC,mBAAmB,CAAM,EACxC,YAAY,UAAQ;IAKhC;;;OAGG;IACG,GAAG,IAAI,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC;IAiGxC;;OAEG;IACH,OAAO,CAAC,QAAQ;IAyEhB;;OAEG;IACH,OAAO,CAAC,YAAY;IAepB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAmEjB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAIpC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAI7B;;;;;;OAMG;YACW,cAAc;IA8F5B,OAAO,CAAC,gBAAgB;IAWxB;;;;OAIG;IACH,OAAO,CAAC,YAAY;IAOpB;;;;;;OAMG;YACW,WAAW;IA0DzB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAcpB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;CAG7B;AAED,eAAe,QAAQ,CAAA"}
package/build/launcher.js CHANGED
@@ -31,7 +31,7 @@ class Launcher {
31
31
  }
32
32
  /**
33
33
  * run sequence
34
- * @return {Promise} that only gets resolves with either an exitCode or an error
34
+ * @return {Promise} that only gets resolved with either an exitCode or an error
35
35
  */
36
36
  async run() {
37
37
  await this.configParser.initialize(this._args);
@@ -61,7 +61,7 @@ class Launcher {
61
61
  /**
62
62
  * catches ctrl+c event
63
63
  */
64
- exitHook(this.exitHandler.bind(this));
64
+ exitHook(this._exitHandler.bind(this));
65
65
  let exitCode = 0;
66
66
  let error = undefined;
67
67
  try {
@@ -80,7 +80,7 @@ class Launcher {
80
80
  log.info('Run onPrepare hook');
81
81
  await runLauncherHook(config.onPrepare, config, caps);
82
82
  await runServiceHook(this._launcher, 'onPrepare', config, caps);
83
- exitCode = await this.runMode(config, caps);
83
+ exitCode = await this._runMode(config, caps);
84
84
  /**
85
85
  * run onComplete hook
86
86
  * Even if it fails we still want to see result and end logger stream.
@@ -117,7 +117,7 @@ class Launcher {
117
117
  /**
118
118
  * run without triggering onPrepare/onComplete hooks
119
119
  */
120
- runMode(config, caps) {
120
+ _runMode(config, caps) {
121
121
  /**
122
122
  * fail if no caps were found
123
123
  */
@@ -142,7 +142,7 @@ class Launcher {
142
142
  this._schedule.push({
143
143
  cid: cid++,
144
144
  caps: caps,
145
- specs: this.formatSpecs(caps, specFileRetries),
145
+ specs: this._formatSpecs(caps, specFileRetries),
146
146
  availableInstances: config.maxInstances || 1,
147
147
  runningInstances: 0
148
148
  });
@@ -161,7 +161,7 @@ class Launcher {
161
161
  this._schedule.push({
162
162
  cid: cid++,
163
163
  caps: capabilities,
164
- specs: this.formatSpecs(capabilities, specFileRetries),
164
+ specs: this._formatSpecs(capabilities, specFileRetries),
165
165
  availableInstances,
166
166
  runningInstances: 0
167
167
  });
@@ -179,7 +179,7 @@ class Launcher {
179
179
  /**
180
180
  * return immediately if no spec was run
181
181
  */
182
- if (this.runSpecs()) {
182
+ if (this._runSpecs()) {
183
183
  resolve(0);
184
184
  }
185
185
  });
@@ -187,7 +187,7 @@ class Launcher {
187
187
  /**
188
188
  * Format the specs into an array of objects with files and retries
189
189
  */
190
- formatSpecs(capabilities, specFileRetries) {
190
+ _formatSpecs(capabilities, specFileRetries) {
191
191
  const files = this.configParser.getSpecs(capabilities.specs, capabilities.exclude);
192
192
  return files.map(file => {
193
193
  if (typeof file === 'string') {
@@ -205,7 +205,7 @@ class Launcher {
205
205
  * run multiple single remote tests
206
206
  * @return {Boolean} true if all specs have been run and all instances have finished
207
207
  */
208
- runSpecs() {
208
+ _runSpecs() {
209
209
  /**
210
210
  * stop spawning new processes when CTRL+C was triggered
211
211
  */
@@ -213,7 +213,7 @@ class Launcher {
213
213
  return true;
214
214
  }
215
215
  const config = this.configParser.getConfig();
216
- while (this.getNumberOfRunningInstances() < config.maxInstances) {
216
+ while (this._getNumberOfRunningInstances() < config.maxInstances) {
217
217
  const schedulableCaps = this._schedule
218
218
  /**
219
219
  * bail if number of errors exceeds allowed
@@ -232,7 +232,7 @@ class Launcher {
232
232
  /**
233
233
  * make sure complete number of running instances is not higher than general maxInstances number
234
234
  */
235
- .filter(() => this.getNumberOfRunningInstances() < config.maxInstances)
235
+ .filter(() => this._getNumberOfRunningInstances() < config.maxInstances)
236
236
  /**
237
237
  * make sure the capability has available capacities
238
238
  */
@@ -252,24 +252,24 @@ class Launcher {
252
252
  break;
253
253
  }
254
254
  const specs = schedulableCaps[0].specs.shift();
255
- this.startInstance(specs.files, schedulableCaps[0].caps, schedulableCaps[0].cid, specs.rid, specs.retries);
255
+ this._startInstance(specs.files, schedulableCaps[0].caps, schedulableCaps[0].cid, specs.rid, specs.retries);
256
256
  schedulableCaps[0].availableInstances--;
257
257
  schedulableCaps[0].runningInstances++;
258
258
  }
259
- return this.getNumberOfRunningInstances() === 0 && this.getNumberOfSpecsLeft() === 0;
259
+ return this._getNumberOfRunningInstances() === 0 && this._getNumberOfSpecsLeft() === 0;
260
260
  }
261
261
  /**
262
262
  * gets number of all running instances
263
263
  * @return {number} number of running instances
264
264
  */
265
- getNumberOfRunningInstances() {
265
+ _getNumberOfRunningInstances() {
266
266
  return this._schedule.map((a) => a.runningInstances).reduce((a, b) => a + b);
267
267
  }
268
268
  /**
269
269
  * get number of total specs left to complete whole suites
270
270
  * @return {number} specs left to complete suite
271
271
  */
272
- getNumberOfSpecsLeft() {
272
+ _getNumberOfSpecsLeft() {
273
273
  return this._schedule.map((a) => a.specs.length).reduce((a, b) => a + b);
274
274
  }
275
275
  /**
@@ -279,7 +279,7 @@ class Launcher {
279
279
  * @param {String} rid Runner ID override
280
280
  * @param {Number} retries Number of retries remaining
281
281
  */
282
- async startInstance(specs, caps, cid, rid, retries) {
282
+ async _startInstance(specs, caps, cid, rid, retries) {
283
283
  if (!this.runner || !this.interface) {
284
284
  throw new Error('Internal Error: no runner initialised, call run() first');
285
285
  }
@@ -290,7 +290,7 @@ class Launcher {
290
290
  }
291
291
  // Retried tests receive the cid of the failing test as rid
292
292
  // so they can run with the same cid of the failing test.
293
- const runnerId = rid || this.getRunnerId(cid);
293
+ const runnerId = rid || this._getRunnerId(cid);
294
294
  const processNumber = this._runnerStarted + 1;
295
295
  // process.debugPort defaults to 5858 and is set even when process
296
296
  // is not being debugged.
@@ -352,7 +352,7 @@ class Launcher {
352
352
  });
353
353
  worker.on('message', this.interface.onMessage.bind(this.interface));
354
354
  worker.on('error', this.interface.onMessage.bind(this.interface));
355
- worker.on('exit', this.endHandler.bind(this));
355
+ worker.on('exit', this._endHandler.bind(this));
356
356
  }
357
357
  _workerHookError(error) {
358
358
  if (!this.interface) {
@@ -368,7 +368,7 @@ class Launcher {
368
368
  * @param {Number} cid capability id (unique identifier for a capability)
369
369
  * @return {String} runner id (combination of cid and test id e.g. 0a, 0b, 1a, 1b ...)
370
370
  */
371
- getRunnerId(cid) {
371
+ _getRunnerId(cid) {
372
372
  if (!this._rid[cid]) {
373
373
  this._rid[cid] = 0;
374
374
  }
@@ -381,7 +381,7 @@ class Launcher {
381
381
  * @param {Array} specs Specs that were run
382
382
  * @param {Number} retries Number or retries remaining
383
383
  */
384
- async endHandler({ cid: rid, exitCode, specs, retries }) {
384
+ async _endHandler({ cid: rid, exitCode, specs, retries }) {
385
385
  const passed = this._isWatchModeHalted() || exitCode === 0;
386
386
  if (!passed && retries > 0) {
387
387
  // Default is true, so test for false explicitly
@@ -416,7 +416,7 @@ class Launcher {
416
416
  * - there are specs to be executed
417
417
  * - we are running watch mode
418
418
  */
419
- const shouldRunSpecs = this.runSpecs();
419
+ const shouldRunSpecs = this._runSpecs();
420
420
  const inWatchMode = this._isWatchMode && !this._hasTriggeredExitRoutine;
421
421
  if (!shouldRunSpecs || inWatchMode) {
422
422
  /**
@@ -437,7 +437,7 @@ class Launcher {
437
437
  * having dead driver processes. To do so let the runner end its Selenium
438
438
  * session first before killing
439
439
  */
440
- exitHandler(callback) {
440
+ _exitHandler(callback) {
441
441
  if (!callback || !this.runner || !this.interface) {
442
442
  return;
443
443
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/cli",
3
- "version": "8.8.1",
3
+ "version": "8.8.3",
4
4
  "description": "WebdriverIO testrunner command line interface",
5
5
  "author": "Christian Bromann <mail@bromann.dev>",
6
6
  "homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-cli",
@@ -28,17 +28,26 @@
28
28
  "bugs": {
29
29
  "url": "https://github.com/webdriverio/webdriverio/issues"
30
30
  },
31
+ "main": "./build/cjs/index.js",
31
32
  "type": "module",
33
+ "module": "./build/index.js",
32
34
  "types": "./build/index.d.ts",
33
35
  "exports": {
34
- ".": "./build/index.js",
36
+ ".": [
37
+ {
38
+ "types": "./build/index.d.ts",
39
+ "import": "./build/index.js",
40
+ "require": "./build/cjs/index.js"
41
+ },
42
+ "./build/cjs/index.js"
43
+ ],
35
44
  "./package.json": "./package.json"
36
45
  },
37
46
  "typeScriptVersion": "3.8.3",
38
47
  "dependencies": {
39
48
  "@types/node": "^18.0.0",
40
49
  "@wdio/config": "8.8.0",
41
- "@wdio/globals": "8.8.1",
50
+ "@wdio/globals": "8.8.2",
42
51
  "@wdio/logger": "8.6.6",
43
52
  "@wdio/protocols": "8.8.1",
44
53
  "@wdio/types": "8.8.0",
@@ -56,7 +65,7 @@
56
65
  "lodash.union": "^4.6.0",
57
66
  "read-pkg-up": "9.1.0",
58
67
  "recursive-readdir": "^2.2.2",
59
- "webdriverio": "8.8.1",
68
+ "webdriverio": "8.8.2",
60
69
  "yargs": "^17.5.1",
61
70
  "yarn-install": "^1.0.0"
62
71
  },
@@ -73,5 +82,5 @@
73
82
  "publishConfig": {
74
83
  "access": "public"
75
84
  },
76
- "gitHead": "9119f9fe5ae85b0c399a58e4e09ca3a824daa305"
85
+ "gitHead": "7adb7f61baef3aaf7d023165089eb8d087b81da4"
77
86
  }