@panneau/medias 3.0.137 → 3.0.140

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/es/index.js +100 -47
  2. package/lib/index.js +98 -45
  3. package/package.json +12 -12
package/es/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
2
- import React, { useContext, useMemo, useCallback, useState } from 'react';
2
+ import React, { useContext, useMemo, useCallback, useState, useEffect } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import _objectSpread from '@babel/runtime/helpers/objectSpread2';
5
5
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
6
6
  import classNames from 'classnames';
7
7
  import { PropTypes as PropTypes$1 } from '@panneau/core';
8
- import { useQuery } from '@panneau/core/hooks';
8
+ import { useQuery, useItemSelection } from '@panneau/core/hooks';
9
9
  import Buttons from '@panneau/element-buttons';
10
10
  import Grid from '@panneau/element-grid';
11
11
  import Icon from '@panneau/element-icon';
@@ -324,7 +324,8 @@ var defaultFilters = [{
324
324
  }]
325
325
  }),
326
326
  value: 'audio'
327
- }]
327
+ }],
328
+ multiple: true
328
329
  }, {
329
330
  id: 'author',
330
331
  component: 'select',
@@ -336,7 +337,8 @@ var defaultFilters = [{
336
337
  "value": "Author"
337
338
  }]
338
339
  }),
339
- options: []
340
+ options: [],
341
+ multiple: true
340
342
  }, {
341
343
  id: 'tag',
342
344
  component: 'select',
@@ -348,7 +350,8 @@ var defaultFilters = [{
348
350
  "value": "Tag"
349
351
  }]
350
352
  }),
