@ray-js/lock-sdk 1.2.0-beta.6 → 1.2.0-beta.8

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,28 @@
1
+ export interface VasNotifyPushConfig {
2
+ appNotify?: boolean;
3
+ iosVoip?: boolean;
4
+ cloudPhone?: boolean;
5
+ }
6
+ export interface VasNotifyScene {
7
+ enable: boolean;
8
+ pushConfig?: VasNotifyPushConfig;
9
+ }
10
+ export interface VasNotifyConfig {
11
+ alert?: boolean | VasNotifyScene;
12
+ doorBell?: VasNotifyScene;
13
+ lockDoor?: VasNotifyScene;
14
+ unlockDoor?: VasNotifyScene & {
15
+ contacts?: Array<Record<string, any>>;
16
+ };
17
+ cloudPhone?: boolean;
18
+ iosVoip?: boolean;
19
+ appNotify?: boolean;
20
+ [k: string]: any;
21
+ }
22
+ export interface UpdateVasNotifyConfigParams {
23
+ key: string;
24
+ enable: boolean;
25
+ userId?: string;
26
+ }
27
+ export declare const getVasNotifyConfigApi: (devId: string) => Promise<VasNotifyConfig>;
28
+ export declare const updateVasNotifyConfigApi: (devId: string, params: UpdateVasNotifyConfigParams) => Promise<VasNotifyConfig>;
@@ -0,0 +1,17 @@
1
+ import { requestApi } from "./request";
2
+ export const getVasNotifyConfigApi = (devId) => {
3
+ return requestApi({
4
+ logName: "getVasNotifyConfig",
5
+ api: "m.lock.vas.notify.config.get",
6
+ version: "1.0",
7
+ data: { devId },
8
+ });
9
+ };
10
+ export const updateVasNotifyConfigApi = (devId, params) => {
11
+ return requestApi({
12
+ logName: "updateVasNotifyConfig",
13
+ api: "m.lock.vas.notify.config.update",
14
+ version: "1.0",
15
+ data: { devId, ...params },
16
+ });
17
+ };
@@ -28,4 +28,9 @@ export declare const getIPCConfig: (devId: string) => Promise<{
28
28
  hardwareCapability: number[];
29
29
  };
30
30
  }>;
31
+ export interface MediaViewTimesResult {
32
+ count: number;
33
+ }
34
+ export declare const getMediaViewTimes: (devId: string) => Promise<MediaViewTimesResult>;
35
+ export declare const setMediaViewTimes: (devId: string) => Promise<MediaViewTimesResult>;
31
36
  export {};
package/lib/api/video.js CHANGED
@@ -30,3 +30,23 @@ export const getIPCConfig = (devId) => {
30
30
  },
31
31
  });
32
32
  };
33
+ export const getMediaViewTimes = (devId) => {
34
+ return requestApi({
35
+ logName: "getMediaViewTimes",
36
+ api: `${THING}.m.device.lock.media.view.times.get`,
37
+ version: "1.0",
38
+ data: {
39
+ devId,
40
+ },
41
+ });
42
+ };
43
+ export const setMediaViewTimes = (devId) => {
44
+ return requestApi({
45
+ logName: "setMediaViewTimes",
46
+ api: `${THING}.m.device.lock.media.view.times.set`,
47
+ version: "1.0",
48
+ data: {
49
+ devId,
50
+ },
51
+ });
52
+ };
@@ -0,0 +1,10 @@
1
+ export interface VoipAuth {
2
+ isAuth: boolean;
3
+ isValid: boolean;
4
+ userId: string;
5
+ userName: string;
6
+ avatarUrl: string;
7
+ [k: string]: any;
8
+ }
9
+ export declare const getVoipAuthApi: (devId: string) => Promise<VoipAuth>;
10
+ export declare const saveVoipAuthApi: (devId: string, userId: string) => Promise<boolean>;
@@ -0,0 +1,17 @@
1
+ import { requestApi } from "./request";
2
+ export const getVoipAuthApi = (devId) => {
3
+ return requestApi({
4
+ logName: "getVoipAuth",
5
+ api: "m.lock.device.voip.auth.get",
6
+ version: "1.0",
7
+ data: { devId },
8
+ });
9
+ };
10
+ export const saveVoipAuthApi = (devId, userId) => {
11
+ return requestApi({
12
+ logName: "saveVoipAuth",
13
+ api: "m.lock.device.voip.auth.save",
14
+ version: "1.0",
15
+ data: { devId, userId },
16
+ });
17
+ };
@@ -12,6 +12,8 @@ export * from "./signal";
12
12
  export * from "./sleep";
