cnhis-design-vue 3.3.3-beta.21 → 3.3.3-beta.23

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/README.md CHANGED
@@ -1,87 +1,87 @@
1
- # 安装
2
-
3
- ```shell
4
- npm i cnhis-design-vue@[版本号]
5
- # or
6
- yarn add cnhis-design-vue@[版本号] #推荐
7
- ```
8
-
9
- ## 1.全局引入
10
-
11
- ```typescript
12
- // main.ts
13
- import { createApp } from 'vue';
14
- import App from './App.vue';
15
- import 'cnhis-design-vue/es/packages/index.css';
16
- import cui from 'cnhis-design-vue';
17
-
18
- const app = createApp(App);
19
- app.use(cui).mount('#app');
20
- ```
21
-
22
- ## 2. 按需引入
23
-
24
- 组件现在支持了自动按需引入, 但是样式文件需要额外的处理
25
-
26
- ### 2.1 样式处理方式1 (按需引入样式)
27
-
28
- ```shell
29
- # 安装自动导入样式的插件
30
- npm i -d vite-plugin-style-import
31
- ```
32
-
33
- ```typescript
34
- // vite.config.ts
35
- import { defineConfig } from 'vite';
36
- import { createStyleImportPlugin } from 'vite-plugin-style-import';
37
-
38
- export default defineConfig({
39
- plugins: [
40
- // ...otherPlugins
41
- createStyleImportPlugin({
42
- libs: [
43
- {
44
- libraryName: 'cnhis-design-vue',
45
- esModule: true,
46
- ensureStyleFile: true,
47
- resolveStyle: name => {
48
- return `cnhis-design-vue/es/components/${ name.slice(2) }/style/index.css`;
49
- }
50
- }
51
- ]
52
- })
53
- ]
54
- });
55
- ```
56
-
57
- ### 2.2 样式处理方式2 (全局引入样式)
58
-
59
- ```typescript
60
- // main.ts
61
- import 'cnhis-design-vue/es/components/index.css';
62
- ```
63
-
64
- ## 3.FAQ
65
-
66
- ### 3.1 项目打包后样式丢失
67
-
68
- 处理方法, 将 cnhis-design-vue 从 vendor 包中移除 (没有出现此问题则不需要)
69
-
70
- ```typescript
71
- // vite.config.ts
72
- import { defineConfig } from 'vite';
73
-
74
- export default defineConfig({
75
- build: {
76
- rollupOptions: {
77
- // ..otherOptions
78
- output: {
79
- dir: './dist',
80
- manualChunks: {
81
- 'cnhis-vendor': ['cnhis-design-vue']
82
- }
83
- }
84
- }
85
- }
86
- });
87
- ```
1
+ # 安装
2
+
3
+ ```shell
4
+ npm i cnhis-design-vue@[版本号]
5
+ # or
6
+ yarn add cnhis-design-vue@[版本号] #推荐
7
+ ```
8
+
9
+ ## 1.全局引入
10
+
11
+ ```typescript
12
+ // main.ts
13
+ import { createApp } from 'vue';
14
+ import App from './App.vue';
15
+ import 'cnhis-design-vue/es/packages/index.css';
16
+ import cui from 'cnhis-design-vue';
17
+
18
+ const app = createApp(App);
19
+ app.use(cui).mount('#app');
20
+ ```
21
+
22
+ ## 2. 按需引入
23
+
24
+ 组件现在支持了自动按需引入, 但是样式文件需要额外的处理
25
+
26
+ ### 2.1 样式处理方式1 (按需引入样式)
27
+
28
+ ```shell
29
+ # 安装自动导入样式的插件
30
+ npm i -d vite-plugin-style-import
31
+ ```
32
+
33
+ ```typescript
34
+ // vite.config.ts
35
+ import { defineConfig } from 'vite';
36
+ import { createStyleImportPlugin } from 'vite-plugin-style-import';
37
+
38
+ export default defineConfig({
39
+ plugins: [
40
+ // ...otherPlugins
41
+ createStyleImportPlugin({
42
+ libs: [
43
+ {
44
+ libraryName: 'cnhis-design-vue',
45
+ esModule: true,
46
+ ensureStyleFile: true,
47
+ resolveStyle: name => {
48
+ return `cnhis-design-vue/es/components/${ name.slice(2) }/style/index.css`;
49
+ }
50
+ }
51
+ ]
52
+ })
53
+ ]
54
+ });
55
+ ```
56
+
57
+ ### 2.2 样式处理方式2 (全局引入样式)
58
+
59
+ ```typescript
60
+ // main.ts
61
+ import 'cnhis-design-vue/es/components/index.css';
62
+ ```
63
+
64
+ ## 3.FAQ
65
+
66
+ ### 3.1 项目打包后样式丢失
67
+
68
+ 处理方法, 将 cnhis-design-vue 从 vendor 包中移除 (没有出现此问题则不需要)
69
+
70
+ ```typescript
71
+ // vite.config.ts
72
+ import { defineConfig } from 'vite';
73
+
74
+ export default defineConfig({
75
+ build: {
76
+ rollupOptions: {
77
+ // ..otherOptions
78
+ output: {
79
+ dir: './dist',
80
+ manualChunks: {
81
+ 'cnhis-vendor': ['cnhis-design-vue']
82
+ }
83
+ }
84
+ }
85
+ }
86
+ });
87
+ ```
@@ -175,6 +175,9 @@ declare const _default: import("vue").DefineComponent<{
175
175
  modelValue: unknown[];
176
176
  componentData: Record<string, any>;
177
177
  } & {
178
+ /**
179
+ * 改变弹窗大小
180
+ */
178
181
  itemKey?: string | Function | undefined;
179
182
  }>, {
180
183
  move: Function;
@@ -534,9 +534,9 @@ declare const _default: import("vue").DefineComponent<{
534
534
  }>;
535
535
  developMode: boolean;
536
536
  draggable: boolean;
537
- isHighlightRow: boolean;
538
537
  idx: number;
539
538
  isHighlight: boolean;
539
+ isHighlightRow: boolean;
540
540
  isFieldSet: boolean;
541
541
  fieldDescribeMode: "column" | "tooltip";
542
542
  hideExpressionOption: AnyObject[];
@@ -563,9 +563,9 @@ declare const _default: import("vue").DefineComponent<{
563
563
  }>;
564
564
  developMode: boolean;
565
565
  draggable: boolean;
566
- isHighlightRow: boolean;
567
566
  idx: number;
568
567
  isHighlight: boolean;
568
+ isHighlightRow: boolean;
569
569
  isFieldSet: boolean;
570
570
  fieldDescribeMode: "column" | "tooltip";
571
571
  hideExpressionOption: AnyObject[];
@@ -754,9 +754,9 @@ declare const _default: import("vue").DefineComponent<{
754
754
  }>;
755
755
  developMode: boolean;
756
756
  draggable: boolean;
757
- isHighlightRow: boolean;
758
757
  idx: number;
759
758
  isHighlight: boolean;
759
+ isHighlightRow: boolean;
760
760
  isFieldSet: boolean;
761
761
  fieldDescribeMode: "column" | "tooltip";
762
762
  hideExpressionOption: AnyObject[];
@@ -383,9 +383,9 @@ declare const _default: import("vue").DefineComponent<{
383
383
  }>;
384
384
  developMode: boolean;
385
385
  draggable: boolean;
386
- isHighlightRow: boolean;
387
386
  idx: number;
388
387
  isHighlight: boolean;
388
+ isHighlightRow: boolean;
389
389
  isFieldSet: boolean;
390
390
  fieldDescribeMode: "column" | "tooltip";
391
391
  hideExpressionOption: AnyObject[];
@@ -2281,6 +2281,7 @@ declare const IhoChat: SFCWithInstall<import("vue").DefineComponent<{
2281
2281
  HappyOutline: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2282
2282
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2283
2283
  ChatFooter: import("vue").DefineComponent<{}, {
2284
+ SPACE_PLACEHOLDER: string;
2284
2285
  inputRef: import("vue").Ref<HTMLDivElement | undefined>;
2285
2286
  state: {
2286
2287
  orgId: string | number;
@@ -2338,9 +2339,11 @@ declare const IhoChat: SFCWithInstall<import("vue").DefineComponent<{
2338
2339
  isWrap: (event: KeyboardEvent) => boolean;
2339
2340
  handleInput: () => void;
2340
2341
  selectEmoji: (name: string) => void;
2342
+ insertSpace: () => void;
2341
2343
  doUpdateFile: (file: File) => Promise<string>;
2342
2344
  fileChange: (options: import("./src/types").FileOptions, chatMessageType: import("./src/constants").MESSAGE_TYPE) => Promise<void>;
2343
2345
  handleMsgSend: () => Promise<void>;
2346
+ removeSpace: () => void;
2344
2347
  doSendMessage: (contentInfo: import("../../shared/types").AnyObject) => Promise<void>;
2345
2348
  clearInput: () => void;
2346
2349
  handleRelay: ({ checkedIds, remark }: {
@@ -2282,6 +2282,7 @@ declare const _default: import("vue").DefineComponent<{
2282
2282
  HappyOutline: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, import("vue").EmitsOptions, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2283
2283
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{}>>, {}>;
2284
2284
  ChatFooter: import("vue").DefineComponent<{}, {
2285
+ SPACE_PLACEHOLDER: string;
2285
2286
  inputRef: import("vue").Ref<HTMLDivElement | undefined>;
2286
2287
  state: {
2287
2288
  orgId: string | number;
@@ -2339,9 +2340,11 @@ declare const _default: import("vue").DefineComponent<{
2339
2340
  isWrap: (event: KeyboardEvent) => boolean;
2340
2341
  handleInput: () => void;
2341
2342
  selectEmoji: (name: string) => void;
2343
+ insertSpace: () => void;
2342
2344
  doUpdateFile: (file: File) => Promise<string>;
2343
2345
  fileChange: (options: import("./types").FileOptions, chatMessageType: import("./constants").MESSAGE_TYPE) => Promise<void>;
2344
2346
  handleMsgSend: () => Promise<void>;
2347
+ removeSpace: () => void;
2345
2348
  doSendMessage: (contentInfo: AnyObject) => Promise<void>;
2346
2349
  clearInput: () => void;
2347
2350
  handleRelay: ({ checkedIds, remark }: {
@@ -4,6 +4,7 @@ import { MESSAGE_TYPE } from '../constants';
4
4
  import { simplifyMessage } from '../utils';
5
5
  import { FileOptions } from '../types';
6
6
  declare const _default: import("vue").DefineComponent<{}, {
7
+ SPACE_PLACEHOLDER: string;
7
8
  inputRef: Ref<HTMLDivElement | undefined>;
8
9
  state: {
9
10
  orgId: string | number;
@@ -61,9 +62,11 @@ declare const _default: import("vue").DefineComponent<{}, {
61
62
  isWrap: (event: KeyboardEvent) => boolean;
62
63
  handleInput: () => void;
63
64
  selectEmoji: (name: string) => void;
65
+ insertSpace: () => void;
64
66
  doUpdateFile: (file: File) => Promise<string>;
65
67
  fileChange: (options: FileOptions, chatMessageType: MESSAGE_TYPE) => Promise<void>;
66
68
  handleMsgSend: () => Promise<void>;
69
+ removeSpace: () => void;
67
70
  doSendMessage: (contentInfo: AnyObject) => Promise<void>;
68
71
  clearInput: () => void;
69
72
  handleRelay: ({ checkedIds, remark }: {
@@ -1,4 +1,4 @@
1
- import { createElementVNode, defineComponent, ref, computed, watch, withDirectives, openBlock, createElementBlock, normalizeStyle, unref, createVNode, withCtx, Fragment, toDisplayString, createCommentVNode, renderList, createBlock, createTextVNode, mergeProps, renderSlot, vShow } from 'vue';
1
+ import { createElementVNode, defineComponent, ref, computed, onMounted, watch, withDirectives, openBlock, createElementBlock, normalizeStyle, unref, createVNode, withCtx, Fragment, toDisplayString, createCommentVNode, renderList, createBlock, createTextVNode, mergeProps, renderSlot, vShow } from 'vue';
2
2
  import { NButton, NIcon, NTooltip, NPopover, NUpload, NUploadTrigger } from 'naive-ui';
3
3
  import ChatAdd from './ChatAdd.vue.js';
4
4
  import { useData } from '../hooks/useData.js';
@@ -92,6 +92,7 @@ const _hoisted_24 = /* @__PURE__ */ createElementVNode("span", {
92
92
  var _sfc_main = /* @__PURE__ */ defineComponent({
93
93
  __name: "ChatFooter",
94
94
  setup(__props) {
95
+ const SPACE_PLACEHOLDER = '<span style="display: inline-block;width: 1px;user-select: none;" data-space="true"></span>';
95
96
  const inputRef = ref();
96
97
  const {
97
98
  state,
@@ -109,7 +110,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
109
110
  defaultValue: [state.userInfo]
110
111
  };
111
112
  });
112
- const sendBtnDisabled = computed(() => !content.value.replace(/(&nbsp;|\s|<br>)+/g, ""));
113
+ const sendBtnDisabled = computed(() => !content.value.replace(/(&nbsp;|\s|<br>|<span[^>]*data-space="true"[^>]*>[\s\S]*?<\/span>)+/g, ""));
113
114
  const isForwardDisabled = computed(() => !state.msgList.some((msgItem) => msgItem.checked));
114
115
  const callBtnDisabled = computed(() => state.showVideo || state.showMultipleVideo);
115
116
  function handleCall(chatMessageType, checkedIds = []) {
@@ -154,15 +155,29 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
154
155
  }
155
156
  function handleInput() {
156
157
  var _a;
158
+ if (!inputRef.value)
159
+ return;
157
160
  content.value = ((_a = inputRef.value) == null ? void 0 : _a.innerHTML) || "";
161
+ insertSpace();
158
162
  }
159
163
  function selectEmoji(name) {
160
164
  var _a;
161
165
  commonEmoticons.value.unshift(name);
162
166
  commonEmoticons.value = uniq(commonEmoticons.value).slice(0, 26);
167
+ if (!inputRef.value)
168
+ return;
163
169
  (_a = inputRef.value) == null ? void 0 : _a.focus();
170
+ insertSpace();
164
171
  document.execCommand("insertHTML", false, `<img data-msg=${name} data-type=${MESSAGE_TYPE.EMOJI} class="emoji--min" src=${emojis.findEmoji(name)} />`);
165
172
  }
173
+ function insertSpace() {
174
+ if (!inputRef.value)
175
+ return;
176
+ if (!inputRef.value.innerHTML || inputRef.value.innerHTML === "<br>") {
177
+ Array.from(inputRef.value.childNodes).forEach((child) => child.remove());
178
+ document.execCommand("insertHTML", false, SPACE_PLACEHOLDER);
179
+ }
180
+ }
166
181
  async function doUpdateFile(file) {
167
182
  const formData = new FormData();
168
183
  formData.append("sender", state.userInfo.id);
@@ -191,13 +206,14 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
191
206
  });
192
207
  }
193
208
  async function handleMsgSend() {
209
+ if (sendBtnDisabled.value)
210
+ return console.log("\u8BF7\u8F93\u5165\u5185\u5BB9");
211
+ removeSpace();
194
212
  const {
195
213
  innerHTML = "",
196
214
  innerText = "",
197
215
  outerText = ""
198
216
  } = inputRef.value || {};
199
- if (sendBtnDisabled.value)
200
- return console.log("\u8BF7\u8F93\u5165\u5185\u5BB9");
201
217
  let chatMessageType = MESSAGE_TYPE.TEXT;
202
218
  let msg = "";
203
219
  if (innerHTML) {
@@ -259,6 +275,12 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
259
275
  origin: "btn"
260
276
  });
261
277
  }
278
+ function removeSpace() {
279
+ if (!inputRef.value)
280
+ return;
281
+ const spaceHolders = inputRef.value.querySelectorAll('[data-space="true"]');
282
+ spaceHolders.forEach((space) => space.remove());
283
+ }
262
284
  async function doSendMessage(contentInfo) {
263
285
  const {
264
286
  chatMessageType = MESSAGE_TYPE.TEXT,
@@ -288,7 +310,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
288
310
  }
289
311
  function clearInput() {
290
312
  if (inputRef.value) {
291
- inputRef.value.innerHTML = "";
313
+ inputRef.value.innerHTML = SPACE_PLACEHOLDER;
292
314
  }
293
315
  content.value = "";
294
316
  }
@@ -323,6 +345,11 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
323
345
  });
324
346
  state.isForward = false;
325
347
  }
348
+ onMounted(() => {
349
+ if (inputRef.value) {
350
+ inputRef.value.innerHTML = SPACE_PLACEHOLDER;
351
+ }
352
+ });
326
353
  watch(() => [state.currentReferenceMsg, state.currentReEditMsg], ([currentReferenceMsg, currentReEditMsg]) => {
327
354
  var _a;
328
355
  if (currentReferenceMsg || currentReEditMsg) {
@@ -225,7 +225,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
225
225
  round: "",
226
226
  size: 100,
227
227
  onClickCapture: _cache[0] || (_cache[0] = ($event) => showLargeAvatar.value = true)
228
- }, null, 8, ["src"]), createCommentVNode(' <n-upload abstract accept="image/*" @change="onChange">\n <n-upload-trigger #="{ handleClick }" abstract>\n <n-button\n circle\n secondary\n class="edit-avatar"\n v-show="userDetail.id === state.userInfo.id"\n @click="handleClick"\n >\n <template #icon>\n <n-icon size="16" color="#666666" :component="Camera" />\n </template>\n </n-button>\n </n-upload-trigger>\n </n-upload> '), createElementVNode("div", _hoisted_4, [createElementVNode("h4", null, [createElementVNode("label", _hoisted_5, toDisplayString(userDetail.name), 1), withDirectives(createElementVNode("label", {
228
+ }, null, 8, ["src"]), createCommentVNode(' <n-upload abstract accept="image/*" @change="onChange">\r\n <n-upload-trigger #="{ handleClick }" abstract>\r\n <n-button\r\n circle\r\n secondary\r\n class="edit-avatar"\r\n v-show="userDetail.id === state.userInfo.id"\r\n @click="handleClick"\r\n >\r\n <template #icon>\r\n <n-icon size="16" color="#666666" :component="Camera" />\r\n </template>\r\n </n-button>\r\n </n-upload-trigger>\r\n </n-upload> '), createElementVNode("div", _hoisted_4, [createElementVNode("h4", null, [createElementVNode("label", _hoisted_5, toDisplayString(userDetail.name), 1), withDirectives(createElementVNode("label", {
229
229
  class: normalizeClass(["iho-chatRole", unref(isDoctorRole)(userDetail.roleInfo) ? "isDoctor" : ""])
230
230
  }, toDisplayString(unref(getRoleName)(userDetail.roleInfo)), 3), [[vShow, unref(getRoleName)(userDetail.roleInfo)]])]), createElementVNode("p", null, toDisplayString(userDetail.orgName), 1)]), createVNode(unref(NButton), {
231
231
  strong: "",
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, inject, ref, shallowRef, computed, watch, openBlock, createBlock, unref, withCtx, createVNode, createElementVNode, normalizeStyle, createCommentVNode, renderSlot, withKeys, createTextVNode, toDisplayString, withDirectives, vShow, createElementBlock, mergeProps, Fragment, renderList, normalizeProps, guardReactiveProps } from 'vue';
2
2
  import { useMessage, NGrid, NGi, NInputGroup, NInput, NButton, NCheckbox, NTree, NSpace, NPopover } from 'naive-ui';
3
- import { getAllChildren, searchBasisTree } from './utils/index.js';
3
+ import { getAllChildren, searchBasisTree, getExpandedKeys } from './utils/index.js';
4
4
  import { union, remove } from 'lodash-es';
5
5
  import SearchGroupList from './components/SearchGroupList.vue.js';
6
6
  import TagItem from './components/TagItem.vue.js';
@@ -379,6 +379,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
379
379
  const filterKey2 = (_d = (_c = props == null ? void 0 : props.wordbook) == null ? void 0 : _c.filter_key) != null ? _d : "keyword";
380
380
  const data = searchBasisTree(treeData.value, kw, filterKey2);
381
381
  searchTreeData.value = data;
382
+ expandedKeys.value = searchTreeData.value.length ? getExpandedKeys(searchTreeData.value) : [];
382
383
  return;
383
384
  }
384
385
  const flatResult = flatFilter(treeData.value);
package/es/env.d.ts CHANGED
@@ -1,25 +1,25 @@
1
- /// <reference types="vite/client" />
2
-
3
- interface ImportMetaEnv {
4
- readonly VITE_APP_TYPE: string;
5
- // 更多环境变量...
6
- }
7
-
8
- interface ImportMeta {
9
- readonly env: ImportMetaEnv;
10
- }
11
-
12
- declare module '*.vue' {
13
- // @ts-ignore
14
- import type { App, defineComponent } from 'vue';
15
- // // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
16
- // // const component: DefineComponent<{}, {}, any>
17
- const component: ReturnType<typeof defineComponent> & {
18
- install(app: App): void;
19
- };
20
- // @ts-ignore
21
- export default component;
22
- }
23
-
24
- declare module '*.js';
25
-
1
+ /// <reference types="vite/client" />
2
+
3
+ interface ImportMetaEnv {
4
+ readonly VITE_APP_TYPE: string;
5
+ // 更多环境变量...
6
+ }
7
+
8
+ interface ImportMeta {
9
+ readonly env: ImportMetaEnv;
10
+ }
11
+
12
+ declare module '*.vue' {
13
+ // @ts-ignore
14
+ import type { App, defineComponent } from 'vue';
15
+ // // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
16
+ // // const component: DefineComponent<{}, {}, any>
17
+ const component: ReturnType<typeof defineComponent> & {
18
+ install(app: App): void;
19
+ };
20
+ // @ts-ignore
21
+ export default component;
22
+ }
23
+
24
+ declare module '*.js';
25
+
@@ -1,5 +1,5 @@
1
1
  var name = "@cnhis-design-vue/shared";
2
- var version = "3.3.3-beta.21";
2
+ var version = "3.3.3-beta.23";
3
3
  var main = "index.ts";
4
4
  var peerDependencies = {
5
5
  "naive-ui": "^2.30.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cnhis-design-vue",
3
- "version": "3.3.3-beta.21",
3
+ "version": "3.3.3-beta.23",
4
4
  "license": "ISC",
5
5
  "module": "./es/components/index.js",
6
6
  "main": "./es/components/index.js",
@@ -73,5 +73,5 @@
73
73
  "iOS 7",
74
74
  "last 3 iOS versions"
75
75
  ],
76
- "gitHead": "62947fabfe219622c1eb353888cee515f64595c5"
76
+ "gitHead": "8e2c9c3977ae65cf55bdeacd06f6be538f72b521"
77
77
  }