yootd 0.0.53 → 0.0.55

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.
@@ -17,7 +17,7 @@ export var DropdownSelect = function DropdownSelect(_ref) {
17
17
  var _rest$overlayClassNam, _items$find$label, _items$find;
18
18
  var items = _ref.items,
19
19
  _ref$arrow = _ref.arrow,
20
- arrow = _ref$arrow === void 0 ? true : _ref$arrow,
20
+ arrow = _ref$arrow === void 0 ? false : _ref$arrow,
21
21
  defaultValue = _ref.defaultValue,
22
22
  onChange = _ref.onChange,
23
23
  rest = _objectWithoutProperties(_ref, _excluded);
@@ -1,6 +1,6 @@
1
1
  .yot-dropdownselect {
2
2
  .ant-dropdown-menu-item.ant-dropdown-menu-item-active{
3
- background-color: #F0F8FF !important;
3
+ background-color: #F0F8FF !important;
4
4
  }
5
5
  }
6
6
 
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import { ISvgIconProps } from "../../utils/types";
3
+ import './index.scss';
4
+ export declare const GoBackIcon: React.ForwardRefExoticComponent<Omit<ISvgIconProps, "ref"> & React.RefAttributes<HTMLLIElement>>;
@@ -0,0 +1,43 @@
1
+ var _excluded = ["style", "className"];
2
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
4
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
5
+ import React, { forwardRef } from 'react';
6
+ import { useBem } from "../../hooks/useBem";
7
+ import "./index.scss";
8
+ export var GoBackIcon = /*#__PURE__*/forwardRef(function (_ref, ref) {
9
+ var style = _ref.style,
10
+ className = _ref.className,
11
+ rest = _objectWithoutProperties(_ref, _excluded);
12
+ var bem = useBem('goback-icon');
13
+ return /*#__PURE__*/React.createElement("svg", _extends({
14
+ ref: ref,
15
+ width: "16",
16
+ height: "16",
17
+ viewBox: "0 0 16 16",
18
+ fill: "none",
19
+ xmlns: "http://www.w3.org/2000/svg"
20
+ }, rest, {
21
+ style: style,
22
+ className: "".concat(bem, " ").concat(className !== null && className !== void 0 ? className : '')
23
+ }), /*#__PURE__*/React.createElement("g", {
24
+ id: "Group 1660"
25
+ }, /*#__PURE__*/React.createElement("g", {
26
+ id: "Rectangle 18755"
27
+ }, /*#__PURE__*/React.createElement("rect", {
28
+ width: "16",
29
+ height: "16",
30
+ rx: "8"
31
+ }), /*#__PURE__*/React.createElement("rect", {
32
+ width: "16",
33
+ height: "16",
34
+ rx: "8"
35
+ })), /*#__PURE__*/React.createElement("path", {
36
+ id: "Union",
37
+ fillRule: "evenodd",
38
+ clipRule: "evenodd",
39
+ d: "M3.47298 7.70007C3.28505 7.85003 3.28505 8.14997 3.47298 8.29993L6.76169 10.9243C6.99398 11.1097 7.32547 10.9334 7.32547 10.6244V9H11.6654C12.2176 9 12.6654 8.55228 12.6654 8C12.6654 7.44772 12.2177 7 11.6654 7H7.32547V5.3756C7.32547 5.06665 6.99398 4.8903 6.76169 5.07566L3.47298 7.70007Z",
40
+ fill: "white"
41
+ })));
42
+ });
43
+ GoBackIcon.displayName = 'GoBackIcon';
@@ -0,0 +1,5 @@
1
+ .yot-goback-icon {
2
+ rect {
3
+ fill: var(--ant-color-primary);
4
+ }
5
+ }
@@ -0,0 +1,7 @@
1
+ import React, { CSSProperties } from 'react';
2
+ import './index.scss';
3
+ export interface GoBackProps {
4
+ style?: CSSProperties;
5
+ className?: string;
6
+ }
7
+ export declare const GoBack: (props: React.PropsWithChildren<GoBackProps>) => React.JSX.Element;
@@ -0,0 +1,24 @@
1
+ import React from 'react';
2
+ import { useNavigate } from 'react-router-dom';
3
+ import { useBem } from "../hooks/useBem";
4
+ import { GoBackIcon } from "./components/GoBackIcon";
5
+ import "./index.scss";
6
+ export var GoBack = function GoBack(props) {
7
+ var style = props.style,
8
+ className = props.className,
9
+ children = props.children;
10
+ var navigate = useNavigate();
11
+ var bem = useBem('goback');
12
+ var handleClick = function handleClick() {
13
+ navigate(-1);
14
+ };
15
+ return /*#__PURE__*/React.createElement("div", {
16
+ className: "".concat(bem, " ").concat(className !== null && className !== void 0 ? className : ''),
17
+ style: style
18
+ }, /*#__PURE__*/React.createElement("div", {
19
+ className: "".concat(bem.b('content')),
20
+ onClick: handleClick
21
+ }, /*#__PURE__*/React.createElement(GoBackIcon, null), /*#__PURE__*/React.createElement("span", {
22
+ className: "".concat(bem.b('content').e('title'))
23
+ }, "\u8FD4\u56DE")), children);
24
+ };
@@ -0,0 +1,24 @@
1
+ .yot-goback {
2
+ height: 59px;
3
+ background-color: #ffffff;
4
+ border-radius: 8px;
5
+ box-sizing: border-box;
6
+ padding: 0 24px;
7
+ display: flex;
8
+ align-items: center;
9
+
10
+ &-content {
11
+ width: fit-content;
12
+ max-width: 60px;
13
+ height: 100%;
14
+ display: flex;
15
+ align-items: center;
16
+ cursor: pointer;
17
+
18
+ &__title {
19
+ font-size: 18px;
20
+ margin-left: 5px;
21
+ font-weight: bold;
22
+ }
23
+ }
24
+ }
package/dist/index.d.ts CHANGED
@@ -169,6 +169,8 @@ export type { UserDropdownProps } from './user-dropdown/types/types';
169
169
  export { ConfigProvider } from './config-provider';
170
170
  export type { ConfigProviderProps } from './config-provider';
171
171
  export { Zone } from './zones';
172
+ export { GoBack } from './go-back';
173
+ export type { GoBackProps } from './go-back';
172
174
  export { VideoPlayer } from './video-player';
173
- export type { VideoPlayerProps } from './video-player';
175
+ export type { VideoPlayerProps, VideoPlayerRef } from './video-player';
174
176
  export type { GetProp, GetProps, GetRef } from './utils/utils';
package/dist/index.js CHANGED
@@ -91,4 +91,5 @@ export { Teacher } from "./teacher";
91
91
  export { UserDropdown } from "./user-dropdown";
92
92
  export { ConfigProvider } from "./config-provider";
93
93
  export { Zone } from "./zones";
94
+ export { GoBack } from "./go-back";
94
95
  export { VideoPlayer } from "./video-player";
@@ -2,7 +2,7 @@ import type { TreeDataNode as AntTreeDataNode, TreeProps as AntTreeProps } from
2
2
  import { Tree as AntTree } from 'antd';
3
3
  import React from 'react';
4
4
  import './index.scss';
5
- export type { AntTreeNode, AntTreeNodeCheckedEvent, AntTreeNodeExpandedEvent, AntTreeNodeMouseEvent, AntTreeNodeProps, AntTreeNodeSelectedEvent, AntdTreeNodeAttribute, DirectoryTreeExpandAction, DirectoryTreeProps, EventDataNode, } from 'antd/es/tree';
5
+ export type { AntdTreeNodeAttribute, AntTreeNode, AntTreeNodeCheckedEvent, AntTreeNodeExpandedEvent, AntTreeNodeMouseEvent, AntTreeNodeProps, AntTreeNodeSelectedEvent, DirectoryTreeExpandAction, DirectoryTreeProps, EventDataNode } from 'antd/es/tree';
6
6
  export type TreeProps = AntTreeProps & {
7
7
  showChildNumbers?: boolean;
8
8
  placeholder?: string;
@@ -1,5 +1,9 @@
1
- import { CSSProperties, FC } from 'react';
1
+ import React, { CSSProperties } from 'react';
2
2
  import './index.scss';
3
+ export interface VideoPlayerRef {
4
+ play: () => void;
5
+ pause: () => void;
6
+ }
3
7
  export interface VideoPlayerProps {
4
8
  /**
5
9
  * 视频地址
@@ -67,4 +71,4 @@ export interface VideoPlayerProps {
67
71
  */
68
72
  onPlayStateChange?: (isPlaying: boolean) => void;
69
73
  }
70
- export declare const VideoPlayer: FC<VideoPlayerProps>;
74
+ export declare const VideoPlayer: React.ForwardRefExoticComponent<VideoPlayerProps & React.RefAttributes<VideoPlayerRef>>;
@@ -15,7 +15,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
15
15
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
16
16
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
17
17
  import * as faceapi from '@vladmandic/face-api';
18
- import React, { useCallback, useEffect, useRef, useState } from 'react';
18
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';
19
19
  import { EndPoint } from 'yootd-webrtc-sdk';
20
20
  import { useBem } from "../hooks/useBem";
21
21
  import "./index.scss";
@@ -27,7 +27,7 @@ var MIN_SCORE = 0.5; // minimum score
27
27
  var MAX_RESULTS = 20; // maximum number of results to return
28
28
 
29
29
  var speeds = ['2.0', '1.75', '1.5', '1.25', '1.0', '0.75', '0.5'];
30
- export var VideoPlayer = function VideoPlayer(_ref) {
30
+ export var VideoPlayer = /*#__PURE__*/forwardRef(function (_ref, ref) {
31
31
  var src = _ref.src,
32
32
  isLive = _ref.isLive,
33
33
  controls = _ref.controls,
@@ -135,6 +135,18 @@ export var VideoPlayer = function VideoPlayer(_ref) {
135
135
  _useState36 = _slicedToArray(_useState35, 2),
136
136
  videoEleSize = _useState36[0],
137
137
  setVideoEleSize = _useState36[1];
138
+ useImperativeHandle(ref, function () {
139
+ return {
140
+ play: function play() {
141
+ var _videoRef$current;
142
+ void ((_videoRef$current = videoRef.current) === null || _videoRef$current === void 0 ? void 0 : _videoRef$current.play());
143
+ },
144
+ pause: function pause() {
145
+ var _videoRef$current2;
146
+ (_videoRef$current2 = videoRef.current) === null || _videoRef$current2 === void 0 || _videoRef$current2.pause();
147
+ }
148
+ };
149
+ });
138
150
  var handleFullScreen = function handleFullScreen() {
139
151
  if (containerRef.current != null) {
140
152
  void containerRef.current.requestFullscreen();
@@ -148,7 +160,7 @@ export var VideoPlayer = function VideoPlayer(_ref) {
148
160
  var handleCanPlay = function handleCanPlay(e) {
149
161
  var video = e.target;
150
162
  try {
151
- var _video$audioTracks, _video$audioTracks2;
163
+ var _video$audioTracks;
152
164
  setHasAudio(
153
165
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
154
166
  // @ts-ignore
@@ -159,27 +171,29 @@ export var VideoPlayer = function VideoPlayer(_ref) {
159
171
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
160
172
  // @ts-ignore
161
173
  Boolean((_video$audioTracks = video.audioTracks) === null || _video$audioTracks === void 0 ? void 0 : _video$audioTracks.length));
162
- console.log('是否包含音频: ',
163
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
164
- // @ts-expect-error
165
- video.mozHasAudio ||
166
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
167
- // @ts-expect-error
168
- Boolean(video.webkitAudioDecodedByteCount) ||
169
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
170
- // @ts-expect-error
171
- Boolean((_video$audioTracks2 = video.audioTracks) === null || _video$audioTracks2 === void 0 ? void 0 : _video$audioTracks2.length));
174
+ // console.log(
175
+ // '是否包含音频: ',
176
+ // // eslint-disable-next-line @typescript-eslint/ban-ts-comment
177
+ // // @ts-expect-error
178
+ // video.mozHasAudio ||
179
+ // // eslint-disable-next-line @typescript-eslint/ban-ts-comment
180
+ // // @ts-expect-error
181
+ // Boolean(video.webkitAudioDecodedByteCount) ||
182
+ // // eslint-disable-next-line @typescript-eslint/ban-ts-comment
183
+ // // @ts-expect-error
184
+ // Boolean(video.audioTracks?.length),
185
+ // );
172
186
  } catch (e) {
173
187
  console.log(e);
174
188
  }
175
189
  };
176
190
  var handlePlayAndStop = function handlePlayAndStop() {
177
191
  if (isPlaying) {
178
- var _videoRef$current;
179
- (_videoRef$current = videoRef.current) === null || _videoRef$current === void 0 || _videoRef$current.pause();
192
+ var _videoRef$current3;
193
+ (_videoRef$current3 = videoRef.current) === null || _videoRef$current3 === void 0 || _videoRef$current3.pause();
180
194
  } else {
181
- var _videoRef$current2;
182
- void ((_videoRef$current2 = videoRef.current) === null || _videoRef$current2 === void 0 ? void 0 : _videoRef$current2.play());
195
+ var _videoRef$current4;
196
+ void ((_videoRef$current4 = videoRef.current) === null || _videoRef$current4 === void 0 ? void 0 : _videoRef$current4.play());
183
197
  }
184
198
  };
185
199
  var handleOnPlay = function handleOnPlay() {
@@ -533,12 +547,12 @@ export var VideoPlayer = function VideoPlayer(_ref) {
533
547
  if (lastTime + 1000 <= Date.now()) {
534
548
  lastTime = Date.now();
535
549
  detect()
536
- .catch((e) => {
537
- console.log("error", e);
538
- })
539
- .finally(() => {
540
- handler = requestAnimationFrame(start);
541
- });
550
+ .catch((e) => {
551
+ console.log("error", e);
552
+ })
553
+ .finally(() => {
554
+ handler = requestAnimationFrame(start);
555
+ });
542
556
  } else {
543
557
  handler = requestAnimationFrame(start);
544
558
  }
@@ -872,4 +886,5 @@ export var VideoPlayer = function VideoPlayer(_ref) {
872
886
  transform: "scale(".concat(canvasSize.width / videoEleSize.width, ")")
873
887
  }
874
888
  }) : null));
875
- };
889
+ });
890
+ VideoPlayer.displayName = 'VideoPlayer';
@@ -1,4 +1,4 @@
1
- var _excluded = ["type", "style", "showSearch", "value", "onChange", "allowClear", "placeholder"];
1
+ var _excluded = ["type", "style", "showSearch", "value", "onChange", "allowClear", "placeholder", "responseType"];
2
2
  function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
3
3
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
4
4
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -25,6 +25,8 @@ export var YearTerm = function YearTerm(_ref) {
25
25
  _ref$allowClear = _ref.allowClear,
26
26
  allowClear = _ref$allowClear === void 0 ? true : _ref$allowClear,
27
27
  placeholder = _ref.placeholder,
28
+ _ref$responseType = _ref.responseType,
29
+ responseType = _ref$responseType === void 0 ? 'id' : _ref$responseType,
28
30
  rest = _objectWithoutProperties(_ref, _excluded);
29
31
  var mb = useBem('YearTerm');
30
32
  var request = useRequest();
@@ -70,7 +72,7 @@ export var YearTerm = function YearTerm(_ref) {
70
72
  });
71
73
  }, [yearData]);
72
74
 
73
- // 将学期数据处理成下拉框
75
+ // 将学期数据处理成下拉框(responseType为id时)
74
76
  var termOptions = useMemo(function () {
75
77
  var _termData$content;
76
78
  return termData === null || termData === void 0 || (_termData$content = termData.content) === null || _termData$content === void 0 ? void 0 : _termData$content.map(function (item) {
@@ -80,6 +82,17 @@ export var YearTerm = function YearTerm(_ref) {
80
82
  };
81
83
  });
82
84
  }, [termData]);
85
+ // 将学期数据处理成对象形式(key:id,value:startDate,endDate)
86
+ var termOptionsTime = useMemo(function () {
87
+ var _termData$content2;
88
+ return termData === null || termData === void 0 || (_termData$content2 = termData.content) === null || _termData$content2 === void 0 ? void 0 : _termData$content2.reduce(function (acc, item) {
89
+ acc[item.termId] = {
90
+ startDate: item === null || item === void 0 ? void 0 : item.startDate,
91
+ endDate: item === null || item === void 0 ? void 0 : item.endDate
92
+ };
93
+ return acc;
94
+ }, {});
95
+ }, [termData]);
83
96
  // 第一个下拉框的placeholder
84
97
  var firstSelectPlaceholder = useMemo(function () {
85
98
  if (type === 'yearTerm' || type === 'year') {
@@ -121,14 +134,35 @@ export var YearTerm = function YearTerm(_ref) {
121
134
  var changeSecondSelect = function changeSecondSelect(value) {
122
135
  setTermId(value);
123
136
  if (type === 'yearTerm') {
124
- onChange === null || onChange === void 0 || onChange({
125
- yearId: yearId,
126
- termId: value
127
- });
137
+ if (responseType === 'id') {
138
+ onChange === null || onChange === void 0 || onChange({
139
+ yearId: yearId,
140
+ termId: value
141
+ });
142
+ } else if (responseType === 'time') {
143
+ var _termOptionsTime$valu, _termOptionsTime$valu2;
144
+ onChange === null || onChange === void 0 || onChange({
145
+ yearId: yearId,
146
+ termTime: {
147
+ startDate: termOptionsTime === null || termOptionsTime === void 0 || (_termOptionsTime$valu = termOptionsTime[value]) === null || _termOptionsTime$valu === void 0 ? void 0 : _termOptionsTime$valu.startDate,
148
+ endDate: termOptionsTime === null || termOptionsTime === void 0 || (_termOptionsTime$valu2 = termOptionsTime[value]) === null || _termOptionsTime$valu2 === void 0 ? void 0 : _termOptionsTime$valu2.endDate
149
+ }
150
+ });
151
+ }
128
152
  } else if (type === 'term') {
129
- onChange === null || onChange === void 0 || onChange({
130
- termId: value
131
- });
153
+ if (responseType === 'id') {
154
+ onChange === null || onChange === void 0 || onChange({
155
+ termId: value
156
+ });
157
+ } else if (responseType === 'time') {
158
+ var _termOptionsTime$valu3, _termOptionsTime$valu4;
159
+ onChange === null || onChange === void 0 || onChange({
160
+ termTime: {
161
+ startDate: termOptionsTime === null || termOptionsTime === void 0 || (_termOptionsTime$valu3 = termOptionsTime[value]) === null || _termOptionsTime$valu3 === void 0 ? void 0 : _termOptionsTime$valu3.startDate,
162
+ endDate: termOptionsTime === null || termOptionsTime === void 0 || (_termOptionsTime$valu4 = termOptionsTime[value]) === null || _termOptionsTime$valu4 === void 0 ? void 0 : _termOptionsTime$valu4.endDate
163
+ }
164
+ });
165
+ }
132
166
  }
133
167
  };
134
168
  // 填充初始值
@@ -1,28 +1,35 @@
1
- export interface PageData<T> {
2
- content: T[];
3
- page: {
4
- number: number;
5
- size: number;
6
- totalElements: number;
7
- totalPages: number;
8
- };
9
- }
10
- // 查询学年返回的数据类型
11
- export interface IYearItem {
12
- id: number; // ID
13
- yearName: string; // 学年名称
14
- }
15
- // 查询学期返回的数据类型
16
- export interface ITermItem {
17
- termId: number; // ID
18
- termName: string; // 学期名称
19
- }
20
- type YearTermProps = {
21
- type?: 'yearTerm' | 'year' | 'term';
22
- style?: React.CSSProperties;
23
- showSearch?: boolean;
24
- value?: Record<string, number>;
25
- onChange?: (record: Record<string, number | undefined>) => void;
26
- allowClear?: boolean;
27
- placeholder?: string[];
28
- };
1
+ export interface PageData<T> {
2
+ content: T[];
3
+ page: {
4
+ number: number;
5
+ size: number;
6
+ totalElements: number;
7
+ totalPages: number;
8
+ };
9
+ }
10
+ // 查询学年返回的数据类型
11
+ export interface IYearItem {
12
+ id: number; // ID
13
+ yearName: string; // 学年名称
14
+ }
15
+ // 查询学期返回的数据类型
16
+ export interface ITermItem {
17
+ termId: number; // ID
18
+ termName: string; // 学期名称
19
+ startDate: string; // 开始日期
20
+ endDate: string; // 结束日期
21
+ }
22
+ type YearTermProps = {
23
+ type?: 'yearTerm' | 'year' | 'term';
24
+ responseType?: 'id' | 'time';
25
+ style?: React.CSSProperties;
26
+ showSearch?: boolean;
27
+ value?: { yearId?: number; termId?: number };
28
+ onChange?: (record: {
29
+ yearId?: number;
30
+ termId?: number;
31
+ termTime?: { startDate?: string; endDate?: string };
32
+ }) => void;
33
+ allowClear?: boolean;
34
+ placeholder?: string[];
35
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yootd",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "description": "A react library developed with dumi",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",
@@ -92,6 +92,7 @@
92
92
  "nanoid": ">=5.0.8",
93
93
  "react": ">=16.9.0",
94
94
  "react-dom": ">=16.9.0",
95
+ "react-router-dom": ">=6.25.0",
95
96
  "yootd-webrtc-sdk": "^1.0.1"
96
97
  },
97
98
  "publishConfig": {