@monkvision/camera-web 5.1.8 → 5.2.1
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/lib/Camera/Camera.js +3 -3
- package/lib/Camera/hooks/useCameraPreview.js +38 -22
- package/lib/Camera/hooks/useUserMedia.d.ts +1 -11
- package/lib/Camera/hooks/useUserMedia.js +7 -43
- package/lib/i18n.js +2 -0
- package/lib/translations/it.json +3 -0
- package/lib/utils/errors.utils.js +6 -0
- package/package.json +12 -12
package/lib/Camera/Camera.js
CHANGED
|
@@ -34,10 +34,10 @@ function Camera(_a) {
|
|
|
34
34
|
var _f = (0, hooks_1.useCameraPreview)({
|
|
35
35
|
resolution: previewResolution,
|
|
36
36
|
facingMode: hooks_1.CameraFacingMode.ENVIRONMENT,
|
|
37
|
-
}), videoRef = _f.ref,
|
|
37
|
+
}), videoRef = _f.ref, previewDimensions = _f.previewDimensions, error = _f.error, retry = _f.retry, isPreviewLoading = _f.isLoading, availableCameraDevices = _f.availableCameraDevices, selectedCameraDeviceId = _f.selectedCameraDeviceId;
|
|
38
38
|
var _g = (0, hooks_1.useCameraCanvas)({
|
|
39
39
|
resolution: resolution,
|
|
40
|
-
streamDimensions:
|
|
40
|
+
streamDimensions: previewDimensions,
|
|
41
41
|
allowImageUpscaling: allowImageUpscaling,
|
|
42
42
|
}), canvasRef = _g.ref, canvasDimensions = _g.dimensions;
|
|
43
43
|
var takeScreenshot = (0, hooks_1.useCameraScreenshot)({
|
|
@@ -65,7 +65,7 @@ function Camera(_a) {
|
|
|
65
65
|
error: error,
|
|
66
66
|
retry: retry,
|
|
67
67
|
isLoading: isLoading,
|
|
68
|
-
dimensions:
|
|
68
|
+
dimensions: previewDimensions,
|
|
69
69
|
previewDimensions: previewDimensions,
|
|
70
70
|
}, cameraPreview: cameraPreview }, (hudProps !== null && hudProps !== void 0 ? hudProps : {})))) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: cameraPreview }));
|
|
71
71
|
}
|
|
@@ -17,40 +17,56 @@ var react_1 = require("react");
|
|
|
17
17
|
var common_1 = require("@monkvision/common");
|
|
18
18
|
var utils_1 = require("./utils");
|
|
19
19
|
var useUserMedia_1 = require("./useUserMedia");
|
|
20
|
+
function getPreviewDimensions(refVideo, windowDimensions) {
|
|
21
|
+
var _a, _b;
|
|
22
|
+
var height = (_a = refVideo.current) === null || _a === void 0 ? void 0 : _a.videoHeight;
|
|
23
|
+
var width = (_b = refVideo.current) === null || _b === void 0 ? void 0 : _b.videoWidth;
|
|
24
|
+
if (!windowDimensions || !height || !width) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
var windowAspectRatio = windowDimensions.width / windowDimensions.height;
|
|
28
|
+
var streamAspectRatio = width / height;
|
|
29
|
+
return windowAspectRatio >= streamAspectRatio
|
|
30
|
+
? {
|
|
31
|
+
width: windowDimensions.height * streamAspectRatio,
|
|
32
|
+
height: windowDimensions.height,
|
|
33
|
+
}
|
|
34
|
+
: {
|
|
35
|
+
width: windowDimensions.width,
|
|
36
|
+
height: windowDimensions.width / streamAspectRatio,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
20
39
|
/**
|
|
21
40
|
* Custom hook used to initialize and handle the camera preview. It initializes the camera stream based on the given
|
|
22
41
|
* configuration, and provides a handle to manage the camera such as the ref to the video element etc.
|
|
23
42
|
*/
|
|
24
43
|
function useCameraPreview(config) {
|
|
25
44
|
var ref = (0, react_1.useRef)(null);
|
|
45
|
+
var _a = (0, react_1.useState)(null), previewDimensions = _a[0], setPreviewDimensions = _a[1];
|
|
26
46
|
var windowDimensions = (0, common_1.useWindowDimensions)();
|
|
27
47
|
var handleError = (0, monitoring_1.useMonitoring)().handleError;
|
|
28
48
|
var userMediaResult = (0, useUserMedia_1.useUserMedia)((0, utils_1.getMediaConstraints)(config), ref);
|
|
29
|
-
var previewDimensions = (0, react_1.useMemo)(function () {
|
|
30
|
-
if (!windowDimensions || !userMediaResult.dimensions) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
var windowAspectRatio = windowDimensions.width / windowDimensions.height;
|
|
34
|
-
var streamAspectRatio = userMediaResult.dimensions.width / userMediaResult.dimensions.height;
|
|
35
|
-
return windowAspectRatio >= streamAspectRatio
|
|
36
|
-
? {
|
|
37
|
-
width: windowDimensions.height * streamAspectRatio,
|
|
38
|
-
height: windowDimensions.height,
|
|
39
|
-
}
|
|
40
|
-
: {
|
|
41
|
-
width: windowDimensions.width,
|
|
42
|
-
height: windowDimensions.width / streamAspectRatio,
|
|
43
|
-
};
|
|
44
|
-
}, [windowDimensions, userMediaResult.dimensions]);
|
|
45
49
|
(0, react_1.useEffect)(function () {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
var currentRef = ref.current;
|
|
51
|
+
if (userMediaResult.stream && currentRef) {
|
|
52
|
+
currentRef.srcObject = userMediaResult.stream;
|
|
53
|
+
var handleMetadata = function () {
|
|
54
|
+
currentRef === null || currentRef === void 0 ? void 0 : currentRef.play().catch(handleError);
|
|
55
|
+
setPreviewDimensions(getPreviewDimensions(ref, windowDimensions));
|
|
56
|
+
};
|
|
57
|
+
var handleResize = function () {
|
|
58
|
+
setPreviewDimensions(getPreviewDimensions(ref, windowDimensions));
|
|
51
59
|
};
|
|
60
|
+
currentRef.onloadedmetadata = handleMetadata;
|
|
61
|
+
currentRef.onresize = handleResize;
|
|
52
62
|
}
|
|
53
|
-
|
|
63
|
+
return function () {
|
|
64
|
+
if (currentRef) {
|
|
65
|
+
currentRef.onloadedmetadata = null;
|
|
66
|
+
currentRef.onresize = null;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}, [windowDimensions, userMediaResult.stream, handleError]);
|
|
54
70
|
return (0, react_1.useMemo)(function () { return (__assign({ ref: ref, previewDimensions: previewDimensions }, userMediaResult)); }, [previewDimensions, userMediaResult]);
|
|
55
71
|
}
|
|
56
72
|
exports.useCameraPreview = useCameraPreview;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
|
-
import { PixelDimensions } from '@monkvision/types';
|
|
3
2
|
/**
|
|
4
3
|
* Enumeration of the different Native error names that can happen when a stream is invalid.
|
|
5
4
|
*/
|
|
@@ -11,11 +10,7 @@ export declare enum InvalidStreamErrorName {
|
|
|
11
10
|
/**
|
|
12
11
|
* The stream had too many video tracks (more than one).
|
|
13
12
|
*/
|
|
14
|
-
TOO_MANY_VIDEO_TRACKS = "TooManyVideoTracks"
|
|
15
|
-
/**
|
|
16
|
-
* The stream's video track had no dimensions.
|
|
17
|
-
*/
|
|
18
|
-
NO_DIMENSIONS = "NoDimensions"
|
|
13
|
+
TOO_MANY_VIDEO_TRACKS = "TooManyVideoTracks"
|
|
19
14
|
}
|
|
20
15
|
/**
|
|
21
16
|
* The type of errors that the `useUserMedia` hook can return.
|
|
@@ -90,11 +85,6 @@ export interface UserMediaResult {
|
|
|
90
85
|
* The resulting video stream. The stream can be null when not initialized or in case of an error.
|
|
91
86
|
*/
|
|
92
87
|
stream: MediaStream | null;
|
|
93
|
-
/**
|
|
94
|
-
* The dimensions of the resulting camera stream. Note that these dimensions can differ from the ones given in the
|
|
95
|
-
* stream constraints if they are not supported or available on the current device.
|
|
96
|
-
*/
|
|
97
|
-
dimensions: PixelDimensions | null;
|
|
98
88
|
/**
|
|
99
89
|
* The error details. If no error has occurred, this object will be null.
|
|
100
90
|
*/
|
|
@@ -84,10 +84,6 @@ var InvalidStreamErrorName;
|
|
|
84
84
|
* The stream had too many video tracks (more than one).
|
|
85
85
|
*/
|
|
86
86
|
InvalidStreamErrorName["TOO_MANY_VIDEO_TRACKS"] = "TooManyVideoTracks";
|
|
87
|
-
/**
|
|
88
|
-
* The stream's video track had no dimensions.
|
|
89
|
-
*/
|
|
90
|
-
InvalidStreamErrorName["NO_DIMENSIONS"] = "NoDimensions";
|
|
91
87
|
})(InvalidStreamErrorName = exports.InvalidStreamErrorName || (exports.InvalidStreamErrorName = {}));
|
|
92
88
|
var InvalidStreamError = /** @class */ (function (_super) {
|
|
93
89
|
__extends(InvalidStreamError, _super);
|
|
@@ -157,25 +153,6 @@ function getStreamDeviceId(stream) {
|
|
|
157
153
|
var settings = getStreamVideoTrackSettings(stream);
|
|
158
154
|
return (_a = settings.deviceId) !== null && _a !== void 0 ? _a : null;
|
|
159
155
|
}
|
|
160
|
-
function swapDimensions(dimensions) {
|
|
161
|
-
return {
|
|
162
|
-
width: dimensions.height,
|
|
163
|
-
height: dimensions.width,
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
function getStreamDimensions(stream, checkOrientation) {
|
|
167
|
-
var _a = getStreamVideoTrackSettings(stream), width = _a.width, height = _a.height;
|
|
168
|
-
if (!width || !height) {
|
|
169
|
-
throw new InvalidStreamError('Unable to set up the Monk camera screenshoter because the video stream does not have the properties width and height defined.', InvalidStreamErrorName.NO_DIMENSIONS);
|
|
170
|
-
}
|
|
171
|
-
var dimensions = { width: width, height: height };
|
|
172
|
-
if (!(0, common_1.isMobileDevice)() || !checkOrientation) {
|
|
173
|
-
return dimensions;
|
|
174
|
-
}
|
|
175
|
-
var isStreamInPortrait = width < height;
|
|
176
|
-
var isDeviceInPortrait = window.matchMedia('(orientation: portrait)').matches;
|
|
177
|
-
return isStreamInPortrait !== isDeviceInPortrait ? swapDimensions(dimensions) : dimensions;
|
|
178
|
-
}
|
|
179
156
|
/**
|
|
180
157
|
* React hook that wraps the `navigator.mediaDevices.getUserMedia` browser function in order to add React logic layers
|
|
181
158
|
* and utility tools :
|
|
@@ -198,12 +175,11 @@ function useUserMedia(constraints, videoRef) {
|
|
|
198
175
|
var _this = this;
|
|
199
176
|
var streamRef = (0, react_1.useRef)(null);
|
|
200
177
|
var _a = (0, react_1.useState)(null), stream = _a[0], setStream = _a[1];
|
|
201
|
-
var _b = (0, react_1.useState)(
|
|
202
|
-
var _c = (0, react_1.useState)(
|
|
203
|
-
var _d = (0, react_1.useState)(
|
|
204
|
-
var _e = (0, react_1.useState)(
|
|
205
|
-
var _f = (0, react_1.useState)(null),
|
|
206
|
-
var _g = (0, react_1.useState)(null), lastConstraintsApplied = _g[0], setLastConstraintsApplied = _g[1];
|
|
178
|
+
var _b = (0, react_1.useState)(false), isLoading = _b[0], setIsLoading = _b[1];
|
|
179
|
+
var _c = (0, react_1.useState)(null), error = _c[0], setError = _c[1];
|
|
180
|
+
var _d = (0, react_1.useState)([]), availableCameraDevices = _d[0], setAvailableCameraDevices = _d[1];
|
|
181
|
+
var _e = (0, react_1.useState)(null), selectedCameraDeviceId = _e[0], setSelectedCameraDeviceId = _e[1];
|
|
182
|
+
var _f = (0, react_1.useState)(null), lastConstraintsApplied = _f[0], setLastConstraintsApplied = _f[1];
|
|
207
183
|
var lastGetUserMediaTimeRef = (0, react_1.useRef)(null);
|
|
208
184
|
var handleError = (0, monitoring_1.useMonitoring)().handleError;
|
|
209
185
|
var isMounted = (0, common_1.useIsMounted)();
|
|
@@ -267,10 +243,9 @@ function useUserMedia(constraints, videoRef) {
|
|
|
267
243
|
if (isMounted()) {
|
|
268
244
|
setStream(str);
|
|
269
245
|
streamRef.current = str;
|
|
270
|
-
setDimensions(getStreamDimensions(str, true));
|
|
271
|
-
setIsLoading(false);
|
|
272
|
-
setAvailableCameraDevices(deviceDetails.availableDevices);
|
|
273
246
|
setSelectedCameraDeviceId(getStreamDeviceId(str));
|
|
247
|
+
setAvailableCameraDevices(deviceDetails.availableDevices);
|
|
248
|
+
setIsLoading(false);
|
|
274
249
|
}
|
|
275
250
|
return [2 /*return*/, str];
|
|
276
251
|
}
|
|
@@ -335,16 +310,6 @@ function useUserMedia(constraints, videoRef) {
|
|
|
335
310
|
effect().catch(handleError);
|
|
336
311
|
}
|
|
337
312
|
}, [constraints, stream, error, isLoading, lastConstraintsApplied, getUserMedia, videoRef]);
|
|
338
|
-
(0, react_1.useEffect)(function () {
|
|
339
|
-
if (stream && videoRef && videoRef.current) {
|
|
340
|
-
// eslint-disable-next-line no-param-reassign
|
|
341
|
-
videoRef.current.onresize = function () {
|
|
342
|
-
if (isMounted()) {
|
|
343
|
-
setDimensions(getStreamDimensions(stream, false));
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
}, [stream, videoRef]);
|
|
348
313
|
(0, react_1.useEffect)(function () {
|
|
349
314
|
return function () {
|
|
350
315
|
var _a;
|
|
@@ -356,7 +321,6 @@ function useUserMedia(constraints, videoRef) {
|
|
|
356
321
|
return (0, common_1.useObjectMemo)({
|
|
357
322
|
getUserMedia: getUserMedia,
|
|
358
323
|
stream: stream,
|
|
359
|
-
dimensions: dimensions,
|
|
360
324
|
error: error,
|
|
361
325
|
retry: retry,
|
|
362
326
|
isLoading: isLoading,
|
package/lib/i18n.js
CHANGED
|
@@ -9,6 +9,7 @@ var en_json_1 = __importDefault(require("./translations/en.json"));
|
|
|
9
9
|
var fr_json_1 = __importDefault(require("./translations/fr.json"));
|
|
10
10
|
var de_json_1 = __importDefault(require("./translations/de.json"));
|
|
11
11
|
var nl_json_1 = __importDefault(require("./translations/nl.json"));
|
|
12
|
+
var it_json_1 = __importDefault(require("./translations/it.json"));
|
|
12
13
|
/**
|
|
13
14
|
* i18n instance of the Camera package. You can use this instance to automatically sync your application current
|
|
14
15
|
* language with the one used by the components of the package.
|
|
@@ -19,5 +20,6 @@ exports.i18nCamera = (0, common_1.i18nCreateSDKInstance)({
|
|
|
19
20
|
fr: { translation: fr_json_1.default },
|
|
20
21
|
de: { translation: de_json_1.default },
|
|
21
22
|
nl: { translation: nl_json_1.default },
|
|
23
|
+
it: { translation: it_json_1.default },
|
|
22
24
|
},
|
|
23
25
|
});
|
|
@@ -14,6 +14,7 @@ function getCameraErrorLabel(error) {
|
|
|
14
14
|
fr: "L'apperçu de la caméra n'est pas disponible car l'accès à la caméra n'est pas autorisé.",
|
|
15
15
|
de: 'Die Kameravorschau ist nicht verfügbar, da für die Seite kein Kamerazugriff gewährt wurde.',
|
|
16
16
|
nl: 'De cameravoorbeeld is niet beschikbaar omdat er geen toegang tot de camera is verleend aan de pagina.',
|
|
17
|
+
it: "L'anteprima della fotocamera non è disponibile perché l'accesso alla fotocamera non è stato concesso alla pagina.",
|
|
17
18
|
};
|
|
18
19
|
case Camera_1.UserMediaErrorType.WEBPAGE_NOT_ALLOWED:
|
|
19
20
|
return {
|
|
@@ -21,6 +22,7 @@ function getCameraErrorLabel(error) {
|
|
|
21
22
|
fr: "Impossible d'accéder à la caméra. Veuillez vous assurer d'appuyer sur “Autoriser” lorsqu'on vous propose d'autoriser l'accès à la caméra pour cette page web.",
|
|
22
23
|
de: 'Die Kamera kann nicht zugelassen werden. Stellen Sie sicher, dass Sie auf „Zulassen“ drücken, wenn Sie aufgefordert werden, die Kamera für diese Webseite zuzulassen.',
|
|
23
24
|
nl: 'Kan geen toestemming krijgen voor de camera. Zorg ervoor dat u op “Toestaan” drukt wanneer u wordt gevraagd om toestemming te geven voor het gebruik van de camera op deze webpagina.',
|
|
25
|
+
it: 'Impossibile ottenere l\'accesso alla fotocamera. Assicurati di premere "Consenti" quando ti viene chiesto di concedere il permesso di utilizzare la fotocamera per questa pagina web.',
|
|
24
26
|
};
|
|
25
27
|
case Camera_1.UserMediaErrorType.BROWSER_NOT_ALLOWED:
|
|
26
28
|
return {
|
|
@@ -28,6 +30,7 @@ function getCameraErrorLabel(error) {
|
|
|
28
30
|
fr: "Impossible d'accéder à la caméra. Veuillez vous assurer d'autoriser l'accès à la caméra pour ce navigateur internet dans les paramètres de votre téléphone.",
|
|
29
31
|
de: 'Der Zugriff auf die Kamera ist nicht möglich. Stellen Sie sicher, dass Sie in den Einstellungen Ihres Geräts den Kamerazugriff für Ihren aktuellen Internetbrowser zulassen.',
|
|
30
32
|
nl: 'Kan geen cameratoegang krijgen. Zorg ervoor dat u de camera toegang verleent tot uw huidige internet browser in de instellingen van uw apparaat.',
|
|
33
|
+
it: "Impossibile ottenere l'accesso alla fotocamera. Assicurati di concedere l'accesso alla fotocamera al tuo browser internet corrente nelle impostazioni del tuo dispositivo.",
|
|
31
34
|
};
|
|
32
35
|
case Camera_1.UserMediaErrorType.STREAM_INACTIVE:
|
|
33
36
|
return {
|
|
@@ -35,6 +38,7 @@ function getCameraErrorLabel(error) {
|
|
|
35
38
|
fr: 'Le flux vidéo de la caméra a été coupé de manière inattendue.',
|
|
36
39
|
de: 'Der Video-Stream der Kamera wurde unerwartet geschlossen.',
|
|
37
40
|
nl: 'De videostream van de camera is onverwacht gesloten.',
|
|
41
|
+
it: 'Il flusso video della fotocamera è stato chiuso inaspettatamente.',
|
|
38
42
|
};
|
|
39
43
|
case Camera_1.UserMediaErrorType.INVALID_STREAM:
|
|
40
44
|
return {
|
|
@@ -42,6 +46,7 @@ function getCameraErrorLabel(error) {
|
|
|
42
46
|
fr: 'Impossible de traiter le flux vidéo de la caméra.',
|
|
43
47
|
de: 'Der Videostrom der Kamera kann nicht verarbeitet werden.',
|
|
44
48
|
nl: 'De videostream van de camera kan niet worden verwerkt.',
|
|
49
|
+
it: 'Impossibile elaborare il flusso video della fotocamera.',
|
|
45
50
|
};
|
|
46
51
|
default:
|
|
47
52
|
return {
|
|
@@ -49,6 +54,7 @@ function getCameraErrorLabel(error) {
|
|
|
49
54
|
fr: 'Une erreur inattendue est survenue lors de la récupération du flux vidéo de la caméra.',
|
|
50
55
|
de: 'Beim Abrufen des Kamera-Videostreams ist ein unerwarteter Fehler aufgetreten.',
|
|
51
56
|
nl: 'Er is een onverwachte fout opgetreden bij het ophalen van de videostream van de camera.',
|
|
57
|
+
it: 'Si è verificato un errore imprevisto durante il recupero del flusso video della fotocamera.',
|
|
52
58
|
};
|
|
53
59
|
}
|
|
54
60
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monkvision/camera-web",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.1",
|
|
4
4
|
"license": "BSD-3-Clause-Clear",
|
|
5
5
|
"packageManager": "yarn@3.2.4",
|
|
6
6
|
"description": "MonkJs camera package for React (web) used to display a camera preview and take pictures",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"lint:fix": "yarn run prettier:fix && yarn run eslint:fix"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@monkvision/common": "5.1
|
|
32
|
-
"@monkvision/common-ui-web": "5.1
|
|
33
|
-
"@monkvision/monitoring": "5.1
|
|
31
|
+
"@monkvision/common": "5.2.1",
|
|
32
|
+
"@monkvision/common-ui-web": "5.2.1",
|
|
33
|
+
"@monkvision/monitoring": "5.2.1",
|
|
34
34
|
"fast-deep-equal": "^3.1.3",
|
|
35
35
|
"i18next": "^23.4.5",
|
|
36
36
|
"react-i18next": "^13.2.0"
|
|
@@ -42,13 +42,13 @@
|
|
|
42
42
|
"react-router-dom": "^6.22.3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@monkvision/eslint-config-base": "5.1
|
|
46
|
-
"@monkvision/eslint-config-typescript": "5.1
|
|
47
|
-
"@monkvision/eslint-config-typescript-react": "5.1
|
|
48
|
-
"@monkvision/jest-config": "5.1
|
|
49
|
-
"@monkvision/prettier-config": "5.1
|
|
50
|
-
"@monkvision/test-utils": "5.1
|
|
51
|
-
"@monkvision/typescript-config": "5.1
|
|
45
|
+
"@monkvision/eslint-config-base": "5.2.1",
|
|
46
|
+
"@monkvision/eslint-config-typescript": "5.2.1",
|
|
47
|
+
"@monkvision/eslint-config-typescript-react": "5.2.1",
|
|
48
|
+
"@monkvision/jest-config": "5.2.1",
|
|
49
|
+
"@monkvision/prettier-config": "5.2.1",
|
|
50
|
+
"@monkvision/test-utils": "5.2.1",
|
|
51
|
+
"@monkvision/typescript-config": "5.2.1",
|
|
52
52
|
"@testing-library/react": "^12.1.5",
|
|
53
53
|
"@testing-library/react-hooks": "^8.0.1",
|
|
54
54
|
"@types/fscreen": "^1.0.1",
|
|
@@ -90,5 +90,5 @@
|
|
|
90
90
|
"url": "https://github.com/monkvision/monkjs/issues"
|
|
91
91
|
},
|
|
92
92
|
"homepage": "https://github.com/monkvision/monkjs",
|
|
93
|
-
"gitHead": "
|
|
93
|
+
"gitHead": "30d140ff8b98f818e0bafa5a41d319d0b5a1e50f"
|
|
94
94
|
}
|