Testing with face face-api.js

This commit is contained in:
Shailesh Pandit 2021-11-05 20:56:41 +05:30
parent 41aad5e205
commit 6fb22e429c
24 changed files with 428 additions and 166 deletions

View file

@ -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",

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -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"]}]

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View 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]}]}]

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View file

@ -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"]}]

View file

@ -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>
))}

View 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');
}

View file

@ -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;
// });
}
}

View file

@ -1,7 +1,7 @@
import { NormalizedFace } from '@tensorflow-models/blazeface';
export interface MLSyncResult {
allFaces: FaceWithEmbedding[];
allFaces: FaceImage[];
clusterResults: ClusteringResults;
}

189
yarn.lock
View file

@ -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"