351
- options: []
353
+ options: [],
354
+ multiple: true
352
355
  }, {
353
356
  id: 'search',
354
357
  component: 'search',
@@ -369,6 +372,9 @@ var propTypes$4 = {
369
372
  layouts: PropTypes.arrayOf(PropTypes.shape({})),
370
373
  theme: PropTypes.string,
371
374
  tableProps: PropTypes.bool,
375
+ onItemsChange: PropTypes.func,
376
+ selectedCount: PropTypes.number,
377
+ onClearSelected: PropTypes.func,
372
378
  className: PropTypes.string
373
379
  };
374
380
  var defaultProps$4 = {
@@ -378,7 +384,7 @@ var defaultProps$4 = {
378
384
  // fields: null,
379
385
  query: null,
380
386
  baseUrl: null,
381
- layout: null,
387
+ layout: 'table',
382
388
  layouts: [{
383
389
  id: 'table',
384
390
  label: /*#__PURE__*/React.createElement(Icon, {
@@ -392,6 +398,9 @@ var defaultProps$4 = {
392
398
  }],
393
399
  theme: null,
394
400
  tableProps: null,
401
+ onItemsChange: null,
402
+ selectedCount: null,
403
+ onClearSelected: null,
395
404
  className: null
396
405
  };
397
406
  function MediasBrowser(_ref) {
@@ -404,6 +413,9 @@ function MediasBrowser(_ref) {
404
413
  layouts = _ref.layouts,
405
414
  theme = _ref.theme,
406
415
  tableProps = _ref.tableProps,
416
+ onItemsChange = _ref.onItemsChange,
417
+ selectedCount = _ref.selectedCount,
418
+ onClearSelected = _ref.onClearSelected,
407
419
  className = _ref.className;
408
420
  var baseQuery = useMemo(function () {
409
421
  return initialQuery;
@@ -439,6 +451,9 @@ function MediasBrowser(_ref) {
439
451
  loading = _useMedias.loading,
440
452
  lastPage = _useMedias.lastPage,
441
453
  total = _useMedias.total;
454
+ useEffect(function () {
455
+ onItemsChange(items);
456
+ }, [items, onItemsChange]);
442
457
  var _useState = useState(initialLayout || 'grid'),
443
458
  _useState2 = _slicedToArray(_useState, 2),
444
459
  layout = _useState2[0],
@@ -449,6 +464,20 @@ function MediasBrowser(_ref) {
449
464
  var onClickLayout = useCallback(function (lay) {
450
465
  setLayout(lay);
451
466
  }, [setLayout]);
467
+ var pagination = /*#__PURE__*/React.createElement(Pagination, {
468
+ page: page,
469
+ lastPage: lastPage,
470
+ total: total,
471
+ url: baseUrl,
472
+ query: query,
473
+ onClickPage: onPageChange,
474
+ theme: theme,
475
+ loading: loading,
476
+ selectedCount: selectedCount,
477
+ onClearSelected: onClearSelected,
478
+ withPreviousNext: true,
479
+ alwaysShowButtons: true
480
+ });
452
481
  return /*#__PURE__*/React.createElement("div", {
453
482
  className: classNames([styles.container, className])
454
483
  }, /*#__PURE__*/React.createElement(Filters, {
@@ -471,21 +500,11 @@ function MediasBrowser(_ref) {
471
500
  active: layout === lay.id,
472
501
  onClick: function onClick() {
473
502
  return onClickLayout(lay.id);
474
- }
503
+ },
504
+ className: 'px-3'
475
505
  });
476
506
  })
477
- }) : null, /*#__PURE__*/React.createElement(Pagination, {
478
- page: page,
479
- lastPage: lastPage,
480
- total: total,
481
- url: baseUrl,
482
- query: query,
483
- onClickPage: onPageChange,
484
- theme: theme,
485
- loading: loading,
486
- withPreviousNext: true,
487
- alwaysShowButtons: true
488
- })), layout === 'grid' ? /*#__PURE__*/React.createElement(Grid, Object.assign({}, tableProps, {
507
+ }) : null, pagination), layout === 'grid' ? /*#__PURE__*/React.createElement(Grid, Object.assign({}, tableProps, {
489
508
  items: items || [],
490
509
  component: MediaCard,
491
510
  componentProps: {
@@ -500,18 +519,7 @@ function MediasBrowser(_ref) {
500
519
  }, "\u2014")
501
520
  })), /*#__PURE__*/React.createElement("div", {
502
521
  className: classNames(['d-flex', 'mt-3', 'mb-1', 'justify-content-end'])
503
- }, /*#__PURE__*/React.createElement(Pagination, {
504
- page: page,
505
- lastPage: lastPage,
506
- total: total,
507
- url: baseUrl,
508
- query: query,
509
- onClickPage: onPageChange,
510
- theme: theme,
511
- loading: loading,
512
- withPreviousNext: true,
513
- alwaysShowButtons: true
514
- })));
522
+ }, pagination));
515
523
  }
516
524
  MediasBrowser.propTypes = propTypes$4;
517
525
  MediasBrowser.defaultProps = defaultProps$4;
@@ -533,54 +541,99 @@ function MediasBrowserContainer(_ref) {
533
541
  MediasBrowserContainer.propTypes = propTypes$3;
534
542
  MediasBrowserContainer.defaultProps = defaultProps$3;
535
543
 
536
- var _excluded$2 = ["value", "onChange", "onConfirm", "multiple", "className"];
544
+ var _excluded$2 = ["value", "selectedItems", "onChange", "onConfirm", "onClose", "multiple", "withoutButtons", "className"];
537
545
  var propTypes$2 = {
538
546
  // eslint-disable-next-line react/forbid-prop-types
539
- value: PropTypes.any,
547
+ value: PropTypes.arrayOf(PropTypes.shape({})),
548
+ selectedItems: PropTypes.arrayOf(PropTypes.shape({})),
540
549
  onChange: PropTypes.func.isRequired,
541
550
  onConfirm: PropTypes.func.isRequired,
551
+ onClose: PropTypes.func,
542
552
  multiple: PropTypes.bool,
553
+ withoutButtons: PropTypes.bool,
543
554
  className: PropTypes.string
544
555
  };
545
556
  var defaultProps$2 = {
546
557
  value: null,
558
+ selectedItems: null,
559
+ onClose: null,
547
560
  multiple: false,
561
+ withoutButtons: false,
548
562
  className: null
549
563
  };
550
564
  function MediasPicker(_ref) {
551
565
  var value = _ref.value,
566
+ initialSelectedItems = _ref.selectedItems,
552
567
  onChange = _ref.onChange,
553
568
  onConfirm = _ref.onConfirm,
569
+ onClose = _ref.onClose,
554
570
  multiple = _ref.multiple,
571
+ withoutButtons = _ref.withoutButtons,
555
572
  className = _ref.className,
556
573
  props = _objectWithoutProperties(_ref, _excluded$2);
557
- var onSelectionChange = useCallback(function (items) {
558
- if (onChange !== null) {
559
- onChange(items);
560
- }
561
- }, [onChange]);
574
+ var _useState = useState(value),
575
+ _useState2 = _slicedToArray(_useState, 2),
576
+ items = _useState2[0],
577
+ setItems = _useState2[1];
578
+ var onItemsChange = useCallback(function (pageItems) {
579
+ setItems(pageItems);
580
+ }, [setItems]);
562
581
  var disabled = value === null || value.length < 1;
582
+ var _useItemSelection = useItemSelection({
583
+ items: items,
584
+ selectedItems: initialSelectedItems,
585
+ onSelectionChange: onChange,
586
+ multipleSelection: multiple
587
+ }),
588
+ onSelectItem = _useItemSelection.onSelectItem,
589
+ onSelectPage = _useItemSelection.onSelectPage,
590
+ onClearSelected = _useItemSelection.onClearSelected,
591
+ pageSelected = _useItemSelection.pageSelected,
592
+ selectedCount = _useItemSelection.selectedCount,
593
+ selectedItems = _useItemSelection.selectedItems;
563
594
  return /*#__PURE__*/React.createElement("div", {
564
595
  className: className
565
596
  }, /*#__PURE__*/React.createElement(MediasBrowser, Object.assign({
566
597
  tableProps: {
567
598
  selectable: true,
568
599
  multipleSelection: multiple,
569
- onSelectionChange: onSelectionChange
570
- }
571
- }, props)), multiple ? /*#__PURE__*/React.createElement(Button, {
572
- className: "mt-2",
600
+ onSelectItem: onSelectItem,
601
+ onSelectPage: onSelectPage,
602
+ selectedItems: selectedItems,
603
+ pageSelected: pageSelected
604
+ },
605
+ onItemsChange: onItemsChange,
606
+ selectedCount: selectedCount,
607
+ onClearSelected: onClearSelected
608
+ }, props)), multiple && !withoutButtons ? /*#__PURE__*/React.createElement("div", {
609
+ className: "d-flex w-100 align-items-end justify-content-end mt-3"
610
+ }, /*#__PURE__*/React.createElement("div", {
611
+ className: "btn-group"
612
+ }, onClose !== null ? /*#__PURE__*/React.createElement(Button, {
613
+ type: "button",
614
+ theme: "secondary",
615
+ onClick: onClose,
616
+ className: "d-block me-2"
617
+ }, /*#__PURE__*/React.createElement(FormattedMessage, {
618
+ id: "PyxZY2",
619
+ defaultMessage: [{
620
+ "type": 0,
621
+ "value": "Cancel"
622
+ }]
623
+ })) : null, /*#__PURE__*/React.createElement(Button, {
624
+ type: "button",
625
+ theme: "primary",
573
626
  onClick: onConfirm,
574
- theme: "info",
575
627
  disabled: disabled,
576
- outline: disabled
628
+ outline: disabled,
629
+ className: "d-block"
577
630
  }, /*#__PURE__*/React.createElement(FormattedMessage, {
578
- id: "UaVu03",
631
+ id: "rvOVCV",
579
632
  defaultMessage: [{
580
633
  "type": 0,
581
- "value": "Confirm"
634
+ "value": "Confirm selection"
582
635
  }]
583
- })) : null);
636
+ })))) : null);
584
637
  }