13
13
  export * from "./misc";
14
14
  export * from "./service";
15
+ export * from "./notify";
16
+ export * from "./voip";
15
17
  export * from "./media";
16
18
  export * from "./voice-file";
17
19
  export * from "./linkage";
@@ -12,6 +12,8 @@ export * from "./signal";
12
12
  export * from "./sleep";
13
13
  export * from "./misc";
14
14
  export * from "./service";
15
+ export * from "./notify";
16
+ export * from "./voip";
15
17
  export * from "./media";
16
18
  export * from "./voice-file";
17
19
  export * from "./linkage";
@@ -9,3 +9,5 @@ export declare function isSupportMultiCamera(): boolean;
9
9
  export declare function getCameraInfo(): import("../../../feature/media/camera").CameraInfo | undefined;
10
10
  export declare function queryCameraInfo(): Promise<import("../../../feature/media/camera").CameraInfo | undefined>;
11
11
  export declare function switchCamera(index: number): Promise<true>;
12
+ export declare function getMediaViewTimes(): Promise<import("../../../api/video").MediaViewTimesResult>;
13
+ export declare function addMediaViewTimes(): Promise<import("../../../api/video").MediaViewTimesResult>;
@@ -1,5 +1,5 @@
1
1
  import { resolveRuntimeFromExportThis } from "../bootstrap/resolve-runtime-from-export-this";
2
- import { getMediaUrlForRuntime, isSupportMediaForRuntime, openLocalAlbumForRuntime, gotoPlaybackForRuntime, getMediaInfoForRuntime, } from "../../../feature/media/media";
2
+ import { getMediaUrlForRuntime, isSupportMediaForRuntime, openLocalAlbumForRuntime, gotoPlaybackForRuntime, getMediaInfoForRuntime, getMediaViewTimesForRuntime, setMediaViewTimesForRuntime, } from "../../../feature/media/media";
3
3
  import { getMediaRotateForRuntime } from "../../../feature/media/rotate";
4
4
  import { isSupportMultiCameraForRuntime, getCameraInfoForRuntime, queryCameraInfoForRuntime, switchCameraForRuntime, } from "../../../feature/media/camera";
