Testing with face face-api.js
This commit is contained in:
parent
41aad5e205
commit
6fb22e429c
24 changed files with 428 additions and 166 deletions
|
@ -18,11 +18,11 @@
|
|||
"@sentry/nextjs": "^6.7.1",
|
||||
"@stripe/stripe-js": "^1.13.2",
|
||||
"@tensorflow-models/blazeface": "./thirdparty/blazeface",
|
||||
"@tensorflow/tfjs": "^3.11.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^3.11.0",
|
||||
"@tensorflow/tfjs": "^1.7.0",
|
||||
"@tensorflow/tfjs-backend-wasm": "^1.7.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^3.11.0",
|
||||
"@tensorflow/tfjs-converter": "^3.11.0",
|
||||
"@tensorflow/tfjs-core": "^3.11.0",
|
||||
"@tensorflow/tfjs-converter": "^1.7.0",
|
||||
"@tensorflow/tfjs-core": "^1.7.0",
|
||||
"@tensorflow/tfjs-tflite": "^0.0.1-alpha.7",
|
||||
"@typescript-eslint/eslint-plugin": "^4.25.0",
|
||||
"@typescript-eslint/parser": "^4.25.0",
|
||||
|
@ -37,6 +37,7 @@
|
|||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"exifr": "^7.1.3",
|
||||
"face-api.js": "^0.22.2",
|
||||
"file-type": "^16.5.3",
|
||||
"formik": "^2.1.5",
|
||||
"heic-convert": "^1.2.4",
|
||||
|
|
BIN
public/models/face-api/age_gender_model-shard1
Normal file
BIN
public/models/face-api/age_gender_model-shard1
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
public/models/face-api/face_expression_model-shard1
Normal file
BIN
public/models/face-api/face_expression_model-shard1
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
public/models/face-api/face_landmark_68_model-shard1
Normal file
BIN
public/models/face-api/face_landmark_68_model-shard1
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
public/models/face-api/face_landmark_68_tiny_model-shard1
Normal file
BIN
public/models/face-api/face_landmark_68_tiny_model-shard1
Normal file
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
[{"weights":[{"name":"dense0/conv0/filters","shape":[3,3,3,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008194216092427571,"min":-0.9423348506291708}},{"name":"dense0/conv0/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006839508168837603,"min":-0.8412595047670252}},{"name":"dense0/conv1/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009194007106855804,"min":-1.2779669878529567}},{"name":"dense0/conv1/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0036026100317637128,"min":-0.3170296827952067}},{"name":"dense0/conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.000740380117706224,"min":-0.06367269012273527}},{"name":"dense0/conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":1,"min":0}},{"name":"dense0/conv2/pointwise_filter","shape":[1,1,32,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":1,"min":0}},{"name":"dense0/conv2/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0037702228508743585,"min":-0.6220867703942692}},{"name":"dense1/conv0/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0033707996209462483,"min":-0.421349952618281}},{"name":"dense1/conv0/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014611541991140328,"min":-1.8556658328748217}},{"name":"dense1/conv0/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002832523046755323,"min":-0.30307996600281956}},{"name":"dense1/conv1/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006593170586754294,"min":-0.6329443763284123}},{"name":"dense1/conv1/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.012215249211180444,"min":-1.6001976466646382}},{"name":"dense1/conv1/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002384825547536214,"min":-0.3028728445370992}},{"name":"dense1/conv2/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005859645441466687,"min":-0.7617539073906693}},{"name":"dense1/conv2/pointwise_filter","shape":[1,1,64,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013121426806730382,"min":-1.7845140457153321}},{"name":"dense1/conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0032247188044529336,"min":-0.46435950784122243}},{"name":"dense2/conv0/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002659512618008782,"min":-0.32977956463308894}},{"name":"dense2/conv0/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015499923743453681,"min":-1.9839902391620712}},{"name":"dense2/conv0/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0032450980999890497,"min":-0.522460794098237}},{"name":"dense2/conv1/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005911862382701799,"min":-0.792189559282041}},{"name":"dense2/conv1/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021025861478319356,"min":-2.2077154552235325}},{"name":"dense2/conv1/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.00349616945958605,"min":-0.46149436866535865}},{"name":"dense2/conv2/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008104994250278847,"min":-1.013124281284856}},{"name":"dense2/conv2/pointwise_filter","shape":[1,1,128,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.029337059282789044,"min":-3.5791212325002633}},{"name":"dense2/conv2/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0038808938334969913,"min":-0.4230174278511721}},{"name":"fc/weights","shape":[128,136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.014016061670639936,"min":-1.8921683255363912}},{"name":"fc/bias","shape":[136],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0029505149698724935,"min":0.088760145008564}}],"paths":["face_landmark_68_tiny_model-shard1"]}]
|
BIN
public/models/face-api/face_recognition_model-shard1
Normal file
BIN
public/models/face-api/face_recognition_model-shard1
Normal file
Binary file not shown.
6
public/models/face-api/face_recognition_model-shard2
Normal file
6
public/models/face-api/face_recognition_model-shard2
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/models/face-api/mtcnn_model-shard1
Normal file
BIN
public/models/face-api/mtcnn_model-shard1
Normal file
Binary file not shown.
1
public/models/face-api/mtcnn_model-weights_manifest.json
Normal file
1
public/models/face-api/mtcnn_model-weights_manifest.json
Normal file
|
@ -0,0 +1 @@
|
|||
[{"paths":["mtcnn_model-shard1"],"weights":[{"dtype":"float32","name":"pnet/conv1/weights","shape":[3,3,3,10]},{"dtype":"float32","name":"pnet/conv1/bias","shape":[10]},{"dtype":"float32","name":"pnet/prelu1_alpha","shape":[10]},{"dtype":"float32","name":"pnet/conv2/weights","shape":[3,3,10,16]},{"dtype":"float32","name":"pnet/conv2/bias","shape":[16]},{"dtype":"float32","name":"pnet/prelu2_alpha","shape":[16]},{"dtype":"float32","name":"pnet/conv3/weights","shape":[3,3,16,32]},{"dtype":"float32","name":"pnet/conv3/bias","shape":[32]},{"dtype":"float32","name":"pnet/prelu3_alpha","shape":[32]},{"dtype":"float32","name":"pnet/conv4_1/weights","shape":[1,1,32,2]},{"dtype":"float32","name":"pnet/conv4_1/bias","shape":[2]},{"dtype":"float32","name":"pnet/conv4_2/weights","shape":[1,1,32,4]},{"dtype":"float32","name":"pnet/conv4_2/bias","shape":[4]},{"dtype":"float32","name":"rnet/conv1/weights","shape":[3,3,3,28]},{"dtype":"float32","name":"rnet/conv1/bias","shape":[28]},{"dtype":"float32","name":"rnet/prelu1_alpha","shape":[28]},{"dtype":"float32","name":"rnet/conv2/weights","shape":[3,3,28,48]},{"dtype":"float32","name":"rnet/conv2/bias","shape":[48]},{"dtype":"float32","name":"rnet/prelu2_alpha","shape":[48]},{"dtype":"float32","name":"rnet/conv3/weights","shape":[2,2,48,64]},{"dtype":"float32","name":"rnet/conv3/bias","shape":[64]},{"dtype":"float32","name":"rnet/prelu3_alpha","shape":[64]},{"dtype":"float32","name":"rnet/fc1/weights","shape":[576,128]},{"dtype":"float32","name":"rnet/fc1/bias","shape":[128]},{"dtype":"float32","name":"rnet/prelu4_alpha","shape":[128]},{"dtype":"float32","name":"rnet/fc2_1/weights","shape":[128,2]},{"dtype":"float32","name":"rnet/fc2_1/bias","shape":[2]},{"dtype":"float32","name":"rnet/fc2_2/weights","shape":[128,4]},{"dtype":"float32","name":"rnet/fc2_2/bias","shape":[4]},{"dtype":"float32","name":"onet/conv1/weights","shape":[3,3,3,32]},{"dtype":"float32","name":"onet/conv1/bias","shape":[32]},{"dtype":"float32","name":"onet/prelu1_alpha","shape":[32]},{"dtype":"float32","name":"onet/conv2/weights","shape":[3,3,32,64]},{"dtype":"float32","name":"onet/conv2/bias","shape":[64]},{"dtype":"float32","name":"onet/prelu2_alpha","shape":[64]},{"dtype":"float32","name":"onet/conv3/weights","shape":[3,3,64,64]},{"dtype":"float32","name":"onet/conv3/bias","shape":[64]},{"dtype":"float32","name":"onet/prelu3_alpha","shape":[64]},{"dtype":"float32","name":"onet/conv4/weights","shape":[2,2,64,128]},{"dtype":"float32","name":"onet/conv4/bias","shape":[128]},{"dtype":"float32","name":"onet/prelu4_alpha","shape":[128]},{"dtype":"float32","name":"onet/fc1/weights","shape":[1152,256]},{"dtype":"float32","name":"onet/fc1/bias","shape":[256]},{"dtype":"float32","name":"onet/prelu5_alpha","shape":[256]},{"dtype":"float32","name":"onet/fc2_1/weights","shape":[256,2]},{"dtype":"float32","name":"onet/fc2_1/bias","shape":[2]},{"dtype":"float32","name":"onet/fc2_2/weights","shape":[256,4]},{"dtype":"float32","name":"onet/fc2_2/bias","shape":[4]},{"dtype":"float32","name":"onet/fc2_3/weights","shape":[256,10]},{"dtype":"float32","name":"onet/fc2_3/bias","shape":[10]}]}]
|
BIN
public/models/face-api/ssd_mobilenetv1_model-shard1
Normal file
BIN
public/models/face-api/ssd_mobilenetv1_model-shard1
Normal file
Binary file not shown.
137
public/models/face-api/ssd_mobilenetv1_model-shard2
Normal file
137
public/models/face-api/ssd_mobilenetv1_model-shard2
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
BIN
public/models/face-api/tiny_face_detector_model-shard1
Normal file
BIN
public/models/face-api/tiny_face_detector_model-shard1
Normal file
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
[{"weights":[{"name":"conv0/filters","shape":[3,3,3,16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.009007044399485869,"min":-1.2069439495311063}},{"name":"conv0/bias","shape":[16],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.005263455241334205,"min":-0.9211046672334858}},{"name":"conv1/depthwise_filter","shape":[3,3,16,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.004001977630690033,"min":-0.5042491814669441}},{"name":"conv1/pointwise_filter","shape":[1,1,16,32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.013836609615999109,"min":-1.411334180831909}},{"name":"conv1/bias","shape":[32],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0015159862590771096,"min":-0.30926119685173037}},{"name":"conv2/depthwise_filter","shape":[3,3,32,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002666276225856706,"min":-0.317286870876948}},{"name":"conv2/pointwise_filter","shape":[1,1,32,64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.015265831292844286,"min":-1.6792414422128714}},{"name":"conv2/bias","shape":[64],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0020280554598453,"min":-0.37113414915168985}},{"name":"conv3/depthwise_filter","shape":[3,3,64,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006100742489683862,"min":-0.8907084034938438}},{"name":"conv3/pointwise_filter","shape":[1,1,64,128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.016276211832083907,"min":-2.0508026908425725}},{"name":"conv3/bias","shape":[128],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.003394414279975143,"min":-0.7637432129944072}},{"name":"conv4/depthwise_filter","shape":[3,3,128,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.006716050119961009,"min":-0.8059260143953211}},{"name":"conv4/pointwise_filter","shape":[1,1,128,256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.021875603993733724,"min":-2.8875797271728514}},{"name":"conv4/bias","shape":[256],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.0041141652009066415,"min":-0.8187188749804216}},{"name":"conv5/depthwise_filter","shape":[3,3,256,1],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008423839597141042,"min":-0.9013508368940915}},{"name":"conv5/pointwise_filter","shape":[1,1,256,512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.030007277283014035,"min":-3.8709387695088107}},{"name":"conv5/bias","shape":[512],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.008402082966823203,"min":-1.4871686851277068}},{"name":"conv8/filters","shape":[1,1,512,25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.028336129469030042,"min":-4.675461362389957}},{"name":"conv8/bias","shape":[25],"dtype":"float32","quantization":{"dtype":"uint8","scale":0.002268134028303857,"min":-0.41053225912299807}}],"paths":["tiny_face_detector_model-shard1"]}]
|
|
@ -11,7 +11,7 @@ import TFJSImage from './TFJSImage';
|
|||
|
||||
export default function MLDebug() {
|
||||
const [token, setToken] = useState<string>();
|
||||
const [clusterFaceDistance, setClusterFaceDistance] = useState<number>(0.8);
|
||||
const [clusterFaceDistance, setClusterFaceDistance] = useState<number>(0.5);
|
||||
const [minClusterSize, setMinClusterSize] = useState<number>(4);
|
||||
const [mlResult, setMlResult] = useState<MLSyncResult>({
|
||||
allFaces: [],
|
||||
|
@ -100,7 +100,7 @@ export default function MLDebug() {
|
|||
<div key={ind}>
|
||||
<TFJSImage
|
||||
faceImage={
|
||||
mlResult.allFaces[faceIndex]?.faceImage
|
||||
mlResult.allFaces[faceIndex]
|
||||
}></TFJSImage>
|
||||
</div>
|
||||
))}
|
||||
|
@ -113,7 +113,7 @@ export default function MLDebug() {
|
|||
<div key={index}>
|
||||
<TFJSImage
|
||||
faceImage={
|
||||
mlResult.allFaces[faceIndex]?.faceImage
|
||||
mlResult.allFaces[faceIndex]
|
||||
}></TFJSImage>
|
||||
</div>
|
||||
))}
|
||||
|
|
101
src/services/machineLearning/faceEnvPatch.js
Normal file
101
src/services/machineLearning/faceEnvPatch.js
Normal file
|
@ -0,0 +1,101 @@
|
|||
/* eslint no-prototype-builtins: "off", no-case-declarations: "off", no-undef: "off", no-constant-condition: "off", eqeqeq: "off" */
|
||||
// From: https://github.com/justadudewhohacks/face-api.js/issues/47
|
||||
// This is needed because face-api.js does not support working in a WebWorker natively
|
||||
// Updated Dec 1 2020 to work on latest Chrome (tested in WebWorkers on Chrome Mobile on Android / Google Pixel 3 as well)
|
||||
|
||||
self.Canvas = self.HTMLCanvasElement = OffscreenCanvas;
|
||||
// self.HTMLCanvasElement.name = 'HTMLCanvasElement';
|
||||
// self.Canvas.name = 'Canvas';
|
||||
|
||||
self.CanvasRenderingContext2D = OffscreenCanvasRenderingContext2D;
|
||||
|
||||
function HTMLImageElement() {}
|
||||
function HTMLVideoElement() {}
|
||||
|
||||
self.Image = HTMLImageElement;
|
||||
self.Video = HTMLVideoElement;
|
||||
|
||||
function Storage() {
|
||||
let _data = {};
|
||||
this.clear = function () {
|
||||
return (_data = {});
|
||||
};
|
||||
this.getItem = function (id) {
|
||||
return _data.hasOwnProperty(id) ? _data[id] : undefined;
|
||||
};
|
||||
this.removeItem = function (id) {
|
||||
return delete _data[id];
|
||||
};
|
||||
this.setItem = function (id, val) {
|
||||
return (_data[id] = String(val));
|
||||
};
|
||||
}
|
||||
class Document extends EventTarget {}
|
||||
|
||||
self.document = new Document();
|
||||
|
||||
self.window = self.Window = self;
|
||||
self.localStorage = new Storage();
|
||||
|
||||
function createElement(element) {
|
||||
switch (element) {
|
||||
case 'canvas':
|
||||
const canvas = new Canvas(1, 1);
|
||||
canvas.localName = 'canvas';
|
||||
canvas.nodeName = 'CANVAS';
|
||||
canvas.tagName = 'CANVAS';
|
||||
canvas.nodeType = 1;
|
||||
canvas.innerHTML = '';
|
||||
canvas.remove = () => {
|
||||
console.log('nope');
|
||||
};
|
||||
return canvas;
|
||||
default:
|
||||
console.log('arg', element);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
document.createElement = createElement;
|
||||
document.location = self.location;
|
||||
|
||||
// These are the same checks face-api.js/isBrowser does
|
||||
if (!typeof window == 'object') {
|
||||
console.warn('Check failed: window');
|
||||
}
|
||||
if (typeof document === 'undefined') {
|
||||
console.warn('Check failed: document');
|
||||
}
|
||||
if (typeof HTMLImageElement === 'undefined') {
|
||||
console.warn('Check failed: HTMLImageElement');
|
||||
}
|
||||
if (typeof HTMLCanvasElement === 'undefined') {
|
||||
console.warn('Check failed: HTMLCanvasElement');
|
||||
}
|
||||
if (typeof HTMLVideoElement === 'undefined') {
|
||||
console.warn('Check failed: HTMLVideoElement');
|
||||
}
|
||||
if (typeof ImageData === 'undefined') {
|
||||
console.warn('Check failed: ImageData');
|
||||
}
|
||||
if (typeof CanvasRenderingContext2D === 'undefined') {
|
||||
console.warn('Check failed: CanvasRenderingContext2D');
|
||||
}
|
||||
|
||||
self.window = window;
|
||||
self.document = document;
|
||||
self.HTMLImageElement = HTMLImageElement;
|
||||
self.HTMLVideoElement = HTMLVideoElement;
|
||||
|
||||
// These are the same checks face-api.js/isBrowser does
|
||||
const isBrowserCheck =
|
||||
typeof window === 'object' &&
|
||||
typeof document !== 'undefined' &&
|
||||
typeof HTMLImageElement !== 'undefined' &&
|
||||
typeof HTMLCanvasElement !== 'undefined' &&
|
||||
typeof HTMLVideoElement !== 'undefined' &&
|
||||
typeof ImageData !== 'undefined' &&
|
||||
typeof CanvasRenderingContext2D !== 'undefined';
|
||||
if (!isBrowserCheck) {
|
||||
throw new Error('Failed to monkey patch for face-api, face-api will fail');
|
||||
}
|
|
@ -1,43 +1,59 @@
|
|||
import { File, getLocalFiles } from 'services/fileService';
|
||||
import DownloadManager from 'services/downloadManager';
|
||||
|
||||
import * as tf from '@tensorflow/tfjs';
|
||||
import { setWasmPaths } from '@tensorflow/tfjs-backend-wasm';
|
||||
import * as tf from '@tensorflow/tfjs-core';
|
||||
// import { setWasmPaths } from '@tensorflow/tfjs-backend-wasm';
|
||||
|
||||
import TFJSFaceDetectionService from './tfjsFaceDetectionService';
|
||||
import TFJSFaceEmbeddingService from './tfjsFaceEmbeddingService';
|
||||
import { FaceWithEmbedding, MLSyncResult } from 'utils/machineLearning/types';
|
||||
// import TFJSFaceDetectionService from './tfjsFaceDetectionService';
|
||||
// import TFJSFaceEmbeddingService from './tfjsFaceEmbeddingService';
|
||||
import { FaceImage, MLSyncResult } from 'utils/machineLearning/types';
|
||||
|
||||
import * as jpeg from 'jpeg-js';
|
||||
import ClusteringService from './clusteringService';
|
||||
|
||||
import './faceEnvPatch';
|
||||
import * as faceapi from 'face-api.js';
|
||||
|
||||
class MachineLearningService {
|
||||
private faceDetectionService: TFJSFaceDetectionService;
|
||||
private faceEmbeddingService: TFJSFaceEmbeddingService;
|
||||
// private faceDetectionService: TFJSFaceDetectionService;
|
||||
// private faceEmbeddingService: TFJSFaceEmbeddingService;
|
||||
private clusteringService: ClusteringService;
|
||||
|
||||
private clusterFaceDistance = 0.8;
|
||||
private clusterFaceDistance = 0.5;
|
||||
private minClusterSize = 4;
|
||||
// private minFacePixels = 64;
|
||||
|
||||
public allFaces: FaceWithEmbedding[];
|
||||
public allFaces: faceapi.WithFaceDescriptor<
|
||||
faceapi.WithFaceLandmarks<
|
||||
{
|
||||
detection: faceapi.FaceDetection;
|
||||
},
|
||||
faceapi.FaceLandmarks68
|
||||
>
|
||||
>[];
|
||||
private allFaceImages: FaceImage[];
|
||||
|
||||
public constructor() {
|
||||
this.faceDetectionService = new TFJSFaceDetectionService();
|
||||
this.faceEmbeddingService = new TFJSFaceEmbeddingService();
|
||||
// this.faceDetectionService = new TFJSFaceDetectionService();
|
||||
// this.faceEmbeddingService = new TFJSFaceEmbeddingService();
|
||||
this.clusteringService = new ClusteringService();
|
||||
|
||||
this.allFaces = [];
|
||||
this.allFaceImages = [];
|
||||
}
|
||||
|
||||
public async init(clusterFaceDistance: number, minClusterSize: number) {
|
||||
this.clusterFaceDistance = clusterFaceDistance;
|
||||
this.minClusterSize = minClusterSize;
|
||||
|
||||
setWasmPaths('/js/tfjs/');
|
||||
// setWasmPath('/js/tfjs/');
|
||||
await tf.ready();
|
||||
|
||||
await this.faceDetectionService.init();
|
||||
await this.faceEmbeddingService.init();
|
||||
// await this.faceDetectionService.init();
|
||||
// await this.faceEmbeddingService.init();
|
||||
await faceapi.nets.ssdMobilenetv1.loadFromUri('/models/face-api/');
|
||||
await faceapi.nets.faceLandmark68Net.loadFromUri('/models/face-api/');
|
||||
await faceapi.nets.faceRecognitionNet.loadFromUri('/models/face-api/');
|
||||
}
|
||||
|
||||
private getUniqueFiles(files: File[], limit: number) {
|
||||
|
@ -67,7 +83,10 @@ class MachineLearningService {
|
|||
for (const file of files.values()) {
|
||||
try {
|
||||
const result = await this.syncFile(file, token);
|
||||
this.allFaces = this.allFaces.concat(result);
|
||||
this.allFaces = this.allFaces.concat(result.faceApiResults);
|
||||
this.allFaceImages = this.allFaceImages.concat(
|
||||
result.faceImages
|
||||
);
|
||||
console.log('TF Memory stats: ', tf.memory());
|
||||
} catch (e) {
|
||||
console.error(
|
||||
|
@ -77,18 +96,27 @@ class MachineLearningService {
|
|||
);
|
||||
}
|
||||
}
|
||||
console.log('allFaces: ', this.allFaces);
|
||||
console.log(
|
||||
'allFaces: ',
|
||||
this.allFaces[0].alignedRect,
|
||||
this.allFaces[0].alignedRect.box,
|
||||
this.allFaces[0].alignedRect.imageDims
|
||||
);
|
||||
|
||||
const clusterResults = this.clusteringService.clusterUsingDBSCAN(
|
||||
this.allFaces.map((f) => f.embedding),
|
||||
this.allFaces.map((f) => Array.from(f.descriptor)),
|
||||
this.clusterFaceDistance,
|
||||
this.minClusterSize
|
||||
);
|
||||
|
||||
// const clusterResults = this.clusteringService.clusterUsingKMEANS(
|
||||
// this.allFaces.map((f) => f.embedding),
|
||||
// 10);
|
||||
|
||||
console.log('[MLService] Got cluster results: ', clusterResults);
|
||||
|
||||
return {
|
||||
allFaces: this.allFaces,
|
||||
allFaces: this.allFaceImages,
|
||||
clusterResults,
|
||||
};
|
||||
}
|
||||
|
@ -108,22 +136,64 @@ class MachineLearningService {
|
|||
|
||||
const tfImage = tf.browser.fromPixels(decodedImg);
|
||||
|
||||
const faces = await this.faceDetectionService.estimateFaces(tfImage);
|
||||
const embeddingResults = await this.faceEmbeddingService.getEmbeddings(
|
||||
tfImage,
|
||||
faces
|
||||
);
|
||||
tf.dispose(tfImage);
|
||||
console.log('[MLService] Got faces: ', faces, embeddingResults);
|
||||
// const faces = await this.faceDetectionService.estimateFaces(tfImage);
|
||||
|
||||
return faces.map((face, index) => {
|
||||
return {
|
||||
fileId: file.id.toString(),
|
||||
face: face,
|
||||
embedding: embeddingResults.embeddings[index],
|
||||
faceImage: embeddingResults.faceImages[index],
|
||||
} as FaceWithEmbedding;
|
||||
});
|
||||
// const faceHasMinPixels = (face) => {
|
||||
// return (
|
||||
// face.alignedBox[2] - face.alignedBox[0] > this.minFacePixels //&&
|
||||
// // face.alignedBox[3] - face.alignedBox[1] > this.minFacePixels
|
||||
// );
|
||||
// }
|
||||
// const filtertedFaces = faces.filter(faceHasMinPixels);
|
||||
|
||||
// const embeddingResults = await this.faceEmbeddingService.getEmbeddings(
|
||||
// tfImage,
|
||||
// filtertedFaces
|
||||
// );
|
||||
|
||||
const faceApiInput = tfImage.expandDims(0) as tf.Tensor4D;
|
||||
const results = await faceapi
|
||||
.detectAllFaces(faceApiInput as any)
|
||||
.withFaceLandmarks()
|
||||
.withFaceDescriptors();
|
||||
// const embeddings = results.map(f=>f.descriptor);
|
||||
// console.log('embeddings', embeddings);
|
||||
let faceImages = [];
|
||||
if (results && results.length > 0) {
|
||||
const faceBoxes = results
|
||||
.map((f) => f.alignedRect.relativeBox)
|
||||
.map((b) => [b.top, b.left, b.bottom, b.right]);
|
||||
const normalizedImage = tf.sub(
|
||||
tf.div(faceApiInput, 127.5),
|
||||
1.0
|
||||
) as tf.Tensor4D;
|
||||
const faceImagesTensor = tf.image.cropAndResize(
|
||||
normalizedImage,
|
||||
faceBoxes,
|
||||
tf.fill([faceBoxes.length], 0, 'int32'),
|
||||
[112, 112]
|
||||
);
|
||||
faceImages = await faceImagesTensor.array();
|
||||
// console.log(JSON.stringify(results));
|
||||
}
|
||||
|
||||
tf.dispose(tfImage);
|
||||
|
||||
return {
|
||||
faceApiResults: results,
|
||||
faceImages: faceImages,
|
||||
};
|
||||
|
||||
// console.log('[MLService] Got faces: ', filtertedFaces, embeddingResults);
|
||||
|
||||
// return filtertedFaces.map((face, index) => {
|
||||
// return {
|
||||
// fileId: file.id.toString(),
|
||||
// face: face,
|
||||
// embedding: embeddingResults.embeddings[index],
|
||||
// faceImage: embeddingResults.faceImages[index],
|
||||
// } as FaceWithEmbedding;
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { NormalizedFace } from '@tensorflow-models/blazeface';
|
||||
|
||||
export interface MLSyncResult {
|
||||
allFaces: FaceWithEmbedding[];
|
||||
allFaces: FaceImage[];
|
||||
clusterResults: ClusteringResults;
|
||||
}
|
||||
|
||||
|
|
189
yarn.lock
189
yarn.lock
|
@ -1391,15 +1391,14 @@
|
|||
"@types/seedrandom" "2.4.27"
|
||||
seedrandom "2.4.3"
|
||||
|
||||
"@tensorflow/tfjs-backend-wasm@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-3.11.0.tgz#cd74d124648c16d094aa983180385ef9f21797a5"
|
||||
integrity sha512-49+MSIa/tOelbr4J0Q+ZMuDGQiAaenUsy9exfaQvEo/FzjV+aitVB7r9IojLCxyB4cfAtqKUGHwmRoreJnN7jw==
|
||||
"@tensorflow/tfjs-backend-wasm@^1.7.0":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-backend-wasm/-/tfjs-backend-wasm-1.7.4.tgz#121868bad3b63244ed3fe13c50505c9a1312dc90"
|
||||
integrity sha512-Jejb2NsqysmzXvrNaIoYmTUCErbEV1vc8Wd1DowFlV6UPB2KW0tjNKtIbvubOG9Hu879cgEfN84c3Yx2Oy/WRA==
|
||||
dependencies:
|
||||
"@tensorflow/tfjs-backend-cpu" "3.11.0"
|
||||
"@types/emscripten" "~0.0.34"
|
||||
|
||||
"@tensorflow/tfjs-backend-webgl@3.11.0", "@tensorflow/tfjs-backend-webgl@^3.11.0":
|
||||
"@tensorflow/tfjs-backend-webgl@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-backend-webgl/-/tfjs-backend-webgl-3.11.0.tgz#fbd7f24c164d17c11d964206b4b075b073b1a3bc"
|
||||
integrity sha512-rNnc/dZ7LIl9O/Pn9W24I1h8kgpJ+XvG8NrdNSfIoWPCW4fvPSlU7B3yMeZXvRneny+z+T3xRs96nWyU2mZBJw==
|
||||
|
@ -1411,58 +1410,62 @@
|
|||
"@types/webgl2" "0.0.6"
|
||||
seedrandom "2.4.3"
|
||||
|
||||
"@tensorflow/tfjs-converter@3.11.0", "@tensorflow/tfjs-converter@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-converter/-/tfjs-converter-3.11.0.tgz#0842269a83599b52fd167a8a05372018a9a1ca6a"
|
||||
integrity sha512-rTRIKvBoqL0qdPYpm8UXauZycOiaBHZB2E2v3OoXoHnjvle/Xn/09uZJdrixgGhR+Kahs3Vz27BEEFz6RI5j2w==
|
||||
"@tensorflow/tfjs-converter@1.7.4", "@tensorflow/tfjs-converter@^1.7.0":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-converter/-/tfjs-converter-1.7.4.tgz#90838fe9ca2d540f22a65fdcbe2311a01e786380"
|
||||
integrity sha512-B/Ux9I3osI0CXoESGR0Xe5C6BsEfC04+g2xn5zVaW9KEuVEnGEgnuBQxgijRFzkqTwoyLv4ptAmjyIghVARX0Q==
|
||||
|
||||
"@tensorflow/tfjs-core@3.11.0", "@tensorflow/tfjs-core@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-core/-/tfjs-core-3.11.0.tgz#1e3986533faaed922bbfc2fe86da506d0e9e5c79"
|
||||
integrity sha512-JOp+1+LCd0Xg3hu7fu6iQPWZnN8Hc6ssfP7B+625XH5GYY1/OhVASa7Ahe2mJr9gZovY2lw8FUejLh1jMmBb1Q==
|
||||
"@tensorflow/tfjs-core@1.7.0":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-core/-/tfjs-core-1.7.0.tgz#9207c8f2481c52a6a40135a6aaf21a9bb0339bdf"
|
||||
integrity sha512-uwQdiklNjqBnHPeseOdG0sGxrI3+d6lybaKu2+ou3ajVeKdPEwpWbgqA6iHjq1iylnOGkgkbbnQ6r2lwkiIIHw==
|
||||
dependencies:
|
||||
"@types/long" "^4.0.1"
|
||||
"@types/offscreencanvas" "~2019.3.0"
|
||||
"@types/seedrandom" "2.4.27"
|
||||
"@types/webgl-ext" "0.0.30"
|
||||
long "4.0.0"
|
||||
node-fetch "~2.6.1"
|
||||
"@types/webgl2" "0.0.4"
|
||||
node-fetch "~2.1.2"
|
||||
seedrandom "2.4.3"
|
||||
|
||||
"@tensorflow/tfjs-data@3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-data/-/tfjs-data-3.11.0.tgz#90dd23a7181f0a744f2882a12c3442b27047383d"
|
||||
integrity sha512-+cUHUHzjM/zs0JVOwHQm9wP15Y+BZdRcUpMoYWia8r3kaGSyvoz6WqzacEP1PeXgJVnr2gtU3D+bF32th8fZfQ==
|
||||
"@tensorflow/tfjs-core@1.7.4", "@tensorflow/tfjs-core@^1.7.0":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-core/-/tfjs-core-1.7.4.tgz#43a44bc01d46de98ee9f15c0b2a4d9af4723e7ea"
|
||||
integrity sha512-3G4VKJ6nPs7iCt6gs3bjRj8chihKrYWenf63R0pm7D9MhlrVoX/tpN4LYVMGgBL7jHPxMLKdOkoAZJrn/J88HQ==
|
||||
dependencies:
|
||||
"@types/offscreencanvas" "~2019.3.0"
|
||||
"@types/seedrandom" "2.4.27"
|
||||
"@types/webgl-ext" "0.0.30"
|
||||
"@types/webgl2" "0.0.4"
|
||||
node-fetch "~2.1.2"
|
||||
seedrandom "2.4.3"
|
||||
|
||||
"@tensorflow/tfjs-data@1.7.4":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-data/-/tfjs-data-1.7.4.tgz#3aa1cb14ac48a0354acd21d08f177c8a262fbb32"
|
||||
integrity sha512-WFYG9wWjNDi62x6o3O20Q0XJxToCw2J4/fBEXiK/Gr0hIqVhl2oLQ1OjTWq7O08NUxM6BRzuG+ra3gWYdQUzOw==
|
||||
dependencies:
|
||||
"@types/node-fetch" "^2.1.2"
|
||||
node-fetch "~2.6.1"
|
||||
node-fetch "~2.1.2"
|
||||
|
||||
"@tensorflow/tfjs-layers@3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-layers/-/tfjs-layers-3.11.0.tgz#456d8dc3fe93937ced329d5d06310da294d3758c"
|
||||
integrity sha512-BtLgLucJZHv5te1K3yjT3iZdHXgMJArrLuOb/oRPOtTp4R2ad5N0V2m5RtuZJ3sI5/ah0h72xtmTWNyTv3/5dw==
|
||||
"@tensorflow/tfjs-layers@1.7.4":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-layers/-/tfjs-layers-1.7.4.tgz#93cdef70a4f414edb4ee470c49415d216f54ba20"
|
||||
integrity sha512-5/K8Z8RBfXsucL6EaSeb3/8jB/I8oPaaXkxwKVsBPQ+u6lB6LEtSKzeiFc57nDr5OMtVaUZV+pKDNEzP0RUQlg==
|
||||
|
||||
"@tensorflow/tfjs-tflite@^0.0.1-alpha.7":
|
||||
version "0.0.1-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs-tflite/-/tfjs-tflite-0.0.1-alpha.7.tgz#647c088689131fee424b7ae0bb9b7fdc74a61475"
|
||||
integrity sha512-aOmmEC/AHzfc/u1Q6ccY6Kr7CfNwjonqyTGVU1OqlQGDrH2IopcCjNSZdatJIB6J2RxlBs979JilCOUpK1LXng==
|
||||
|
||||
"@tensorflow/tfjs@^3.11.0":
|
||||
version "3.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs/-/tfjs-3.11.0.tgz#63d5231f41d57ca11b910664632a8e349eba3967"
|
||||
integrity sha512-TTYrKdkoh1sHnt4vn6MboLbpi1Es4U1Aw+L3PqwadRvXW4+7ySUtc00McrQ+ooK0q3Qhl3N7cvgchgM7nED3Mg==
|
||||
"@tensorflow/tfjs@^1.7.0":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@tensorflow/tfjs/-/tfjs-1.7.4.tgz#ea5483bc4b34f5a4c66d600e456c25b6071ea75e"
|
||||
integrity sha512-XWGwRQ/ECEoQacd74JY/dmbLdnMpwtq3H8tls45dQ+GJ553Advir1FDo/aQt0Yr6fTimQDeiOIG4Mcb5KduP/w==
|
||||
dependencies:
|
||||
"@tensorflow/tfjs-backend-cpu" "3.11.0"
|
||||
"@tensorflow/tfjs-backend-webgl" "3.11.0"
|
||||
"@tensorflow/tfjs-converter" "3.11.0"
|
||||
"@tensorflow/tfjs-core" "3.11.0"
|
||||
"@tensorflow/tfjs-data" "3.11.0"
|
||||
"@tensorflow/tfjs-layers" "3.11.0"
|
||||
argparse "^1.0.10"
|
||||
chalk "^4.1.0"
|
||||
core-js "3"
|
||||
regenerator-runtime "^0.13.5"
|
||||
yargs "^16.0.3"
|
||||
"@tensorflow/tfjs-converter" "1.7.4"
|
||||
"@tensorflow/tfjs-core" "1.7.4"
|
||||
"@tensorflow/tfjs-data" "1.7.4"
|
||||
"@tensorflow/tfjs-layers" "1.7.4"
|
||||
|
||||
"@tokenizer/token@^0.3.0":
|
||||
version "0.3.0"
|
||||
|
@ -1532,11 +1535,6 @@
|
|||
resolved "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.9.tgz"
|
||||
integrity sha512-LisgKLlYQk19baQwjkBZZXdJL0KbeTpdEnrAfz5hQACbklCY0gVFnsKUyjfNWF1UQsCSjw93Sj5jSbiO8RPfdw==
|
||||
|
||||
"@types/long@^4.0.1":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz"
|
||||
|
@ -1712,6 +1710,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/webgl-ext/-/webgl-ext-0.0.30.tgz#0ce498c16a41a23d15289e0b844d945b25f0fb9d"
|
||||
integrity sha512-LKVgNmBxN0BbljJrVUwkxwRYqzsAEPcZOe6S2T6ZaBDIrFp0qu4FNlpc5sM1tGbXUYFgdVQIoeLk1Y1UoblyEg==
|
||||
|
||||
"@types/webgl2@0.0.4":
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.4.tgz#c3b0f9d6b465c66138e84e64cb3bdf8373c2c279"
|
||||
integrity sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw==
|
||||
|
||||
"@types/webgl2@0.0.6":
|
||||
version "0.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.6.tgz#1ea2db791362bd8521548d664dbd3c5311cdf4b6"
|
||||
|
@ -1942,7 +1945,7 @@ are-we-there-yet@~1.1.2:
|
|||
delegates "^1.0.0"
|
||||
readable-stream "^2.0.6"
|
||||
|
||||
argparse@^1.0.10, argparse@^1.0.7:
|
||||
argparse@^1.0.7:
|
||||
version "1.0.10"
|
||||
resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz"
|
||||
integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==
|
||||
|
@ -2530,15 +2533,6 @@ cli-truncate@^2.1.0:
|
|||
slice-ansi "^3.0.0"
|
||||
string-width "^4.2.0"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz"
|
||||
|
@ -2684,11 +2678,6 @@ core-js-pure@^3.16.0:
|
|||
resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.17.3.tgz"
|
||||
integrity sha512-YusrqwiOTTn8058JDa0cv9unbXdIiIgcgI9gXso0ey4WgkFLd3lYlV9rp9n7nDCsYxXsMDTjA4m1h3T348mdlQ==
|
||||
|
||||
core-js@3:
|
||||
version "3.19.1"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.1.tgz#f6f173cae23e73a7d88fa23b6e9da329276c6641"
|
||||
integrity sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==
|
||||
|
||||
core-js@^2.4.0:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
|
||||
|
@ -3453,6 +3442,14 @@ express@^4.16.3:
|
|||
utils-merge "1.0.1"
|
||||
vary "~1.1.2"
|
||||
|
||||
face-api.js@^0.22.2:
|
||||
version "0.22.2"
|
||||
resolved "https://registry.yarnpkg.com/face-api.js/-/face-api.js-0.22.2.tgz#5accbf7e53b1569685d116a7e18dbc4800770d39"
|
||||
integrity sha512-9Bbv/yaBRTKCXjiDqzryeKhYxmgSjJ7ukvOvEBy6krA0Ah/vNBlsf7iBNfJljWiPA8Tys1/MnB3lyP2Hfmsuyw==
|
||||
dependencies:
|
||||
"@tensorflow/tfjs-core" "1.7.0"
|
||||
tslib "^1.11.1"
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
|
@ -3666,11 +3663,6 @@ gensync@^1.0.0-beta.2:
|
|||
resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
||||
get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz"
|
||||
|
@ -4594,11 +4586,6 @@ log-update@^4.0.0:
|
|||
slice-ansi "^4.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
long@4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
|
||||
integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz"
|
||||
|
@ -4858,12 +4845,10 @@ node-fetch@^2.6.0, node-fetch@^2.6.1:
|
|||
resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.2.tgz"
|
||||
integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA==
|
||||
|
||||
node-fetch@~2.6.1:
|
||||
version "2.6.6"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
|
||||
integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
|
||||
dependencies:
|
||||
whatwg-url "^5.0.0"
|
||||
node-fetch@~2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5"
|
||||
integrity sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=
|
||||
|
||||
node-forge@^0.10.0:
|
||||
version "0.10.0"
|
||||
|
@ -5748,7 +5733,7 @@ regenerator-runtime@^0.11.0:
|
|||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz"
|
||||
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
||||
|
||||
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.5, regenerator-runtime@^0.13.7:
|
||||
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
|
||||
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
|
||||
|
@ -5797,11 +5782,6 @@ regjsparser@^0.6.4:
|
|||
dependencies:
|
||||
jsesc "~0.5.0"
|
||||
|
||||
require-directory@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
|
||||
require-from-string@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz"
|
||||
|
@ -6586,11 +6566,6 @@ tr46@^1.0.1:
|
|||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
tr46@~0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
|
||||
|
||||
tryer@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz"
|
||||
|
@ -6611,7 +6586,7 @@ tsconfig-paths@^3.11.0:
|
|||
minimist "^1.2.0"
|
||||
strip-bom "^3.0.0"
|
||||
|
||||
tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
tslib@^1.10.0, tslib@^1.11.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
@ -6839,11 +6814,6 @@ watchpack@2.1.1:
|
|||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
|
||||
webidl-conversions@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
|
||||
integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz"
|
||||
|
@ -6876,14 +6846,6 @@ webpack-sources@^1.3.0:
|
|||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
whatwg-url@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
|
||||
integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
|
||||
dependencies:
|
||||
tr46 "~0.0.3"
|
||||
webidl-conversions "^3.0.0"
|
||||
|
||||
whatwg-url@^7.0.0:
|
||||
version "7.1.0"
|
||||
resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz"
|
||||
|
@ -7193,11 +7155,6 @@ xtend@^4.0.0, xtend@^4.0.2:
|
|||
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.8"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
|
||||
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"
|
||||
|
@ -7208,24 +7165,6 @@ yaml@^1.10.0:
|
|||
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs@^16.0.3:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"
|
||||
|
|
Loading…
Reference in a new issue