585
638
  MediasPicker.propTypes = propTypes$2;
586
639
  MediasPicker.defaultProps = defaultProps$2;
package/lib/index.js CHANGED
@@ -328,7 +328,8 @@ var defaultFilters = [{
328
328
  }]
329
329
  }),
330
330
  value: 'audio'
331
- }]
331
+ }],
332
+ multiple: true
332
333
  }, {
333
334
  id: 'author',
334
335
  component: 'select',
@@ -340,7 +341,8 @@ var defaultFilters = [{
340
341
  "value": "Author"
341
342
  }]
342
343
  }),
343
- options: []
344
+ options: [],
345
+ multiple: true
344
346
  }, {
345
347
  id: 'tag',
346
348
  component: 'select',
@@ -352,7 +354,8 @@ var defaultFilters = [{
352
354
  "value": "Tag"
353
355
  }]
354
356
  }),
355
- options: []
357
+ options: [],
358
+ multiple: true
356
359
  }, {
357
360
  id: 'search',
358
361
  component: 'search',
@@ -373,6 +376,9 @@ var propTypes$4 = {
373
376
  layouts: PropTypes.arrayOf(PropTypes.shape({})),
374
377
  theme: PropTypes.string,
375
378
  tableProps: PropTypes.bool,
379
+ onItemsChange: PropTypes.func,
380
+ selectedCount: PropTypes.number,
381
+ onClearSelected: PropTypes.func,
376
382
  className: PropTypes.string
377
383
  };
378
384
  var defaultProps$4 = {
@@ -382,7 +388,7 @@ var defaultProps$4 = {
382
388
  // fields: null,
383
389
  query: null,
384
390
  baseUrl: null,
385
- layout: null,
391
+ layout: 'table',
386
392
  layouts: [{
387
393
  id: 'table',
388
394
  label: /*#__PURE__*/React.createElement(Icon, {
@@ -396,6 +402,9 @@ var defaultProps$4 = {
396
402
  }],
397
403
  theme: null,
398
404
  tableProps: null,
405
+ onItemsChange: null,
406
+ selectedCount: null,
407
+ onClearSelected: null,
399
408
  className: null
400
409
  };
401
410
  function MediasBrowser(_ref) {
@@ -408,6 +417,9 @@ function MediasBrowser(_ref) {
408
417
  layouts = _ref.layouts,
409
418
  theme = _ref.theme,
410
419
  tableProps = _ref.tableProps,
420
+ onItemsChange = _ref.onItemsChange,
421
+ selectedCount = _ref.selectedCount,
422
+ onClearSelected = _ref.onClearSelected,
411
423
  className = _ref.className;
412
424
  var baseQuery = React.useMemo(function () {
413
425
  return initialQuery;
@@ -443,6 +455,9 @@ function MediasBrowser(_ref) {
443
455
  loading = _useMedias.loading,
444
456
  lastPage = _useMedias.lastPage,
445
457
  total = _useMedias.total;
458
+ React.useEffect(function () {
459
+ onItemsChange(items);
460
+ }, [items, onItemsChange]);
446
461
  var _useState = React.useState(initialLayout || 'grid'),
447
462
  _useState2 = _slicedToArray(_useState, 2),
448
463
  layout = _useState2[0],
@@ -453,6 +468,20 @@ function MediasBrowser(_ref) {
453
468
  var onClickLayout = React.useCallback(function (lay) {
454
469
  setLayout(lay);
455
470
  }, [setLayout]);
471
+ var pagination = /*#__PURE__*/React.createElement(Pagination, {
472
+ page: page,
473
+ lastPage: lastPage,
474
+ total: total,
475
+ url: baseUrl,
476
+ query: query,
477
+ onClickPage: onPageChange,
478
+ theme: theme,
479
+ loading: loading,
480
+ selectedCount: selectedCount,
481
+ onClearSelected: onClearSelected,
482
+ withPreviousNext: true,
483
+ alwaysShowButtons: true
484
+ });
456
485
  return /*#__PURE__*/React.createElement("div", {
457
486
  className: classNames([styles.container, className])
458
487
  }, /*#__PURE__*/React.createElement(Filters, {
@@ -475,21 +504,11 @@ function MediasBrowser(_ref) {
475
504
  active: layout === lay.id,
476
505
  onClick: function onClick() {
477
506
  return onClickLayout(lay.id);
478
- }
507
+ },
508
+ className: 'px-3'
479
509
  });
480
510
  })
481
- }) : null, /*#__PURE__*/React.createElement(Pagination, {
482
- page: page,
483
- lastPage: lastPage,
484
- total: total,
485
- url: baseUrl,
486
- query: query,
487
- onClickPage: onPageChange,
488
- theme: theme,
489
- loading: loading,
490
- withPreviousNext: true,
491
- alwaysShowButtons: true
492
- })), layout === 'grid' ? /*#__PURE__*/React.createElement(Grid, Object.assign({}, tableProps, {
511
+ }) : null, pagination), layout === 'grid' ? /*#__PURE__*/React.createElement(Grid, Object.assign({}, tableProps, {
493
512
  items: items || [],
494
513
  component: MediaCard,
495
514
  componentProps: {
@@ -504,18 +523,7 @@ function MediasBrowser(_ref) {
504
523
  }, "\u2014")
505
524
  })), /*#__PURE__*/React.createElement("div", {
506
525
  className: classNames(['d-flex', 'mt-3', 'mb-1', 'justify-content-end'])
507
- }, /*#__PURE__*/React.createElement(Pagination, {
508
- page: page,
509
- lastPage: lastPage,
510
- total: total,
511
- url: baseUrl,
512
- query: query,
513
- onClickPage: onPageChange,
514
- theme: theme,
515
- loading: loading,
516
- withPreviousNext: true,
517
- alwaysShowButtons: true
518
- })));
526
+ }, pagination));
519
527
  }
520
528
  MediasBrowser.propTypes = propTypes$4;
521
529
  MediasBrowser.defaultProps = defaultProps$4;
@@ -537,54 +545,99 @@ function MediasBrowserContainer(_ref) {
537
545
  MediasBrowserContainer.propTypes = propTypes$3;
538
546
  MediasBrowserContainer.defaultProps = defaultProps$3;
539
547
 
540
- var _excluded$2 = ["value", "onChange", "onConfirm", "multiple", "className"];
548
+ var _excluded$2 = ["value", "selectedItems", "onChange", "onConfirm", "onClose", "multiple", "withoutButtons", "className"];
541
549
  var propTypes$2 = {
542
550
  // eslint-disable-next-line react/forbid-prop-types
543
- value: PropTypes.any,
551
+ value: PropTypes.arrayOf(PropTypes.shape({})),
552
+ selectedItems: PropTypes.arrayOf(PropTypes.shape({})),
544
553
  onChange: PropTypes.func.isRequired,
545
554
  onConfirm: PropTypes.func.isRequired,
555
+ onClose: PropTypes.func,
546
556
  multiple: PropTypes.bool,
557
+ withoutButtons: PropTypes.bool,
547
558
  className: PropTypes.string
548
559
  };
549
560
  var defaultProps$2 = {
550
561
  value: null,
562
+ selectedItems: null,
563
+ onClose: null,
551
564
  multiple: false,
565
+ withoutButtons: false,
552
566
  className: null
553
567
  };
554
568
  function MediasPicker(_ref) {
555
569
  var value = _ref.value,
570
+ initialSelectedItems = _ref.selectedItems,
556
571
  onChange = _ref.onChange,
557
572
  onConfirm = _ref.onConfirm,
573
+ onClose = _ref.onClose,
558
574
  multiple = _ref.multiple,
575
+ withoutButtons = _ref.withoutButtons,
559
576
  className = _ref.className,
560
577
  props = _objectWithoutProperties(_ref, _excluded$2);
561
- var onSelectionChange = React.useCallback(function (items) {
562
- if (onChange !== null) {
563
- onChange(items);
564
- }
565
- }, [onChange]);
578
+ var _useState = React.useState(value),
579
+ _useState2 = _slicedToArray(_useState, 2),
580
+ items = _useState2[0],
581
+ setItems = _useState2[1];
582
+ var onItemsChange = React.useCallback(function (pageItems) {
583
+ setItems(pageItems);
584
+ }, [setItems]);
566
585
  var disabled = value === null || value.length < 1;
586
+ var _useItemSelection = hooks.useItemSelection({
587
+ items: items,
588
+ selectedItems: initialSelectedItems,
589
+ onSelectionChange: onChange,
590
+ multipleSelection: multiple
591
+ }),
592
+ onSelectItem = _useItemSelection.onSelectItem,
593
+ onSelectPage = _useItemSelection.onSelectPage,
594
+ onClearSelected = _useItemSelection.onClearSelected,
595
+ pageSelected = _useItemSelection.pageSelected,
596
+ selectedCount = _useItemSelection.selectedCount,
597
+ selectedItems = _useItemSelection.selectedItems;
567
598
  return /*#__PURE__*/React.createElement("div", {
568
599
  className: className
569
600
  }, /*#__PURE__*/React.createElement(MediasBrowser, Object.assign({
570
601
  tableProps: {
571
602
  selectable: true,
572
603
  multipleSelection: multiple,
573
- onSelectionChange: onSelectionChange
574
- }
575
- }, props)), multiple ? /*#__PURE__*/React.createElement(Button, {
576
- className: "mt-2",
604
+ onSelectItem: onSelectItem,
605
+ onSelectPage: onSelectPage,
606
+ selectedItems: selectedItems,
607
+ pageSelected: pageSelected
608
+ },
609
+ onItemsChange: onItemsChange,
610
+ selectedCount: selectedCount,
611
+ onClearSelected: onClearSelected
612
+ }, props)), multiple && !withoutButtons ? /*#__PURE__*/React.createElement("div", {
613
+ className: "d-flex w-100 align-items-end justify-content-end mt-3"
614
+ }, /*#__PURE__*/React.createElement("div", {
615
+ className: "btn-group"
616
+ }, onClose !== null ? /*#__PURE__*/React.createElement(Button, {
617
+ type: "button",
618
+ theme: "secondary",
619
+ onClick: onClose,
620
+ className: "d-block me-2"
621
+ }, /*#__PURE__*/React.createElement(reactIntl.FormattedMessage, {
622
+ id: "PyxZY2",
623
+ defaultMessage: [{
624
+ "type": 0,
625
+ "value": "Cancel"
626
+ }]
627
+ })) : null, /*#__PURE__*/React.createElement(Button, {
628
+ type: "button",
629
+ theme: "primary",
577
630
  onClick: onConfirm,
578
- theme: "info",
579
631
  disabled: disabled,
580
- outline: disabled
632
+ outline: disabled,
633
+ className: "d-block"
581
634
  }, /*#__PURE__*/React.createElement(reactIntl.FormattedMessage, {
582
- id: "UaVu03",
635
+ id: "rvOVCV",
583
636
  defaultMessage: [{
584
637
  "type": 0,
585
- "value": "Confirm"
638
+ "value": "Confirm selection"
586
639
  }]
587
- })) : null);
640
+ })))) : null);
588
641
  }
