@naniteninja/profile-comparison-lib 0.0.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/index.d.ts
ADDED
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnInit, AfterViewInit, OnChanges, EventEmitter, ElementRef, Renderer2, SimpleChanges } from '@angular/core';
|
|
3
|
+
import * as i3 from '@angular/common/http';
|
|
4
|
+
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
|
|
5
|
+
import { Observable } from 'rxjs';
|
|
6
|
+
import * as i4 from '@angular/forms';
|
|
7
|
+
import { FormGroup, FormControl } from '@angular/forms';
|
|
8
|
+
import * as i2 from '@angular/common';
|
|
9
|
+
import * as i7 from '@angular/router';
|
|
10
|
+
import { Router } from '@angular/router';
|
|
11
|
+
|
|
12
|
+
interface IProfileConfig {
|
|
13
|
+
person1Interests: string[];
|
|
14
|
+
person2Interests: string[];
|
|
15
|
+
person3Interests: string[];
|
|
16
|
+
user1Image: string;
|
|
17
|
+
user2Image: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface IBoundingBox {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface IPoint {
|
|
28
|
+
x: number;
|
|
29
|
+
y: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface IFaceLandmarks {
|
|
33
|
+
[name: string]: IPoint | undefined;
|
|
34
|
+
}
|
|
35
|
+
interface IFaceBoxWithLandmarks extends IBoundingBox {
|
|
36
|
+
landmarks?: IFaceLandmarks;
|
|
37
|
+
}
|
|
38
|
+
interface IFaceDetectionResult {
|
|
39
|
+
imageUrl: string;
|
|
40
|
+
faces: IFaceBoxWithLandmarks[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface IWordAlignment {
|
|
44
|
+
word: string;
|
|
45
|
+
alignedWith: string | null;
|
|
46
|
+
score: number;
|
|
47
|
+
index: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface IWordPair {
|
|
51
|
+
wordA: string;
|
|
52
|
+
wordB: string;
|
|
53
|
+
score: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface ISimilarityThreshold {
|
|
57
|
+
threshold: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface IAlignmentRow {
|
|
61
|
+
left: string;
|
|
62
|
+
right: string;
|
|
63
|
+
score: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface FileInputEvent {
|
|
67
|
+
target: HTMLInputElement & EventTarget;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface FaceDetectionResponse {
|
|
71
|
+
faces?: IFaceBoxWithLandmarks[];
|
|
72
|
+
data?: {
|
|
73
|
+
faces?: IFaceBoxWithLandmarks[];
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
interface FaceDetectionData {
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface IImageCompressionConfig$1 {
|
|
80
|
+
maxWidth: number;
|
|
81
|
+
maxHeight: number;
|
|
82
|
+
format: 'image/jpeg' | 'image/png' | 'image/webp';
|
|
83
|
+
qualityStart: number;
|
|
84
|
+
qualityMin: number;
|
|
85
|
+
qualityStep: number;
|
|
86
|
+
maxBytes: number;
|
|
87
|
+
downscaleStep: number;
|
|
88
|
+
minWidth: number;
|
|
89
|
+
minHeight: number;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface IComparisonResult {
|
|
93
|
+
similarity: number;
|
|
94
|
+
differences: string[];
|
|
95
|
+
timestamp: Date;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
interface ISimilarityResponse {
|
|
99
|
+
similarity: number;
|
|
100
|
+
[key: string]: unknown;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
interface IFacePlusPlusFace {
|
|
104
|
+
face_rectangle?: IFaceRectangle;
|
|
105
|
+
faceRect?: IFaceRectangle;
|
|
106
|
+
rect?: IFaceRectangle;
|
|
107
|
+
landmark?: Record<string, {
|
|
108
|
+
x: number;
|
|
109
|
+
y: number;
|
|
110
|
+
}>;
|
|
111
|
+
[key: string]: unknown;
|
|
112
|
+
}
|
|
113
|
+
interface IFaceRectangle {
|
|
114
|
+
left: number;
|
|
115
|
+
top: number;
|
|
116
|
+
width: number;
|
|
117
|
+
height: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface IFacePlusPlusResponse {
|
|
121
|
+
faces?: IFacePlusPlusFace[];
|
|
122
|
+
error_message?: string;
|
|
123
|
+
[key: string]: unknown;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface IOpenAIResponse {
|
|
127
|
+
choices: Array<{
|
|
128
|
+
message: {
|
|
129
|
+
content: string;
|
|
130
|
+
};
|
|
131
|
+
}>;
|
|
132
|
+
data?: Array<{
|
|
133
|
+
embedding: number[];
|
|
134
|
+
[key: string]: unknown;
|
|
135
|
+
}>;
|
|
136
|
+
[key: string]: unknown;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface IOpenAIEmbeddingItem {
|
|
140
|
+
embedding: number[];
|
|
141
|
+
[key: string]: unknown;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
interface IEnvironment {
|
|
145
|
+
production: boolean;
|
|
146
|
+
apiNinjasKey: string;
|
|
147
|
+
openaiApiKey: string;
|
|
148
|
+
apiFaceplusKey?: string;
|
|
149
|
+
apiFaceplusSecret?: string;
|
|
150
|
+
[key: string]: unknown;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
interface IMatrixLegendItem {
|
|
154
|
+
abbr: string;
|
|
155
|
+
full: string;
|
|
156
|
+
}
|
|
157
|
+
interface IMatrixRow {
|
|
158
|
+
label: string;
|
|
159
|
+
values: string[];
|
|
160
|
+
}
|
|
161
|
+
interface IMatrixData {
|
|
162
|
+
legend: IMatrixLegendItem[];
|
|
163
|
+
headers: string[];
|
|
164
|
+
rows: IMatrixRow[];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
declare class EmbeddingService {
|
|
168
|
+
private model$;
|
|
169
|
+
getEmbedding(text: string): Observable<Float32Array>;
|
|
170
|
+
/**
|
|
171
|
+
* Group-align two lists based on semantic similarity, allowing one-to-many relationships.
|
|
172
|
+
*
|
|
173
|
+
* Design goals:
|
|
174
|
+
* - Semantic relevance takes priority over original order or spacing.
|
|
175
|
+
* - Each term in listB is assigned to the single most similar anchor in listA (if above threshold).
|
|
176
|
+
* - For an anchor in listA with multiple highly related listB terms, they are emitted as consecutive rows:
|
|
177
|
+
* [A, B1], ['-', B2], ['-', B3], ... so they render adjacently and remain visually connected.
|
|
178
|
+
* - Low-similarity/unassigned terms from either side are appended at the end and never break groups.
|
|
179
|
+
*/
|
|
180
|
+
groupAlignLists(listA: string[], listB: string[], threshold?: number, preserveLeftOrder?: boolean, exclusivityMargin?: number, leftCohesion?: number): Observable<IAlignmentRow[]>;
|
|
181
|
+
cosineSimilarity(a: Float32Array, b: Float32Array): number;
|
|
182
|
+
/**
|
|
183
|
+
* Align words in listA with their most semantically similar words in listB
|
|
184
|
+
*
|
|
185
|
+
* Algorithm:
|
|
186
|
+
* 1. Generate embeddings for all words in both lists using Universal Sentence Encoder
|
|
187
|
+
* 2. For each word in listA, compare its embedding with all words in listB
|
|
188
|
+
* 3. Find the word in listB with highest cosine similarity score
|
|
189
|
+
* 4. Return alignment results with similarity scores
|
|
190
|
+
*
|
|
191
|
+
* @param listA - Source list of words to align
|
|
192
|
+
* @param listB - Target list of words to find matches in
|
|
193
|
+
* @returns Observable of alignment results with word, alignedWith, score, and index
|
|
194
|
+
*/
|
|
195
|
+
alignLists(listA: string[], listB: string[]): Observable<IWordAlignment[]>;
|
|
196
|
+
/**
|
|
197
|
+
* Find best matching pairs between two lists above a similarity threshold
|
|
198
|
+
*
|
|
199
|
+
* @param listA - Source list of words
|
|
200
|
+
* @param listB - Target list of words to match against
|
|
201
|
+
* @param threshold - Minimum similarity score (0-1, default: 0.15)
|
|
202
|
+
* @returns Observable of word pairs with similarity scores
|
|
203
|
+
*/
|
|
204
|
+
findBestMatchingPairs(listA: string[], listB: string[], threshold?: number): Observable<IWordPair[]>;
|
|
205
|
+
calculateSimilarity(primaryText: string, comparisonText: string): Observable<number>;
|
|
206
|
+
testWordSimilarity(word1: string, word2: string): Observable<void>;
|
|
207
|
+
private domainCompatibilityCap;
|
|
208
|
+
private computeLexicalBoost;
|
|
209
|
+
private loadModel;
|
|
210
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EmbeddingService, never>;
|
|
211
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<EmbeddingService>;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
declare class FileConversionService {
|
|
215
|
+
private static readonly MIME_TYPE_JPEG;
|
|
216
|
+
private static readonly MIME_TYPE_PNG;
|
|
217
|
+
private static readonly MIME_TYPE_WEBP;
|
|
218
|
+
private static readonly FILE_EXTENSION_JPG;
|
|
219
|
+
private static readonly FILE_EXTENSION_JPEG;
|
|
220
|
+
private static readonly FILE_EXTENSION_PNG;
|
|
221
|
+
private static readonly FILE_EXTENSION_WEBP;
|
|
222
|
+
urlToFile(url: string, fileName: string, mimeType: string): Observable<File>;
|
|
223
|
+
isDataUrl(str: string): boolean;
|
|
224
|
+
dataUrlToFile(dataUrl: string, fileName: string): File;
|
|
225
|
+
getMimeFromFilename(fileName: string): string;
|
|
226
|
+
getFileForImageString(imageStr: string, fileBaseName: string): Observable<File>;
|
|
227
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FileConversionService, never>;
|
|
228
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<FileConversionService>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
declare class ImageCompressionService {
|
|
232
|
+
compressImageFile(file: File, config: IImageCompressionConfig$1, overrides?: Partial<IImageCompressionConfig$1>): Observable<{
|
|
233
|
+
file: File;
|
|
234
|
+
dataUrl: string;
|
|
235
|
+
}>;
|
|
236
|
+
loadImageFromFile(file: File): Observable<HTMLImageElement>;
|
|
237
|
+
canvasToBlob(canvas: HTMLCanvasElement, type: string, quality: number): Observable<Blob>;
|
|
238
|
+
blobToDataURL(blob: Blob): Observable<string>;
|
|
239
|
+
renameFileForFormat(name: string, mime: string): string;
|
|
240
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ImageCompressionService, never>;
|
|
241
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ImageCompressionService>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* OpenAI Alignment Service
|
|
246
|
+
* Uses OpenAI Chat Completions API to align two lists of text in a single request.
|
|
247
|
+
* This replaces the previous embedding-based approach to avoid rate limits and reduce complexity.
|
|
248
|
+
*/
|
|
249
|
+
declare class OpenAIEmbeddingService {
|
|
250
|
+
private http;
|
|
251
|
+
private static readonly API_URL;
|
|
252
|
+
private static readonly MODEL;
|
|
253
|
+
private static readonly HEADER_CONTENT_TYPE;
|
|
254
|
+
private static readonly HEADER_AUTHORIZATION;
|
|
255
|
+
private static readonly CONTENT_TYPE_JSON;
|
|
256
|
+
private static readonly BEARER_PREFIX;
|
|
257
|
+
private static readonly SPACER_SMALL;
|
|
258
|
+
private static readonly SPACER_LARGE;
|
|
259
|
+
private readonly API_URL;
|
|
260
|
+
private readonly MODEL;
|
|
261
|
+
private alignmentCache;
|
|
262
|
+
private spacerAlignmentCache;
|
|
263
|
+
constructor(http: HttpClient);
|
|
264
|
+
/**
|
|
265
|
+
* Get aligned lists with spacers.
|
|
266
|
+
* Now uses a direct LLM call with a specific prompt to generate the aligned lists.
|
|
267
|
+
*/
|
|
268
|
+
getAlignedLists(listA: string[], listB: string[], apiKey: string): Observable<{
|
|
269
|
+
listA: string[];
|
|
270
|
+
listB: string[];
|
|
271
|
+
}>;
|
|
272
|
+
private sanitizeResponse;
|
|
273
|
+
/**
|
|
274
|
+
* Get alignment between two lists using a single OpenAI Chat Completion request.
|
|
275
|
+
* Uses canonical caching to ensure A->B and B->A use the same API response.
|
|
276
|
+
*/
|
|
277
|
+
groupAlignLists(listA: string[], listB: string[], threshold: number | undefined, preserveLeftOrder: boolean | undefined, exclusivityMargin: number | undefined, leftCohesion: number | undefined, apiKey: string): Observable<IAlignmentRow[]>;
|
|
278
|
+
/**
|
|
279
|
+
* Calculate semantic similarity between two texts using OpenAI Embeddings API.
|
|
280
|
+
* Returns a cosine similarity score in [0, 1] (0 for empty/invalid inputs).
|
|
281
|
+
*/
|
|
282
|
+
calculateSimilarity(textA: string, textB: string, apiKey: string): Observable<number>;
|
|
283
|
+
/**
|
|
284
|
+
* Fetch embeddings for multiple texts in a single request.
|
|
285
|
+
*/
|
|
286
|
+
getEmbeddings(texts: string[], apiKey: string): Observable<number[][]>;
|
|
287
|
+
private cosineSimilarityVectors;
|
|
288
|
+
clearCache(): void;
|
|
289
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<OpenAIEmbeddingService, never>;
|
|
290
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<OpenAIEmbeddingService>;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
declare class ProfileComparisonLibService {
|
|
294
|
+
constructor();
|
|
295
|
+
/**
|
|
296
|
+
* Main service for profile comparison functionality
|
|
297
|
+
*/
|
|
298
|
+
compareProfiles(profile1: IProfileConfig, profile2: IProfileConfig): IComparisonResult;
|
|
299
|
+
/**
|
|
300
|
+
* Get library version
|
|
301
|
+
*/
|
|
302
|
+
getVersion(): string;
|
|
303
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProfileComparisonLibService, never>;
|
|
304
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ProfileComparisonLibService>;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
declare class ProfileService {
|
|
308
|
+
private http;
|
|
309
|
+
private static readonly BASE_URL;
|
|
310
|
+
private static readonly FACE_PLUS_PLUS_URL;
|
|
311
|
+
private baseUrl;
|
|
312
|
+
private baseUrlf;
|
|
313
|
+
constructor(http: HttpClient);
|
|
314
|
+
compareInterests(text_1: string, text_2: string, apiKey: string): Observable<ISimilarityResponse>;
|
|
315
|
+
detectFace(image: File | string, creds?: {
|
|
316
|
+
apiKey?: string;
|
|
317
|
+
apiSecret?: string;
|
|
318
|
+
}): Observable<IFaceDetectionResult>;
|
|
319
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProfileService, never>;
|
|
320
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<ProfileService>;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
declare class ProfileComparisonLibComponent implements OnInit, AfterViewInit, OnChanges {
|
|
324
|
+
private profileService;
|
|
325
|
+
private openaiEmbeddingService;
|
|
326
|
+
private renderer;
|
|
327
|
+
private fileConversionService;
|
|
328
|
+
private imageCompressionService;
|
|
329
|
+
private static readonly DEFAULT_OBJECT_POSITION;
|
|
330
|
+
private static readonly DEFAULT_EYE_ALIGNMENT_BIAS_PX;
|
|
331
|
+
private static readonly DEFAULT_IMAGE_FORMAT;
|
|
332
|
+
private static readonly DEFAULT_IMAGE_QUALITY_START;
|
|
333
|
+
private static readonly DEFAULT_IMAGE_QUALITY_MIN;
|
|
334
|
+
private static readonly DEFAULT_IMAGE_QUALITY_STEP;
|
|
335
|
+
private static readonly DEFAULT_MAX_BYTES;
|
|
336
|
+
private static readonly DEFAULT_DOWNSCALE_STEP;
|
|
337
|
+
private static readonly DEFAULT_MIN_WIDTH;
|
|
338
|
+
private static readonly DEFAULT_MIN_HEIGHT;
|
|
339
|
+
private static readonly DEFAULT_MAX_WIDTH;
|
|
340
|
+
private static readonly DEFAULT_MAX_HEIGHT;
|
|
341
|
+
private static readonly SPACER_SMALL;
|
|
342
|
+
private static readonly SPACER_LARGE;
|
|
343
|
+
private static readonly CONSOLIDATION_SEPARATOR_X;
|
|
344
|
+
private static readonly CONSOLIDATION_SEPARATOR_SLASH;
|
|
345
|
+
private static readonly FACEPP_RATE_LIMIT_DELAY_MS;
|
|
346
|
+
private static readonly DEFAULT_PROFILE_IMAGE_NAME;
|
|
347
|
+
config: IProfileConfig;
|
|
348
|
+
apiNinjasKey: string;
|
|
349
|
+
faceplusKey: string;
|
|
350
|
+
faceplusSecret: string;
|
|
351
|
+
openaiApiKey: string;
|
|
352
|
+
fadeAllEdges: boolean;
|
|
353
|
+
matrixDataChange: EventEmitter<IMatrixData>;
|
|
354
|
+
selectedFile: File | null;
|
|
355
|
+
result: unknown;
|
|
356
|
+
firstImageData: FaceDetectionData | null;
|
|
357
|
+
secondImageData: FaceDetectionData | null;
|
|
358
|
+
user1Transform: string;
|
|
359
|
+
user2Transform: string;
|
|
360
|
+
alignmentCalculated: boolean;
|
|
361
|
+
isAligning: boolean;
|
|
362
|
+
user1ObjectPosition: string;
|
|
363
|
+
user2ObjectPosition: string;
|
|
364
|
+
private user1NaturalWidth;
|
|
365
|
+
private user1NaturalHeight;
|
|
366
|
+
private user2NaturalWidth;
|
|
367
|
+
private user2NaturalHeight;
|
|
368
|
+
private user1FaceRaw;
|
|
369
|
+
private user2FaceRaw;
|
|
370
|
+
private eyeAlignmentBiasPx;
|
|
371
|
+
firstPersonInterests: string[];
|
|
372
|
+
secondPersonInterests: string[];
|
|
373
|
+
thirdPersonInterests: string[];
|
|
374
|
+
centerItem: string[];
|
|
375
|
+
person1Interests: string[];
|
|
376
|
+
person2Interests: string[];
|
|
377
|
+
person3Interests: string[];
|
|
378
|
+
user1Image: string;
|
|
379
|
+
user2Image: string;
|
|
380
|
+
private baseConfig;
|
|
381
|
+
displayPerson1Interests: string[];
|
|
382
|
+
displayPerson2Interests: string[];
|
|
383
|
+
alignedPerson1Interests: string[];
|
|
384
|
+
alignedPerson2Interests: string[];
|
|
385
|
+
leftProfileClicked: boolean;
|
|
386
|
+
rightProfileClicked: boolean;
|
|
387
|
+
sortedA: {
|
|
388
|
+
item: string;
|
|
389
|
+
score: number;
|
|
390
|
+
}[];
|
|
391
|
+
sortedB: {
|
|
392
|
+
item: string;
|
|
393
|
+
score: number;
|
|
394
|
+
}[];
|
|
395
|
+
sortedC: {
|
|
396
|
+
item: string;
|
|
397
|
+
score: number;
|
|
398
|
+
}[];
|
|
399
|
+
similarity: number;
|
|
400
|
+
similarityMatrixCsv: string;
|
|
401
|
+
matrixData: IMatrixData | null;
|
|
402
|
+
customApiKey: string;
|
|
403
|
+
showApiKeyModal: boolean;
|
|
404
|
+
apiKeyInputValue: string;
|
|
405
|
+
quotaExhausted: boolean;
|
|
406
|
+
customFaceppKey: string;
|
|
407
|
+
customFaceppSecret: string;
|
|
408
|
+
showFaceppKeyModal: boolean;
|
|
409
|
+
faceppKeyInputValue: string;
|
|
410
|
+
faceppSecretInputValue: string;
|
|
411
|
+
faceppQuotaExhausted: boolean;
|
|
412
|
+
customOpenAIKey: string;
|
|
413
|
+
showOpenAIKeyModal: boolean;
|
|
414
|
+
openaiKeyInputValue: string;
|
|
415
|
+
openaiQuotaExhausted: boolean;
|
|
416
|
+
compressionConfig: IImageCompressionConfig$1;
|
|
417
|
+
private computeSub?;
|
|
418
|
+
private detectFaceSub1?;
|
|
419
|
+
private detectFaceSub2?;
|
|
420
|
+
private activeRequestEpoch;
|
|
421
|
+
form: FormGroup<{
|
|
422
|
+
interest1: FormControl<string | null>;
|
|
423
|
+
interest2: FormControl<string | null>;
|
|
424
|
+
}>;
|
|
425
|
+
leftContainer: ElementRef;
|
|
426
|
+
rightContainer: ElementRef;
|
|
427
|
+
constructor(profileService: ProfileService, openaiEmbeddingService: OpenAIEmbeddingService, renderer: Renderer2, fileConversionService: FileConversionService, imageCompressionService: ImageCompressionService);
|
|
428
|
+
anchorSide: 'left' | 'right';
|
|
429
|
+
ngOnInit(): void;
|
|
430
|
+
ngAfterViewInit(): void;
|
|
431
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
432
|
+
private updateConfigProperties;
|
|
433
|
+
private buildConfigWithDefaults;
|
|
434
|
+
onUserImageLoad(which: 1 | 2, event: Event): void;
|
|
435
|
+
private updateObjectPositionForFace;
|
|
436
|
+
private getProfileContainerSize;
|
|
437
|
+
private getOverlapSizeCssPx;
|
|
438
|
+
private setOverlapSizeCssPx;
|
|
439
|
+
waitForImagesAndInitDrag(): void;
|
|
440
|
+
initDrag(): void;
|
|
441
|
+
compute(): void;
|
|
442
|
+
createSemanticAlignment(person1Results: {
|
|
443
|
+
item: string;
|
|
444
|
+
score: number;
|
|
445
|
+
}[], person2Results: {
|
|
446
|
+
item: string;
|
|
447
|
+
score: number;
|
|
448
|
+
}[]): Promise<void>;
|
|
449
|
+
createEmbeddingBasedAlignment(person1Results: {
|
|
450
|
+
item: string;
|
|
451
|
+
score: number;
|
|
452
|
+
}[], person2Results: {
|
|
453
|
+
item: string;
|
|
454
|
+
score: number;
|
|
455
|
+
}[]): Promise<void>;
|
|
456
|
+
sortByMaxSimilarity(personList: string[], otherLists: string[][]): Observable<{
|
|
457
|
+
item: string;
|
|
458
|
+
score: number;
|
|
459
|
+
}[]>;
|
|
460
|
+
onViewProfile(): void;
|
|
461
|
+
getActiveApiKey(): string;
|
|
462
|
+
updateApiKey(): void;
|
|
463
|
+
closeApiKeyModal(): void;
|
|
464
|
+
handleApiQuotaError(error: HttpErrorResponse | {
|
|
465
|
+
status?: number;
|
|
466
|
+
error?: {
|
|
467
|
+
message?: string;
|
|
468
|
+
};
|
|
469
|
+
}): void;
|
|
470
|
+
private saveApiKeyToStorage;
|
|
471
|
+
private loadApiKeyFromStorage;
|
|
472
|
+
onFileInputChange(event: FileInputEvent): void;
|
|
473
|
+
private compressConfigImagesIfNeeded;
|
|
474
|
+
private compressImageStringToDataUrl;
|
|
475
|
+
private loadCustomConfig;
|
|
476
|
+
getEyeCoordinatesFromBBox(bbox: IBoundingBox): {
|
|
477
|
+
leftEye: IPoint;
|
|
478
|
+
rightEye: IPoint;
|
|
479
|
+
};
|
|
480
|
+
getEyeCoordinatesFromFace(face: IFaceBoxWithLandmarks): {
|
|
481
|
+
leftEye: IPoint;
|
|
482
|
+
rightEye: IPoint;
|
|
483
|
+
};
|
|
484
|
+
getNoseCoordinateFromFace(face: IFaceBoxWithLandmarks): IPoint;
|
|
485
|
+
private clampPointToFaceRect;
|
|
486
|
+
getNoseCoordinateFromBBox(bbox: IBoundingBox): IPoint;
|
|
487
|
+
getFaceCoordinatesFromBBox(bbox: IBoundingBox): {
|
|
488
|
+
faceCenter: IPoint;
|
|
489
|
+
faceTop: IPoint;
|
|
490
|
+
faceBottom: IPoint;
|
|
491
|
+
faceLeft: IPoint;
|
|
492
|
+
faceRight: IPoint;
|
|
493
|
+
};
|
|
494
|
+
initializeFaceDetection(): void;
|
|
495
|
+
calculateFaceAlignment(user1Data: FaceDetectionData, user2Data: FaceDetectionData): void;
|
|
496
|
+
applyDefaultAlignment(): void;
|
|
497
|
+
isValidFaceData(face: IBoundingBox): boolean;
|
|
498
|
+
getActiveFaceppKey(): string;
|
|
499
|
+
getActiveFaceppSecret(): string;
|
|
500
|
+
updateFaceppCredentials(): void;
|
|
501
|
+
closeFaceppKeyModal(): void;
|
|
502
|
+
handleFaceppError(error: HttpErrorResponse | {
|
|
503
|
+
status?: number;
|
|
504
|
+
error?: {
|
|
505
|
+
message?: string;
|
|
506
|
+
};
|
|
507
|
+
}): void;
|
|
508
|
+
private saveFaceppCredsToStorage;
|
|
509
|
+
private loadFaceppCredsFromStorage;
|
|
510
|
+
private getActiveOpenAIKey;
|
|
511
|
+
updateOpenAIKey(): void;
|
|
512
|
+
closeOpenAIKeyModal(): void;
|
|
513
|
+
private saveOpenAIKeyToStorage;
|
|
514
|
+
private loadOpenAIKeyFromStorage;
|
|
515
|
+
private generateSimilarityMatrix;
|
|
516
|
+
private cosineSimilarity;
|
|
517
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProfileComparisonLibComponent, never>;
|
|
518
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ProfileComparisonLibComponent, "lib-profile-comparison", never, { "config": { "alias": "config"; "required": false; }; "apiNinjasKey": { "alias": "apiNinjasKey"; "required": false; }; "faceplusKey": { "alias": "faceplusKey"; "required": false; }; "faceplusSecret": { "alias": "faceplusSecret"; "required": false; }; "openaiApiKey": { "alias": "openaiApiKey"; "required": false; }; "fadeAllEdges": { "alias": "fadeAllEdges"; "required": false; }; }, { "matrixDataChange": "matrixDataChange"; }, never, never, false, never>;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
interface IImageCompressionConfig {
|
|
522
|
+
maxWidth: number;
|
|
523
|
+
maxHeight: number;
|
|
524
|
+
format: 'image/jpeg' | 'image/png' | 'image/webp';
|
|
525
|
+
qualityStart: number;
|
|
526
|
+
qualityMin: number;
|
|
527
|
+
qualityStep: number;
|
|
528
|
+
maxBytes: number;
|
|
529
|
+
downscaleStep: number;
|
|
530
|
+
minWidth: number;
|
|
531
|
+
minHeight: number;
|
|
532
|
+
}
|
|
533
|
+
declare class CustomInputComponent {
|
|
534
|
+
private router;
|
|
535
|
+
person1Text: string;
|
|
536
|
+
person2Text: string;
|
|
537
|
+
person3Text: string;
|
|
538
|
+
user1File: File | null;
|
|
539
|
+
user2File: File | null;
|
|
540
|
+
user1Preview: string | null;
|
|
541
|
+
user2Preview: string | null;
|
|
542
|
+
saving: boolean;
|
|
543
|
+
error: string | null;
|
|
544
|
+
private static readonly MAX_WIDTH;
|
|
545
|
+
private static readonly MAX_HEIGHT;
|
|
546
|
+
private static readonly COMPRESSION_FORMAT;
|
|
547
|
+
private static readonly QUALITY_START;
|
|
548
|
+
private static readonly QUALITY_MIN;
|
|
549
|
+
private static readonly QUALITY_STEP;
|
|
550
|
+
private static readonly MAX_BYTES;
|
|
551
|
+
private static readonly DOWNSCALE_STEP;
|
|
552
|
+
private static readonly MIN_WIDTH;
|
|
553
|
+
private static readonly MIN_HEIGHT;
|
|
554
|
+
compressionConfig: IImageCompressionConfig;
|
|
555
|
+
constructor(router: Router);
|
|
556
|
+
onUser1FileChange(event: Event): Promise<void>;
|
|
557
|
+
onUser2FileChange(event: Event): Promise<void>;
|
|
558
|
+
saveAndView(): Promise<void>;
|
|
559
|
+
clearAll(): void;
|
|
560
|
+
close(): void;
|
|
561
|
+
private toList;
|
|
562
|
+
private fileToDataURL;
|
|
563
|
+
private previewFile;
|
|
564
|
+
private compressImageFile;
|
|
565
|
+
private loadImageFromFile;
|
|
566
|
+
private canvasToBlob;
|
|
567
|
+
private blobToDataURL;
|
|
568
|
+
private renameFileForFormat;
|
|
569
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CustomInputComponent, never>;
|
|
570
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CustomInputComponent, "lib-custom-input", never, {}, {}, never, never, true, never>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
declare class DocumentationComponent implements OnInit {
|
|
574
|
+
private openaiEmbeddingService;
|
|
575
|
+
private profileService;
|
|
576
|
+
private router;
|
|
577
|
+
apiKeyInput: string;
|
|
578
|
+
textA: string;
|
|
579
|
+
textB: string;
|
|
580
|
+
embeddingScore: number | null;
|
|
581
|
+
embeddingLoading: boolean;
|
|
582
|
+
embeddingError: string | null;
|
|
583
|
+
listAInput: string;
|
|
584
|
+
listBInput: string;
|
|
585
|
+
matchingPairs: Array<{
|
|
586
|
+
wordA: string;
|
|
587
|
+
wordB: string;
|
|
588
|
+
score: number;
|
|
589
|
+
}>;
|
|
590
|
+
pairsLoading: boolean;
|
|
591
|
+
pairsError: string | null;
|
|
592
|
+
faceFile: File | null;
|
|
593
|
+
faceResult: unknown;
|
|
594
|
+
faceLoading: boolean;
|
|
595
|
+
faceError: string | null;
|
|
596
|
+
compareA: string;
|
|
597
|
+
compareB: string;
|
|
598
|
+
apiSimilarity: number | null;
|
|
599
|
+
apiLoading: boolean;
|
|
600
|
+
apiError: string | null;
|
|
601
|
+
openaiKeyInput: string;
|
|
602
|
+
defaultApiNinjasKey: string;
|
|
603
|
+
defaultOpenaiApiKey: string;
|
|
604
|
+
constructor(openaiEmbeddingService: OpenAIEmbeddingService, profileService: ProfileService, router: Router);
|
|
605
|
+
ngOnInit(): void;
|
|
606
|
+
getActiveApiKey(): string;
|
|
607
|
+
saveKey(): void;
|
|
608
|
+
getStoredKey(): string | null;
|
|
609
|
+
getActiveOpenAIKey(): string;
|
|
610
|
+
saveOpenAIKey(): void;
|
|
611
|
+
runEmbeddingSimilarity(): void;
|
|
612
|
+
runBestPairs(): void;
|
|
613
|
+
onFaceFileChange(event: Event): void;
|
|
614
|
+
runFaceDetect(): void;
|
|
615
|
+
runApiSimilarity(): void;
|
|
616
|
+
similarityLabel(): string;
|
|
617
|
+
apiSimilarityLabel(): string;
|
|
618
|
+
pairLabel(p: {
|
|
619
|
+
wordA: string;
|
|
620
|
+
wordB: string;
|
|
621
|
+
score: number;
|
|
622
|
+
}): string;
|
|
623
|
+
faceResultJson(): string;
|
|
624
|
+
private formatNumber;
|
|
625
|
+
goHome(event: Event): void;
|
|
626
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DocumentationComponent, never>;
|
|
627
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DocumentationComponent, "lib-documentation", never, { "defaultApiNinjasKey": { "alias": "defaultApiNinjasKey"; "required": false; }; "defaultOpenaiApiKey": { "alias": "defaultOpenaiApiKey"; "required": false; }; }, {}, never, never, true, never>;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
declare class ProfileComparisonLibModule {
|
|
631
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ProfileComparisonLibModule, never>;
|
|
632
|
+
static ɵmod: i0.ɵɵNgModuleDeclaration<ProfileComparisonLibModule, [typeof ProfileComparisonLibComponent], [typeof i2.CommonModule, typeof i3.HttpClientModule, typeof i4.FormsModule, typeof i4.ReactiveFormsModule, typeof CustomInputComponent, typeof DocumentationComponent, typeof i7.RouterModule], [typeof ProfileComparisonLibComponent, typeof CustomInputComponent, typeof DocumentationComponent]>;
|
|
633
|
+
static ɵinj: i0.ɵɵInjectorDeclaration<ProfileComparisonLibModule>;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export { CustomInputComponent, DocumentationComponent, EmbeddingService, FileConversionService, ImageCompressionService, OpenAIEmbeddingService, ProfileComparisonLibComponent, ProfileComparisonLibModule, ProfileComparisonLibService, ProfileService };
|
|
637
|
+
export type { FaceDetectionData, FaceDetectionResponse, FileInputEvent, IAlignmentRow, IBoundingBox, IComparisonResult, IEnvironment, IFaceBoxWithLandmarks, IFaceDetectionResult, IFaceLandmarks, IFacePlusPlusFace, IFacePlusPlusResponse, IFaceRectangle, IImageCompressionConfig$1 as IImageCompressionConfig, IMatrixData, IMatrixLegendItem, IMatrixRow, IOpenAIEmbeddingItem, IOpenAIResponse, IPoint, IProfileConfig, ISimilarityResponse, ISimilarityThreshold, IWordAlignment, IWordPair };
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@naniteninja/profile-comparison-lib",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Angular library for profile comparison functionality",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"angular",
|
|
7
|
+
"profile",
|
|
8
|
+
"comparison",
|
|
9
|
+
"library"
|
|
10
|
+
],
|
|
11
|
+
"author": "",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": ""
|
|
16
|
+
},
|
|
17
|
+
"peerDependencies": {
|
|
18
|
+
"@angular/common": "^14.2.0",
|
|
19
|
+
"@angular/core": "^14.2.0",
|
|
20
|
+
"axios": "1.13.2",
|
|
21
|
+
"socket.io": "4.8.1",
|
|
22
|
+
"socket.io-client": "4.8.1"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"tslib": "^2.3.0"
|
|
26
|
+
},
|
|
27
|
+
"module": "fesm2022/naniteninja-profile-comparison-lib.mjs",
|
|
28
|
+
"typings": "index.d.ts",
|
|
29
|
+
"exports": {
|
|
30
|
+
"./package.json": {
|
|
31
|
+
"default": "./package.json"
|
|
32
|
+
},
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./index.d.ts",
|
|
35
|
+
"default": "./fesm2022/naniteninja-profile-comparison-lib.mjs"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"sideEffects": false
|
|
39
|
+
}
|