cnhis-design-vue 3.3.3-beta.22 → 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,12 +534,12 @@ declare const _default: import("vue").DefineComponent<{
534
534
  }>;
535
535
  developMode: boolean;
536
536
  draggable: boolean;
537
- fieldDescribeMode: "column" | "tooltip";
538
- isFieldSet: boolean;
539
- hideExpressionOption: AnyObject[];
540
537
  idx: number;
541
538
  isHighlight: boolean;
542
539
  isHighlightRow: boolean;
540
+ isFieldSet: boolean;
541
+ fieldDescribeMode: "column" | "tooltip";
542
+ hideExpressionOption: AnyObject[];
543
543
  }>;
544
544
  EditDialog: import("vue").DefineComponent<{
545
545
  visible: {
@@ -563,12 +563,12 @@ declare const _default: import("vue").DefineComponent<{
563
563
  }>;
564
564
  developMode: boolean;
565
565
  draggable: boolean;
566
- fieldDescribeMode: "column" | "tooltip";
567
- isFieldSet: boolean;
568
- hideExpressionOption: AnyObject[];
569
566
  idx: number;
570
567
  isHighlight: boolean;
571
568
  isHighlightRow: boolean;
569
+ isFieldSet: boolean;
570
+ fieldDescribeMode: "column" | "tooltip";
571
+ hideExpressionOption: AnyObject[];
572
572
  }>;
573
573
  setStyle: typeof setStyle;
574
574
  }, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("close" | "save" | "reset")[], "close" | "save" | "reset", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
@@ -754,12 +754,12 @@ declare const _default: import("vue").DefineComponent<{
754
754
  }>;
755
755
  developMode: boolean;
756
756
  draggable: boolean;
757
- fieldDescribeMode: "column" | "tooltip";
758
- isFieldSet: boolean;
759
- hideExpressionOption: AnyObject[];
760
757
  idx: number;
761
758
  isHighlight: boolean;
762
759
  isHighlightRow: boolean;
760
+ isFieldSet: boolean;
761
+ fieldDescribeMode: "column" | "tooltip";
762
+ hideExpressionOption: AnyObject[];
763
763
  }>;
764
764
  isArray: {
765
765
  (value?: any): value is any[];
@@ -898,9 +898,9 @@ declare const _default: import("vue").DefineComponent<{
898
898
  showSeq: boolean;
899
899
  developMode: boolean;
900
900
  footerFlag: boolean;
901
+ fieldDescribeMode: "column" | "tooltip";
901
902
  customColumns: FieldSetColumnItem[];
902
903
  showSortPriority: boolean;
903
904
  showHeadFilter: boolean;
904
- fieldDescribeMode: "column" | "tooltip";
905
905
  }>;
906
906
  export default _default;
@@ -383,11 +383,11 @@ declare const _default: import("vue").DefineComponent<{
383
383
  }>;
384
384
  developMode: boolean;
385
385
  draggable: boolean;
386
- fieldDescribeMode: "column" | "tooltip";
387
- isFieldSet: boolean;
388
- hideExpressionOption: AnyObject[];
389
386
  idx: number;
390
387
  isHighlight: boolean;
391
388
  isHighlightRow: boolean;
389
+ isFieldSet: boolean;
390
+ fieldDescribeMode: "column" | "tooltip";
391
+ hideExpressionOption: AnyObject[];
392
392
  }>;
393
393
  export default _default;
@@ -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: "",
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.22";
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.22",
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": "bcb99abde9f0704e4e535eee1bbc4ccce1e46953"
76
+ "gitHead": "8e2c9c3977ae65cf55bdeacd06f6be538f72b521"
77
77
  }