589
642
  MediasPicker.propTypes = propTypes$2;
590
643
  MediasPicker.defaultProps = defaultProps$2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panneau/medias",
3
- "version": "3.0.137",
3
+ "version": "3.0.140",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "javascript"
@@ -46,16 +46,16 @@
46
46
  },
47
47
  "dependencies": {
48
48
  "@babel/runtime": "^7.12.5",
49
- "@panneau/core": "^3.0.136",
50
- "@panneau/data": "^3.0.136",
51
- "@panneau/element-button": "^3.0.136",
52
- "@panneau/element-buttons": "^3.0.136",
53
- "@panneau/element-grid": "^3.0.136",
54
- "@panneau/element-icon": "^3.0.136",
55
- "@panneau/element-media-card": "^3.0.136",
56
- "@panneau/element-pagination": "^3.0.136",
57
- "@panneau/element-table": "^3.0.137",
58
- "@panneau/filter-filters": "^3.0.137",
49
+ "@panneau/core": "^3.0.140",
50
+ "@panneau/data": "^3.0.140",
51
+ "@panneau/element-button": "^3.0.140",
52
+ "@panneau/element-buttons": "^3.0.140",
53
+ "@panneau/element-grid": "^3.0.140",
54
+ "@panneau/element-icon": "^3.0.140",
55
+ "@panneau/element-media-card": "^3.0.140",
56
+ "@panneau/element-pagination": "^3.0.140",
57
+ "@panneau/element-table": "^3.0.140",
58
+ "@panneau/filter-filters": "^3.0.140",
59
59
  "classnames": "^2.5.1",
60
60
  "lodash": "^4.17.21",
61
61
  "prop-types": "^15.7.2",
@@ -64,5 +64,5 @@
64
64
  "publishConfig": {
65
65
  "access": "public"
66
66
  },
67
- "gitHead": "15122b8a8fa0e7b58a45d235171bbedd2e935d30"
67
+ "gitHead": "f148a421cabe2dfa529d2df1eaae42d0f4bb32c5"
68
68
  }