5
5
  export async function getMediaUrl(params) {
@@ -32,3 +32,9 @@ export async function queryCameraInfo() {
32
32
  export async function switchCamera(index) {
33
33
  return switchCameraForRuntime(resolveRuntimeFromExportThis(this), index);
34
34
  }
35
+ export async function getMediaViewTimes() {
36
+ return getMediaViewTimesForRuntime(resolveRuntimeFromExportThis(this));
37
+ }
38
+ export async function addMediaViewTimes() {
39
+ return setMediaViewTimesForRuntime(resolveRuntimeFromExportThis(this));
40
+ }
@@ -0,0 +1,7 @@
1
+ export type { VasNotifyConfig, VasNotifyScene, VasNotifyPushConfig, UpdateVasNotifyConfigParams, } from "../../../api/notify";
2
+ export declare function getVasNotifyConfig(): Promise<import("../../../api/notify").VasNotifyConfig>;
3
+ export declare function updateVasNotifyConfig(params: {
4
+ key: string;
5
+ enable: boolean;
6
+ userId?: string;
7
+ }): Promise<import("../../../api/notify").VasNotifyConfig>;
@@ -0,0 +1,8 @@
1
+ import { resolveRuntimeFromExportThis } from "../bootstrap/resolve-runtime-from-export-this";
2
+ import { getVasNotifyConfigForRuntime, updateVasNotifyConfigForRuntime, } from "../../../feature/notify/notify";
3
+ export async function getVasNotifyConfig() {
4
+ return getVasNotifyConfigForRuntime(resolveRuntimeFromExportThis(this));
5
+ }
6
+ export async function updateVasNotifyConfig(params) {
7
+ return updateVasNotifyConfigForRuntime(resolveRuntimeFromExportThis(this), params);
8
+ }
@@ -0,0 +1,3 @@
1
+ export type { VoipAuth } from "../../../api/voip";
2
+ export declare function getVoipAuth(): Promise<import("../../../api/voip").VoipAuth>;
3
+ export declare function saveVoipAuth(userId: string): Promise<boolean>;
@@ -0,0 +1,8 @@
1
+ import { resolveRuntimeFromExportThis } from "../bootstrap/resolve-runtime-from-export-this";
2
+ import { getVoipAuthForRuntime, saveVoipAuthForRuntime, } from "../../../feature/voip/voip";
3
+ export async function getVoipAuth() {
4
+ return getVoipAuthForRuntime(resolveRuntimeFromExportThis(this));
5
+ }
6
+ export async function saveVoipAuth(userId) {
7
+ return saveVoipAuthForRuntime(resolveRuntimeFromExportThis(this), userId);
8
+ }
@@ -1,4 +1,5 @@
1
1
  import type { LockDeviceRuntime } from "../../runtime/LockDeviceRuntime";
2
+ import { MediaViewTimesResult } from "../../api/video";
2
3
  export interface GetMediaUrlParams {
3
4
  mediaPath: string;
4
5
  mediaBucket: string;
@@ -35,3 +36,5 @@ export interface MediaInfo {
35
36
  isTwoWayTalk: boolean;
36
37
  }
37
38
  export declare const getMediaInfoForRuntime: (runtime: LockDeviceRuntime) => MediaInfo;
39
+ export declare const getMediaViewTimesForRuntime: (runtime: LockDeviceRuntime) => Promise<MediaViewTimesResult>;
40
+ export declare const setMediaViewTimesForRuntime: (runtime: LockDeviceRuntime) => Promise<MediaViewTimesResult>;
@@ -4,6 +4,7 @@ import dpCodes from "../../config/dp-code";
4
4
  import { RotateType, VedioType } from "../../constant";
5
5
  import { isSupportShortLink } from "../../platform";
6
6
  import { getError } from "../../utils/errors";
7
+ import { getMediaViewTimes, setMediaViewTimes, } from "../../api/video";
7
8
  export const getMediaUrlForRuntime = async (runtime, params) => {
8
9
  const devId = runtime.config.devInfo.devId;
9
10
  if ("mediaPath" in params && "mediaBucket" in params) {
@@ -85,3 +86,9 @@ export const getMediaInfoForRuntime = (runtime) => {
85
86
  isTwoWayTalk: runtime.config.isTwoWayTalk,
86
87
  };
87
88
  };
89
+ export const getMediaViewTimesForRuntime = (runtime) => {
90
+ return getMediaViewTimes(runtime.config.devInfo.devId);
91
+ };
92
+ export const setMediaViewTimesForRuntime = (runtime) => {
93
+ return setMediaViewTimes(runtime.config.devInfo.devId);
94
+ };
@@ -34,28 +34,52 @@ export const isActiveThreadForRuntime = async (rt) => {
34
34
  }
35
35
  return false;
36
36
  };
37
+ const allModes = [
38
+ {
39
+ mode: "VR",
40
+ value: 1,
41
+ },
42
+ {
43
+ mode: "original",
44
+ value: 0,
45
+ },
46
+ {
47
+ mode: "vertical",
48
+ value: 3,
49
+ },
50
+ {
51
+ mode: "horizontal",
52
+ value: 2,
53
+ },
54
+ ];
37
55
  export const getDeviceAdvancedAbilitiesForRuntime = async (rt) => {
38
56
  if (rt.cache.deviceAdvanceAbilityCache) {
39
57
  return rt.cache.deviceAdvanceAbilityCache;
40
58
  }
41
- const [productAbilities, deviceAdvancedAbility] = await Promise.all([
59
+ const [productAbilitiesRes, deviceAdvancedAbilityRes] = await Promise.allSettled([
42
60
  getProductAbilities(rt.config.devInfo.devId, [
43
61
  "tyabi4ucx5",
44
62
  "tyabis9tpe",
45
63
  "tyabiwxrn9",
46
64
  "tyabipd4hh",
47
65
  "tyabin4u5v",
66
+ "visual_door_lock_cloud_store",
48
67
  ]),
49
68
  getDeviceAdvancedAbility(rt.config.devInfo.devId),
50
69
  ]);
70
+ const productAbilities = productAbilitiesRes.status === "fulfilled" ? productAbilitiesRes.value : [];
71
+ const deviceAdvancedAbility = deviceAdvancedAbilityRes.status === "fulfilled"
72
+ ? deviceAdvancedAbilityRes.value
73
+ : undefined;
51
74
  const deviceAdvanceAbilityCache = {
52
75
  cloudStorage: {
53
- support: deviceAdvancedAbility.types.includes(0),
76
+ support: deviceAdvancedAbility?.types?.includes(0) ?? false,
54
77
  },
55
78
  vr: {
56
79
  support: false,
57
- defaultMode: "",
80
+ defaultMode: "VR",
58
81
  modes: [],
82
+ coverMode: "VR",
59
83
  },
60
84
  ai: {
61
85
  support: false,
@@ -66,12 +90,12 @@ export const getDeviceAdvancedAbilitiesForRuntime = async (rt) => {
66
90
  config: {},
67
91
  },
68
92
  voip: {
69
- support: deviceAdvancedAbility.types.includes(1),
93
+ support: false,
70
94
  config: {},
71
95
  },
72
96
  wechatVoip: {
73
97
  support: false,
74
- config: {},
98
+ isPublice: true,
75
99
  },
76
100
  unlockGuide: {
77
101
  support: false,
@@ -85,8 +109,11 @@ export const getDeviceAdvancedAbilitiesForRuntime = async (rt) => {
85
109
  productAbilities.forEach((item) => {
86
110
  try {
87
111
  if (item.isOpen) {
88
- const data = JSON.parse(item.extConfig);
112
+ const data = item.extConfig ? JSON.parse(item.extConfig) : {};
89
113
  switch (item.abilityCode) {
114
+ case "visual_door_lock_cloud_store":
115
+ deviceAdvanceAbilityCache.cloudStorage.support = true;
116
+ break;
90
117
  case "tyabi4ucx5": {
91
118
  deviceAdvanceAbilityCache.ai.config = data;
92
119
  const dataReport = data?.ai_data_report ?? false;
@@ -100,6 +127,37 @@ export const getDeviceAdvancedAbilitiesForRuntime = async (rt) => {
100
127
  petRecognition ||
101
128
  voice ||
102
129
  message;
130
+ deviceAdvanceAbilityCache.vr.support = !!data?.lock_VR;
131
+ if (deviceAdvanceAbilityCache.vr.support) {
132
+ const modeMap = {
133
+ original: {
134
+ mode: "original",
135
+ value: 0,
136
+ },
137
+ VR: {
138
+ mode: "VR",
139
+ value: 1,
140
+ },
141
+ horizontal: {
142
+ mode: "horizontal",
143
+ value: 2,
144
+ },
145
+ vertical: {
146
+ mode: "vertical",
147
+ value: 3,
148
+ },
149
+ };
150
+ deviceAdvanceAbilityCache.vr.modes = allModes.filter((item) => {
151
+ return data?.modes?.includes(item.mode);
152
+ });
153
+ deviceAdvanceAbilityCache.vr.defaultMode = data.default_mode;
154
+ const exist = deviceAdvanceAbilityCache.vr.modes.find((x) => x.mode === deviceAdvanceAbilityCache.vr.defaultMode);
155
+ if (!exist) {
156
+ deviceAdvanceAbilityCache.vr.defaultMode =
157
+ deviceAdvanceAbilityCache.vr.modes?.[0].mode;
158
+ }
159
+ deviceAdvanceAbilityCache.vr.coverMode = data.photo_cover_format;
160
+ }
103
161
  break;
104
162
  }
105
163
  case "tyabis9tpe": {
@@ -109,8 +167,16 @@ export const getDeviceAdvancedAbilitiesForRuntime = async (rt) => {
109
167
  }
110
168
  case "tyabiwxrn9": {
111
169
  deviceAdvanceAbilityCache.wechatVoip.support =
170
+ deviceAdvancedAbility?.types?.includes(1) ?? false;
171
+ deviceAdvanceAbilityCache.wechatVoip.isPublice =
172
+ data?.WechatType === "0";
173
+ if (!deviceAdvanceAbilityCache.wechatVoip.isPublice) {
174
+ deviceAdvanceAbilityCache.wechatVoip.appId =
175
+ data["WechatMPAppid"];
176
+ deviceAdvanceAbilityCache.wechatVoip.modeId = data["WechatMPMid"];
177
+ }
178
+ deviceAdvanceAbilityCache.voip.support =
112
179
  !!data?.voipType?.includes("0");
113
- deviceAdvanceAbilityCache.wechatVoip.config = data;
114
180
  break;
115
181
  }
116
182
  case "tyabipd4hh": {
@@ -0,0 +1,4 @@
1
+ import { type UpdateVasNotifyConfigParams } from "../../api/notify";
2
+ import type { LockDeviceRuntime } from "../../runtime/LockDeviceRuntime";
3
+ export declare const getVasNotifyConfigForRuntime: (rt: LockDeviceRuntime) => Promise<import("../../api/notify").VasNotifyConfig>;
4
+ export declare const updateVasNotifyConfigForRuntime: (rt: LockDeviceRuntime, params: UpdateVasNotifyConfigParams) => Promise<import("../../api/notify").VasNotifyConfig>;
@@ -0,0 +1,3 @@
1
+ import { getVasNotifyConfigApi, updateVasNotifyConfigApi, } from "../../api/notify";
2
+ export const getVasNotifyConfigForRuntime = (rt) => getVasNotifyConfigApi(rt.config.devInfo.devId);
3
+ export const updateVasNotifyConfigForRuntime = (rt, params) => updateVasNotifyConfigApi(rt.config.devInfo.devId, params);
@@ -1,6 +1,6 @@
1
1
  import type { LockDeviceRuntime } from "../../runtime/LockDeviceRuntime";
2
2
  export interface GotoServiceParams {
3
- tab?: "cloudStorage" | "AI";
3
+ tab?: "cloudStorage" | "AI" | "voip";
4
4
  showGift?: boolean;
5
5
  }
6
6
  export declare function gotoServiceForRuntime(rt: LockDeviceRuntime, params?: GotoServiceParams): Promise<unknown>;
@@ -4,6 +4,9 @@ export function gotoServiceForRuntime(rt, params) {
4
4
  if (params?.tab === "AI") {
5
5
  type = 3;
6
6
  }
7
+ else if (params?.tab === "voip") {
8
+ type = 1;
9
+ }
7
10
  return new Promise((resolve, reject) => {
8
11
  let url = `godzilla://tyawqoyej4wi3pqebb?deviceId=${rt.config.devInfo.devId}&commodityType=${type}`;
9
12
  if (params?.showGift) {
@@ -84,8 +84,8 @@ export const initState = async (runtime) => {
84
84
  }
85
85
  else {
86
86
  try {
87
- const modeRes = await ipc.getCurrentSupportedTalkMode(devId);
88
87
  runtime.config.supportTalk = true;
88
+ const modeRes = await ipc.getCurrentSupportedTalkMode(devId);
89
89
  runtime.config.isTwoWayTalk = modeRes.talkbackMode === 2;
90
90
  sdkLog("info", "initState", "supportTalk", {
91
91
  devId,
@@ -99,7 +99,7 @@ export const initState = async (runtime) => {
99
99
  sdkLog("error", "initState", "supportTalk", {
100
100
  devId,
101
101
  duration: Date.now() - startedAt,
102
- data: {},
102
+ error: e,
103
103
  });
104
104
  }
105
105
  }
@@ -0,0 +1,5 @@
1
+ import type { LockDeviceRuntime } from "../../runtime/LockDeviceRuntime";
2
+ export declare const setStorageForRuntime: (rt: LockDeviceRuntime, key: string, data: unknown) => void;
3
+ export declare const getStorageForRuntime: <T = unknown>(rt: LockDeviceRuntime, key: string) => T | null;
4
+ export declare const removeStorageForRuntime: (rt: LockDeviceRuntime, key: string) => void;
5
+ export declare const clearStorageForRuntime: (rt: LockDeviceRuntime, keys: string[]) => void;
@@ -0,0 +1,32 @@
1
+ import { getStorageSync, removeStorageSync, setStorageSync, } from "../../platform";
2
+ const buildStorageKey = (rt, key) => {
3
+ const { devId, activeTime } = rt.config.devInfo;
4
+ return `${devId}_${activeTime}_${key}`;
5
+ };
6
+ export const setStorageForRuntime = (rt, key, data) => {
7
+ const value = typeof data === "string" ? data : JSON.stringify(data);
8
+ setStorageSync(buildStorageKey(rt, key), value);
9
+ };
10
+ export const getStorageForRuntime = (rt, key) => {
11
+ const raw = getStorageSync(buildStorageKey(rt, key));
12
+ if (raw == null || raw === "") {
13
+ return null;
14
+ }
15
+ if (typeof raw === "string") {
16
+ try {
17
+ return JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return raw;
21
+ }
22
+ }
23
+ return raw;
24
+ };
25
+ export const removeStorageForRuntime = (rt, key) => {
26
+ removeStorageSync(buildStorageKey(rt, key));
27
+ };
28
+ export const clearStorageForRuntime = (rt, keys) => {
29
+ keys.forEach((key) => {
30
+ removeStorageSync(buildStorageKey(rt, key));
31
+ });
32
+ };
@@ -0,0 +1,3 @@
1
+ import type { LockDeviceRuntime } from "../../runtime/LockDeviceRuntime";
2
+ export declare const getVoipAuthForRuntime: (rt: LockDeviceRuntime) => Promise<import("../../api/voip").VoipAuth>;
3
+ export declare const saveVoipAuthForRuntime: (rt: LockDeviceRuntime, userId: string) => Promise<boolean>;
@@ -0,0 +1,3 @@
1
+ import { getVoipAuthApi, saveVoipAuthApi } from "../../api/voip";
2
+ export const getVoipAuthForRuntime = (rt) => getVoipAuthApi(rt.config.devInfo.devId);
3
+ export const saveVoipAuthForRuntime = (rt, userId) => saveVoipAuthApi(rt.config.devInfo.devId, userId);
@@ -334,14 +334,19 @@ export interface AlbumMessage extends MediaInfo {
334
334
  type: number;
335
335
  createTime: number;
336
336
  }
337
+ export type VRModeType = "original" | "VR" | "horizontal" | "vertical";
337
338
  export interface DeviceAdvancedAbility {
338
339
  cloudStorage: {
339
340
  support: boolean;
340
341
  };
341
342
  vr: {
342
343
  support: boolean;
343
- defaultMode: string;
344
- modes: string[];
344
+ coverMode: VRModeType;
345
+ modes: Array<{
346
+ mode: VRModeType;
347
+ value: number;
348
+ }>;
349
+ defaultMode: VRModeType;
345
350
  };
346
351
  ai: {
347
352
  support: boolean;
@@ -353,7 +358,9 @@ export interface DeviceAdvancedAbility {
353
358
  };
354
359
  wechatVoip: {
355
360
  support: boolean;
356
- config: Record<string, any>;
361
+ isPublice: boolean;
362
+ appId?: string;
363
+ modeId?: string;
357
364
  };
358
365
  voip: {
359
366
  support: boolean;
@@ -1,2 +1,3 @@
1
1
  export * from "./device";
2
+ export * from "./storage";
2
3
  export { default as ipc } from "./ipc";
@@ -1,2 +1,3 @@
1
1
  export * from "./device";
2
+ export * from "./storage";
2
3
  export { default as ipc } from "./ipc";
@@ -0,0 +1,3 @@
1
+ export declare const setStorageSync: (key: string, data: unknown) => void;
2
+ export declare const getStorageSync: (key: string) => any;
3
+ export declare const removeStorageSync: (key: string) => void;
@@ -0,0 +1,9 @@
1
+ export const setStorageSync = (key, data) => {
2
+ ty.setStorageSync({ key, data });
3
+ };
4
+ export const getStorageSync = (key) => {
5
+ return ty.getStorageSync({ key });
6
+ };
7
+ export const removeStorageSync = (key) => {
8
+ ty.removeStorageSync({ key });
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ray-js/lock-sdk",
3
- "version": "1.2.0-beta.6",
3
+ "version": "1.2.0-beta.8",
4
4
  "files": [
5
5
  "lib",
6
6
  "LICENSE.md"