@chainpatrol/sdk 1.8.0 → 1.9.0
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/CHANGELOG.md +6 -0
- package/dist/api/index.d.mts +3 -1
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/api/index.mjs +2 -0
- package/dist/api/index.mjs.map +1 -1
- package/dist/{chunk-ZTE6QNOQ.mjs → chunk-O5IZ7M5X.mjs} +10 -8
- package/dist/chunk-O5IZ7M5X.mjs.map +1 -0
- package/dist/index.js +689 -76
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +689 -76
- package/dist/index.mjs.map +1 -1
- package/dist/skill/cli.js +8 -6
- package/dist/skill/cli.js.map +1 -1
- package/dist/skill/cli.mjs +1 -1
- package/dist/skill/index.js +8 -6
- package/dist/skill/index.js.map +1 -1
- package/dist/skill/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-ZTE6QNOQ.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1255,17 +1255,17 @@ var PolyDateFormatter = class {
|
|
|
1255
1255
|
constructor(dt, intl, opts) {
|
|
1256
1256
|
this.opts = opts;
|
|
1257
1257
|
this.originalZone = void 0;
|
|
1258
|
-
let
|
|
1258
|
+
let z56 = void 0;
|
|
1259
1259
|
if (this.opts.timeZone) {
|
|
1260
1260
|
this.dt = dt;
|
|
1261
1261
|
} else if (dt.zone.type === "fixed") {
|
|
1262
1262
|
const gmtOffset = -1 * (dt.offset / 60);
|
|
1263
1263
|
const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
|
|
1264
1264
|
if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
|
|
1265
|
-
|
|
1265
|
+
z56 = offsetZ;
|
|
1266
1266
|
this.dt = dt;
|
|
1267
1267
|
} else {
|
|
1268
|
-
|
|
1268
|
+
z56 = "UTC";
|
|
1269
1269
|
this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1270
1270
|
this.originalZone = dt.zone;
|
|
1271
1271
|
}
|
|
@@ -1273,14 +1273,14 @@ var PolyDateFormatter = class {
|
|
|
1273
1273
|
this.dt = dt;
|
|
1274
1274
|
} else if (dt.zone.type === "iana") {
|
|
1275
1275
|
this.dt = dt;
|
|
1276
|
-
|
|
1276
|
+
z56 = dt.zone.name;
|
|
1277
1277
|
} else {
|
|
1278
|
-
|
|
1278
|
+
z56 = "UTC";
|
|
1279
1279
|
this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
|
|
1280
1280
|
this.originalZone = dt.zone;
|
|
1281
1281
|
}
|
|
1282
1282
|
const intlOpts = __spreadValues({}, this.opts);
|
|
1283
|
-
intlOpts.timeZone = intlOpts.timeZone ||
|
|
1283
|
+
intlOpts.timeZone = intlOpts.timeZone || z56;
|
|
1284
1284
|
this.dtf = getCachedDTF(intl, intlOpts);
|
|
1285
1285
|
}
|
|
1286
1286
|
format() {
|
|
@@ -11430,6 +11430,50 @@ z.object({
|
|
|
11430
11430
|
endDate: z.date()
|
|
11431
11431
|
})
|
|
11432
11432
|
});
|
|
11433
|
+
var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
|
|
11434
|
+
var utcDateSchema = (endOfDay) => z.preprocess((value) => {
|
|
11435
|
+
if (typeof value !== "string") {
|
|
11436
|
+
return value;
|
|
11437
|
+
}
|
|
11438
|
+
const parsed = DateTime.fromISO(value, { zone: "utc" });
|
|
11439
|
+
if (!parsed.isValid) {
|
|
11440
|
+
return new Date(Number.NaN);
|
|
11441
|
+
}
|
|
11442
|
+
return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11443
|
+
}, z.coerce.date());
|
|
11444
|
+
var funnelCountsSchema = z.object({
|
|
11445
|
+
blocked: z.number().int().nonnegative().describe(
|
|
11446
|
+
"Distinct assets whose earliest report for this org falls in the range and whose current status or pending status is BLOCKED"
|
|
11447
|
+
)
|
|
11448
|
+
});
|
|
11449
|
+
z.object({
|
|
11450
|
+
slug: z.string().min(1).describe("Organization slug"),
|
|
11451
|
+
startDate: utcDateSchema(false).describe(
|
|
11452
|
+
"Only include assets whose earliest report was created on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11453
|
+
),
|
|
11454
|
+
endDate: utcDateSchema(true).describe(
|
|
11455
|
+
"Only include assets whose earliest report was created on or before this date. A date-only value (YYYY-MM-DD) covers the whole day in UTC; pass a full timestamp for a precise cut-off"
|
|
11456
|
+
),
|
|
11457
|
+
brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
|
|
11458
|
+
}).refine((input) => input.startDate.getTime() <= input.endDate.getTime(), {
|
|
11459
|
+
message: "startDate must be on or before endDate",
|
|
11460
|
+
path: ["startDate"]
|
|
11461
|
+
});
|
|
11462
|
+
z.object({
|
|
11463
|
+
range: z.object({
|
|
11464
|
+
startDate: z.date(),
|
|
11465
|
+
endDate: z.date()
|
|
11466
|
+
}),
|
|
11467
|
+
customer: funnelCountsSchema.describe(
|
|
11468
|
+
"Currently blocked assets first reported by the customer (reportedByCustomer, external reporter, or customer-role user)"
|
|
11469
|
+
),
|
|
11470
|
+
chainpatrol: funnelCountsSchema.describe(
|
|
11471
|
+
"Currently blocked assets first reported by ChainPatrol staff or automation. Staff and automation are collapsed together."
|
|
11472
|
+
),
|
|
11473
|
+
totals: funnelCountsSchema.describe(
|
|
11474
|
+
"customer + chainpatrol. This is a first-report blocked cohort and does not equal metrics/found, which counts assets by blockedAt."
|
|
11475
|
+
)
|
|
11476
|
+
});
|
|
11433
11477
|
z.object({
|
|
11434
11478
|
slug: z.string().min(1),
|
|
11435
11479
|
startDate: z.date().optional(),
|
|
@@ -11461,8 +11505,8 @@ z.object({
|
|
|
11461
11505
|
})
|
|
11462
11506
|
)
|
|
11463
11507
|
});
|
|
11464
|
-
var
|
|
11465
|
-
var
|
|
11508
|
+
var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
|
|
11509
|
+
var utcDateSchema2 = (endOfDay) => z.preprocess((value) => {
|
|
11466
11510
|
if (typeof value !== "string") {
|
|
11467
11511
|
return value;
|
|
11468
11512
|
}
|
|
@@ -11470,14 +11514,14 @@ var utcDateSchema = (endOfDay) => z.preprocess((value) => {
|
|
|
11470
11514
|
if (!parsed.isValid) {
|
|
11471
11515
|
return new Date(Number.NaN);
|
|
11472
11516
|
}
|
|
11473
|
-
return endOfDay &&
|
|
11517
|
+
return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
|
|
11474
11518
|
}, z.coerce.date());
|
|
11475
11519
|
z.object({
|
|
11476
11520
|
slug: z.string().min(1).describe("Organization slug"),
|
|
11477
|
-
startDate:
|
|
11521
|
+
startDate: utcDateSchema2(false).optional().describe(
|
|
11478
11522
|
"Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
|
|
11479
11523
|
),
|
|
11480
|
-
endDate:
|
|
11524
|
+
endDate: utcDateSchema2(true).optional().describe(
|
|
11481
11525
|
"Only include takedowns completed on or before this date. A date-only value (YYYY-MM-DD) covers the whole day in UTC; pass a full timestamp for a precise cut-off"
|
|
11482
11526
|
),
|
|
11483
11527
|
blockLabel: z.string().optional().describe(
|
|
@@ -11935,7 +11979,9 @@ var organizationMetricsIncludeFieldSchema = z.enum([
|
|
|
11935
11979
|
"newThreats",
|
|
11936
11980
|
"threatsWatchlisted",
|
|
11937
11981
|
"takedownsFiled",
|
|
11982
|
+
"takedownsInProgress",
|
|
11938
11983
|
"takedownsCompleted",
|
|
11984
|
+
"takedownsCancelled",
|
|
11939
11985
|
"domainThreats",
|
|
11940
11986
|
"twitterThreats",
|
|
11941
11987
|
"telegramThreats",
|
|
@@ -11977,7 +12023,7 @@ z.object({
|
|
|
11977
12023
|
startDate: z.coerce.date().optional(),
|
|
11978
12024
|
endDate: z.coerce.date().optional(),
|
|
11979
12025
|
include: z.array(organizationMetricsIncludeFieldSchema).optional().describe(
|
|
11980
|
-
"Subset of metrics to compute. When omitted or empty, every metric is computed (legacy behavior). Each value in `include` costs roughly one
|
|
12026
|
+
"Subset of metrics to compute. When omitted or empty, every metric is computed (legacy behavior). Each value in `include` costs roughly one aggregate query, so narrow the list when an agent only needs a couple of numbers \u2014 this is the main lever for keeping big-org calls inside the 30s function cap. Fields not in `include` come back as `null`. `takedownsInProgress` and `takedownsCancelled` count takedowns currently in that status whose `updatedAt` falls in the window (same windowing as `takedownsFiled`), so they reconcile with the takedowns list filtered by status over the same date range."
|
|
11981
12027
|
)
|
|
11982
12028
|
}).refine(
|
|
11983
12029
|
(value) => {
|
|
@@ -12005,7 +12051,9 @@ var metricsObjectSchema = z.object({
|
|
|
12005
12051
|
newThreats: metricValue,
|
|
12006
12052
|
threatsWatchlisted: metricValue,
|
|
12007
12053
|
takedownsFiled: metricValue,
|
|
12054
|
+
takedownsInProgress: metricValue,
|
|
12008
12055
|
takedownsCompleted: metricValue,
|
|
12056
|
+
takedownsCancelled: metricValue,
|
|
12009
12057
|
domainThreats: metricValue,
|
|
12010
12058
|
twitterThreats: metricValue,
|
|
12011
12059
|
telegramThreats: metricValue,
|
|
@@ -13388,20 +13436,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
|
|
|
13388
13436
|
|
|
13389
13437
|
// ../../node_modules/culori/src/a98/convertXyz65ToA98.js
|
|
13390
13438
|
var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
|
|
13391
|
-
var convertXyz65ToA98 = ({ x, y, z:
|
|
13439
|
+
var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
|
|
13392
13440
|
if (x === void 0) x = 0;
|
|
13393
13441
|
if (y === void 0) y = 0;
|
|
13394
|
-
if (
|
|
13442
|
+
if (z56 === void 0) z56 = 0;
|
|
13395
13443
|
let res = {
|
|
13396
13444
|
mode: "a98",
|
|
13397
13445
|
r: gamma(
|
|
13398
|
-
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 *
|
|
13446
|
+
x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
|
|
13399
13447
|
),
|
|
13400
13448
|
g: gamma(
|
|
13401
|
-
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 *
|
|
13449
|
+
x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
|
|
13402
13450
|
),
|
|
13403
13451
|
b: gamma(
|
|
13404
|
-
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 *
|
|
13452
|
+
x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
|
|
13405
13453
|
)
|
|
13406
13454
|
};
|
|
13407
13455
|
if (alpha !== void 0) {
|
|
@@ -13468,14 +13516,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
|
|
|
13468
13516
|
var convertLrgbToRgb_default = convertLrgbToRgb;
|
|
13469
13517
|
|
|
13470
13518
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
|
|
13471
|
-
var convertXyz65ToRgb = ({ x, y, z:
|
|
13519
|
+
var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
13472
13520
|
if (x === void 0) x = 0;
|
|
13473
13521
|
if (y === void 0) y = 0;
|
|
13474
|
-
if (
|
|
13522
|
+
if (z56 === void 0) z56 = 0;
|
|
13475
13523
|
let res = convertLrgbToRgb_default({
|
|
13476
|
-
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 *
|
|
13477
|
-
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 *
|
|
13478
|
-
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 *
|
|
13524
|
+
r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 * z56,
|
|
13525
|
+
g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 * z56,
|
|
13526
|
+
b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 * z56
|
|
13479
13527
|
});
|
|
13480
13528
|
if (alpha !== void 0) {
|
|
13481
13529
|
res.alpha = alpha;
|
|
@@ -13725,13 +13773,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
|
|
|
13725
13773
|
|
|
13726
13774
|
// ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
|
|
13727
13775
|
var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
|
|
13728
|
-
var convertXyz65ToLab65 = ({ x, y, z:
|
|
13776
|
+
var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
|
|
13729
13777
|
if (x === void 0) x = 0;
|
|
13730
13778
|
if (y === void 0) y = 0;
|
|
13731
|
-
if (
|
|
13779
|
+
if (z56 === void 0) z56 = 0;
|
|
13732
13780
|
let f0 = f(x / D65.X);
|
|
13733
13781
|
let f1 = f(y / D65.Y);
|
|
13734
|
-
let f22 = f(
|
|
13782
|
+
let f22 = f(z56 / D65.Z);
|
|
13735
13783
|
let res = {
|
|
13736
13784
|
mode: "lab65",
|
|
13737
13785
|
l: 116 * f1 - 16,
|
|
@@ -14388,10 +14436,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
|
|
|
14388
14436
|
|
|
14389
14437
|
// ../../node_modules/culori/src/itp/convertXyz65ToItp.js
|
|
14390
14438
|
var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
|
|
14391
|
-
var convertXyz65ToItp = ({ x, y, z:
|
|
14439
|
+
var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
|
|
14392
14440
|
const absX = toAbs(x);
|
|
14393
14441
|
const absY = toAbs(y);
|
|
14394
|
-
const absZ = toAbs(
|
|
14442
|
+
const absZ = toAbs(z56);
|
|
14395
14443
|
const l2 = transferPqEncode(
|
|
14396
14444
|
0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
|
|
14397
14445
|
);
|
|
@@ -14449,15 +14497,15 @@ var jabPqEncode = (v) => {
|
|
|
14449
14497
|
return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
|
|
14450
14498
|
};
|
|
14451
14499
|
var abs = (v = 0) => Math.max(v * 203, 0);
|
|
14452
|
-
var convertXyz65ToJab = ({ x, y, z:
|
|
14500
|
+
var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
|
|
14453
14501
|
x = abs(x);
|
|
14454
14502
|
y = abs(y);
|
|
14455
|
-
|
|
14456
|
-
let xp = 1.15 * x - 0.15 *
|
|
14503
|
+
z56 = abs(z56);
|
|
14504
|
+
let xp = 1.15 * x - 0.15 * z56;
|
|
14457
14505
|
let yp = 0.66 * y + 0.34 * x;
|
|
14458
|
-
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 *
|
|
14459
|
-
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 *
|
|
14460
|
-
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 *
|
|
14506
|
+
let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 * z56);
|
|
14507
|
+
let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 * z56);
|
|
14508
|
+
let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 * z56);
|
|
14461
14509
|
let i = (l2 + m) / 2;
|
|
14462
14510
|
let res = {
|
|
14463
14511
|
mode: "jab",
|
|
@@ -14643,14 +14691,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
|
|
|
14643
14691
|
var convertLabToXyz50_default = convertLabToXyz50;
|
|
14644
14692
|
|
|
14645
14693
|
// ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
|
|
14646
|
-
var convertXyz50ToRgb = ({ x, y, z:
|
|
14694
|
+
var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
|
|
14647
14695
|
if (x === void 0) x = 0;
|
|
14648
14696
|
if (y === void 0) y = 0;
|
|
14649
|
-
if (
|
|
14697
|
+
if (z56 === void 0) z56 = 0;
|
|
14650
14698
|
let res = convertLrgbToRgb_default({
|
|
14651
|
-
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 *
|
|
14652
|
-
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 *
|
|
14653
|
-
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 *
|
|
14699
|
+
r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 * z56,
|
|
14700
|
+
g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 * z56,
|
|
14701
|
+
b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 * z56
|
|
14654
14702
|
});
|
|
14655
14703
|
if (alpha !== void 0) {
|
|
14656
14704
|
res.alpha = alpha;
|
|
@@ -14681,13 +14729,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
|
|
|
14681
14729
|
|
|
14682
14730
|
// ../../node_modules/culori/src/lab/convertXyz50ToLab.js
|
|
14683
14731
|
var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
|
|
14684
|
-
var convertXyz50ToLab = ({ x, y, z:
|
|
14732
|
+
var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
|
|
14685
14733
|
if (x === void 0) x = 0;
|
|
14686
14734
|
if (y === void 0) y = 0;
|
|
14687
|
-
if (
|
|
14735
|
+
if (z56 === void 0) z56 = 0;
|
|
14688
14736
|
let f0 = f2(x / D50.X);
|
|
14689
14737
|
let f1 = f2(y / D50.Y);
|
|
14690
|
-
let f22 = f2(
|
|
14738
|
+
let f22 = f2(z56 / D50.Z);
|
|
14691
14739
|
let res = {
|
|
14692
14740
|
mode: "lab",
|
|
14693
14741
|
l: 116 * f1 - 16,
|
|
@@ -14922,18 +14970,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
|
|
|
14922
14970
|
var convertLchuvToLuv_default = convertLchuvToLuv;
|
|
14923
14971
|
|
|
14924
14972
|
// ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
|
|
14925
|
-
var u_fn = (x, y,
|
|
14926
|
-
var v_fn = (x, y,
|
|
14973
|
+
var u_fn = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
14974
|
+
var v_fn = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14927
14975
|
var un = u_fn(D50.X, D50.Y, D50.Z);
|
|
14928
14976
|
var vn = v_fn(D50.X, D50.Y, D50.Z);
|
|
14929
14977
|
var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
|
|
14930
|
-
var convertXyz50ToLuv = ({ x, y, z:
|
|
14978
|
+
var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
|
|
14931
14979
|
if (x === void 0) x = 0;
|
|
14932
14980
|
if (y === void 0) y = 0;
|
|
14933
|
-
if (
|
|
14981
|
+
if (z56 === void 0) z56 = 0;
|
|
14934
14982
|
let l2 = l_fn(y / D50.Y);
|
|
14935
|
-
let u = u_fn(x, y,
|
|
14936
|
-
let v = v_fn(x, y,
|
|
14983
|
+
let u = u_fn(x, y, z56);
|
|
14984
|
+
let v = v_fn(x, y, z56);
|
|
14937
14985
|
if (!isFinite(u) || !isFinite(v)) {
|
|
14938
14986
|
l2 = u = v = 0;
|
|
14939
14987
|
} else {
|
|
@@ -14954,8 +15002,8 @@ var convertXyz50ToLuv = ({ x, y, z: z55, alpha }) => {
|
|
|
14954
15002
|
var convertXyz50ToLuv_default = convertXyz50ToLuv;
|
|
14955
15003
|
|
|
14956
15004
|
// ../../node_modules/culori/src/luv/convertLuvToXyz50.js
|
|
14957
|
-
var u_fn2 = (x, y,
|
|
14958
|
-
var v_fn2 = (x, y,
|
|
15005
|
+
var u_fn2 = (x, y, z56) => 4 * x / (x + 15 * y + 3 * z56);
|
|
15006
|
+
var v_fn2 = (x, y, z56) => 9 * y / (x + 15 * y + 3 * z56);
|
|
14959
15007
|
var un2 = u_fn2(D50.X, D50.Y, D50.Z);
|
|
14960
15008
|
var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
|
|
14961
15009
|
var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
@@ -14969,8 +15017,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
|
|
|
14969
15017
|
let vp = v / (13 * l2) + vn2;
|
|
14970
15018
|
let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
|
|
14971
15019
|
let x = y * (9 * up) / (4 * vp);
|
|
14972
|
-
let
|
|
14973
|
-
let res = { mode: "xyz50", x, y, z:
|
|
15020
|
+
let z56 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
|
|
15021
|
+
let res = { mode: "xyz50", x, y, z: z56 };
|
|
14974
15022
|
if (alpha !== void 0) {
|
|
14975
15023
|
res.alpha = alpha;
|
|
14976
15024
|
}
|
|
@@ -15587,15 +15635,15 @@ var convertP3ToXyz65 = (rgb2) => {
|
|
|
15587
15635
|
var convertP3ToXyz65_default = convertP3ToXyz65;
|
|
15588
15636
|
|
|
15589
15637
|
// ../../node_modules/culori/src/p3/convertXyz65ToP3.js
|
|
15590
|
-
var convertXyz65ToP3 = ({ x, y, z:
|
|
15638
|
+
var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
|
|
15591
15639
|
if (x === void 0) x = 0;
|
|
15592
15640
|
if (y === void 0) y = 0;
|
|
15593
|
-
if (
|
|
15641
|
+
if (z56 === void 0) z56 = 0;
|
|
15594
15642
|
let res = convertLrgbToRgb_default(
|
|
15595
15643
|
{
|
|
15596
|
-
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 *
|
|
15597
|
-
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 *
|
|
15598
|
-
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 *
|
|
15644
|
+
r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 * z56,
|
|
15645
|
+
g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 * z56,
|
|
15646
|
+
b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 * z56
|
|
15599
15647
|
},
|
|
15600
15648
|
"p3"
|
|
15601
15649
|
);
|
|
@@ -15630,19 +15678,19 @@ var gamma2 = (v) => {
|
|
|
15630
15678
|
}
|
|
15631
15679
|
return 16 * v;
|
|
15632
15680
|
};
|
|
15633
|
-
var convertXyz50ToProphoto = ({ x, y, z:
|
|
15681
|
+
var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
|
|
15634
15682
|
if (x === void 0) x = 0;
|
|
15635
15683
|
if (y === void 0) y = 0;
|
|
15636
|
-
if (
|
|
15684
|
+
if (z56 === void 0) z56 = 0;
|
|
15637
15685
|
let res = {
|
|
15638
15686
|
mode: "prophoto",
|
|
15639
15687
|
r: gamma2(
|
|
15640
|
-
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 *
|
|
15688
|
+
x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
|
|
15641
15689
|
),
|
|
15642
15690
|
g: gamma2(
|
|
15643
|
-
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 *
|
|
15691
|
+
x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
|
|
15644
15692
|
),
|
|
15645
|
-
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 *
|
|
15693
|
+
b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
|
|
15646
15694
|
};
|
|
15647
15695
|
if (alpha !== void 0) {
|
|
15648
15696
|
res.alpha = alpha;
|
|
@@ -15702,20 +15750,20 @@ var gamma3 = (v) => {
|
|
|
15702
15750
|
}
|
|
15703
15751
|
return 4.5 * v;
|
|
15704
15752
|
};
|
|
15705
|
-
var convertXyz65ToRec2020 = ({ x, y, z:
|
|
15753
|
+
var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
|
|
15706
15754
|
if (x === void 0) x = 0;
|
|
15707
15755
|
if (y === void 0) y = 0;
|
|
15708
|
-
if (
|
|
15756
|
+
if (z56 === void 0) z56 = 0;
|
|
15709
15757
|
let res = {
|
|
15710
15758
|
mode: "rec2020",
|
|
15711
15759
|
r: gamma3(
|
|
15712
|
-
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 *
|
|
15760
|
+
x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
|
|
15713
15761
|
),
|
|
15714
15762
|
g: gamma3(
|
|
15715
|
-
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 *
|
|
15763
|
+
x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
|
|
15716
15764
|
),
|
|
15717
15765
|
b: gamma3(
|
|
15718
|
-
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 *
|
|
15766
|
+
x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
|
|
15719
15767
|
)
|
|
15720
15768
|
};
|
|
15721
15769
|
if (alpha !== void 0) {
|
|
@@ -15868,15 +15916,15 @@ var definition_default26 = definition26;
|
|
|
15868
15916
|
|
|
15869
15917
|
// ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
|
|
15870
15918
|
var convertXyz65ToXyz50 = (xyz652) => {
|
|
15871
|
-
let { x, y, z:
|
|
15919
|
+
let { x, y, z: z56, alpha } = xyz652;
|
|
15872
15920
|
if (x === void 0) x = 0;
|
|
15873
15921
|
if (y === void 0) y = 0;
|
|
15874
|
-
if (
|
|
15922
|
+
if (z56 === void 0) z56 = 0;
|
|
15875
15923
|
let res = {
|
|
15876
15924
|
mode: "xyz50",
|
|
15877
|
-
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 *
|
|
15878
|
-
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 *
|
|
15879
|
-
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 *
|
|
15925
|
+
x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 * z56,
|
|
15926
|
+
y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 * z56,
|
|
15927
|
+
z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 * z56
|
|
15880
15928
|
};
|
|
15881
15929
|
if (alpha !== void 0) {
|
|
15882
15930
|
res.alpha = alpha;
|
|
@@ -15887,15 +15935,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
|
|
|
15887
15935
|
|
|
15888
15936
|
// ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
|
|
15889
15937
|
var convertXyz50ToXyz65 = (xyz502) => {
|
|
15890
|
-
let { x, y, z:
|
|
15938
|
+
let { x, y, z: z56, alpha } = xyz502;
|
|
15891
15939
|
if (x === void 0) x = 0;
|
|
15892
15940
|
if (y === void 0) y = 0;
|
|
15893
|
-
if (
|
|
15941
|
+
if (z56 === void 0) z56 = 0;
|
|
15894
15942
|
let res = {
|
|
15895
15943
|
mode: "xyz65",
|
|
15896
|
-
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 *
|
|
15897
|
-
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 *
|
|
15898
|
-
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 *
|
|
15944
|
+
x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 * z56,
|
|
15945
|
+
y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 * z56,
|
|
15946
|
+
z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 * z56
|
|
15899
15947
|
};
|
|
15900
15948
|
if (alpha !== void 0) {
|
|
15901
15949
|
res.alpha = alpha;
|
|
@@ -16165,6 +16213,571 @@ z.string().optional().nullable().transform((value) => {
|
|
|
16165
16213
|
}
|
|
16166
16214
|
);
|
|
16167
16215
|
|
|
16216
|
+
// ../../internal/utils/src/industry.ts
|
|
16217
|
+
var Industry = {
|
|
16218
|
+
// Finance
|
|
16219
|
+
BANKING: "banking",
|
|
16220
|
+
FINANCIAL_SERVICES: "financial_services",
|
|
16221
|
+
FINTECH: "fintech",
|
|
16222
|
+
PAYMENTS: "payments"};
|
|
16223
|
+
|
|
16224
|
+
// ../../internal/validation/src/dark-web/templates.ts
|
|
16225
|
+
var BRAND = { kind: "brand" };
|
|
16226
|
+
var lit = (value) => ({ kind: "literal", value });
|
|
16227
|
+
var phrase = (...tokens) => ({ type: "phrase", tokens });
|
|
16228
|
+
var bn = (slop, ...words) => ({
|
|
16229
|
+
type: "phrase",
|
|
16230
|
+
tokens: [BRAND, ...words.map(lit)],
|
|
16231
|
+
slop
|
|
16232
|
+
});
|
|
16233
|
+
var nb = (slop, ...words) => ({
|
|
16234
|
+
type: "phrase",
|
|
16235
|
+
tokens: [...words.map(lit), BRAND],
|
|
16236
|
+
slop
|
|
16237
|
+
});
|
|
16238
|
+
var word = (value) => ({ type: "term", value, match: "word" });
|
|
16239
|
+
var prefix = (value) => ({
|
|
16240
|
+
type: "term",
|
|
16241
|
+
value,
|
|
16242
|
+
match: "prefix"
|
|
16243
|
+
});
|
|
16244
|
+
var or = (...children) => ({
|
|
16245
|
+
type: "group",
|
|
16246
|
+
op: "OR",
|
|
16247
|
+
children
|
|
16248
|
+
});
|
|
16249
|
+
var and = (...children) => ({
|
|
16250
|
+
type: "group",
|
|
16251
|
+
op: "AND",
|
|
16252
|
+
children
|
|
16253
|
+
});
|
|
16254
|
+
var notOneOf = (...children) => ({
|
|
16255
|
+
type: "group",
|
|
16256
|
+
op: "OR",
|
|
16257
|
+
children,
|
|
16258
|
+
negated: true
|
|
16259
|
+
});
|
|
16260
|
+
var brandWith = (...values) => and(phrase(BRAND), or(...values.map(word)));
|
|
16261
|
+
var SCAN_TEMPLATES = [
|
|
16262
|
+
{
|
|
16263
|
+
id: "p2p-instant-transfer",
|
|
16264
|
+
category: "payment-fraud",
|
|
16265
|
+
title: "P2P and instant transfer abuse",
|
|
16266
|
+
description: "Actors advertising instant peer-to-peer transfers into or out of the brand, a common way to move stolen funds before a hold clears.",
|
|
16267
|
+
// Source rows: 1, 55. The original ("[brand]"~3) was proximity on one
|
|
16268
|
+
// position, a no-op; dropped rather than ported.
|
|
16269
|
+
query: and(
|
|
16270
|
+
or(
|
|
16271
|
+
phrase(BRAND, lit("to"), BRAND),
|
|
16272
|
+
bn(2, "instant"),
|
|
16273
|
+
bn(2, "anyone"),
|
|
16274
|
+
bn(1, "pay"),
|
|
16275
|
+
bn(3, "pay anyone"),
|
|
16276
|
+
bn(2, "p2p"),
|
|
16277
|
+
bn(3, "instant transfer"),
|
|
16278
|
+
bn(3, "receive from anyone"),
|
|
16279
|
+
bn(4, "phone number"),
|
|
16280
|
+
bn(2, "member to member"),
|
|
16281
|
+
nb(3, "send")
|
|
16282
|
+
),
|
|
16283
|
+
notOneOf(word("rate"), word("price"))
|
|
16284
|
+
)
|
|
16285
|
+
},
|
|
16286
|
+
{
|
|
16287
|
+
id: "transfers-ach-direct-debit",
|
|
16288
|
+
category: "payment-fraud",
|
|
16289
|
+
title: "Transfers, ACH and direct debit",
|
|
16290
|
+
description: "Discussion of pushing or pulling funds via ACH, direct debit or bill pay, including chatter about pending and settlement timing.",
|
|
16291
|
+
// Source rows: 6, 8, 18, 41. Row 18 was missing an OR before "Direct Debit".
|
|
16292
|
+
query: or(
|
|
16293
|
+
bn(1, "transfer"),
|
|
16294
|
+
nb(1, "transfer"),
|
|
16295
|
+
bn(5, "ach"),
|
|
16296
|
+
nb(4, "pull"),
|
|
16297
|
+
nb(4, "push"),
|
|
16298
|
+
bn(4, "pending"),
|
|
16299
|
+
bn(4, "settle"),
|
|
16300
|
+
nb(4, "link"),
|
|
16301
|
+
brandWith("billpay", "acctverify"),
|
|
16302
|
+
and(phrase(BRAND), or(phrase(lit("direct debit")), phrase(lit("direct deposit"))))
|
|
16303
|
+
)
|
|
16304
|
+
},
|
|
16305
|
+
{
|
|
16306
|
+
id: "wallet-linking",
|
|
16307
|
+
category: "payment-fraud",
|
|
16308
|
+
title: "Wallet linking and instant funding",
|
|
16309
|
+
description: "Linking the brand to mobile wallets for instant funding, and 'linkable' account trading where a name match is being sold.",
|
|
16310
|
+
// Source rows: 19, 44, 51
|
|
16311
|
+
query: and(
|
|
16312
|
+
or(
|
|
16313
|
+
bn(5, "apple pay"),
|
|
16314
|
+
bn(5, "apple"),
|
|
16315
|
+
bn(3, "apple linkable"),
|
|
16316
|
+
bn(2, "linkable"),
|
|
16317
|
+
bn(2, "linkables"),
|
|
16318
|
+
nb(2, "linkable"),
|
|
16319
|
+
nb(2, "link"),
|
|
16320
|
+
and(phrase(BRAND), phrase(lit("name match")))
|
|
16321
|
+
),
|
|
16322
|
+
notOneOf(word("espn"), word("airtag"))
|
|
16323
|
+
)
|
|
16324
|
+
},
|
|
16325
|
+
{
|
|
16326
|
+
id: "card-data-exposure",
|
|
16327
|
+
category: "payment-fraud",
|
|
16328
|
+
title: "Card data and virtual cards",
|
|
16329
|
+
description: "Brand-issued card details being traded: expiry, CVV, virtual card numbers and card activation.",
|
|
16330
|
+
// Source rows: 43
|
|
16331
|
+
query: and(
|
|
16332
|
+
brandWith("exp", "cvv", "vcc", "debit"),
|
|
16333
|
+
notOneOf(word("checking"), word("limits"))
|
|
16334
|
+
)
|
|
16335
|
+
},
|
|
16336
|
+
{
|
|
16337
|
+
id: "card-loading",
|
|
16338
|
+
category: "payment-fraud",
|
|
16339
|
+
title: "Card and account loading",
|
|
16340
|
+
description: "'Loading' services that push stolen funds onto brand accounts or cards for a cut.",
|
|
16341
|
+
// Source rows: 42
|
|
16342
|
+
query: or(
|
|
16343
|
+
nb(1, "loading"),
|
|
16344
|
+
nb(1, "load"),
|
|
16345
|
+
bn(1, "loads"),
|
|
16346
|
+
bn(1, "loading"),
|
|
16347
|
+
bn(3, "drop"),
|
|
16348
|
+
bn(2, "cash"),
|
|
16349
|
+
and(
|
|
16350
|
+
phrase(BRAND),
|
|
16351
|
+
or(
|
|
16352
|
+
phrase(lit("loading method")),
|
|
16353
|
+
phrase(lit("loading guide")),
|
|
16354
|
+
phrase(lit("loading tut")),
|
|
16355
|
+
phrase(lit("loading tutorial"))
|
|
16356
|
+
)
|
|
16357
|
+
)
|
|
16358
|
+
)
|
|
16359
|
+
},
|
|
16360
|
+
{
|
|
16361
|
+
id: "cross-platform-cashout",
|
|
16362
|
+
category: "payment-fraud",
|
|
16363
|
+
title: "Cross-platform cash-out",
|
|
16364
|
+
description: "Moving funds from the brand into other consumer payment apps to break the trail.",
|
|
16365
|
+
// Source rows: 56
|
|
16366
|
+
query: and(
|
|
16367
|
+
phrase(BRAND),
|
|
16368
|
+
or(
|
|
16369
|
+
phrase(lit("cash app")),
|
|
16370
|
+
word("venmo"),
|
|
16371
|
+
phrase(lit("transfer to paypal")),
|
|
16372
|
+
phrase(lit("visa money transfer"))
|
|
16373
|
+
)
|
|
16374
|
+
)
|
|
16375
|
+
},
|
|
16376
|
+
{
|
|
16377
|
+
id: "crypto-offramp",
|
|
16378
|
+
category: "payment-fraud",
|
|
16379
|
+
title: "Crypto off-ramp",
|
|
16380
|
+
description: "Converting funds held at the brand into cryptocurrency through exchanges and P2P markets.",
|
|
16381
|
+
// Source rows: 63
|
|
16382
|
+
query: and(
|
|
16383
|
+
phrase(BRAND),
|
|
16384
|
+
or(
|
|
16385
|
+
word("crypto"),
|
|
16386
|
+
word("moonpay"),
|
|
16387
|
+
word("switchere"),
|
|
16388
|
+
word("kraken"),
|
|
16389
|
+
word("paxful"),
|
|
16390
|
+
word("noones"),
|
|
16391
|
+
word("coinomi"),
|
|
16392
|
+
word("coinzoom"),
|
|
16393
|
+
word("bitcoin"),
|
|
16394
|
+
word("btc")
|
|
16395
|
+
)
|
|
16396
|
+
)
|
|
16397
|
+
},
|
|
16398
|
+
{
|
|
16399
|
+
id: "mobile-check-deposit",
|
|
16400
|
+
category: "deposit-fraud",
|
|
16401
|
+
title: "Mobile check deposit fraud",
|
|
16402
|
+
description: "Check fraud against mobile deposit, traded under slang including 'glass', 'MCD', 'slips' and 'persy'.",
|
|
16403
|
+
// Source rows: 2, 13, 35, 46
|
|
16404
|
+
industries: [
|
|
16405
|
+
Industry.BANKING,
|
|
16406
|
+
Industry.FINANCIAL_SERVICES,
|
|
16407
|
+
Industry.FINTECH,
|
|
16408
|
+
Industry.PAYMENTS
|
|
16409
|
+
],
|
|
16410
|
+
query: or(
|
|
16411
|
+
bn(5, "checks"),
|
|
16412
|
+
bn(5, "check"),
|
|
16413
|
+
bn(5, "mobile deposit"),
|
|
16414
|
+
nb(5, "mobile deposit"),
|
|
16415
|
+
bn(5, "slip"),
|
|
16416
|
+
bn(5, "slips"),
|
|
16417
|
+
bn(5, "glass"),
|
|
16418
|
+
bn(5, "md"),
|
|
16419
|
+
bn(5, "mcd"),
|
|
16420
|
+
bn(5, "treasury"),
|
|
16421
|
+
nb(5, "treasury"),
|
|
16422
|
+
bn(5, "persy"),
|
|
16423
|
+
bn(5, "deposit limit"),
|
|
16424
|
+
and(phrase(BRAND), or(prefix("stimm"), word("mcd"), phrase(lit("pop on"))))
|
|
16425
|
+
)
|
|
16426
|
+
},
|
|
16427
|
+
{
|
|
16428
|
+
id: "atm-abuse",
|
|
16429
|
+
category: "deposit-fraud",
|
|
16430
|
+
title: "ATM abuse and 'box work'",
|
|
16431
|
+
description: "ATM deposit and withdrawal manipulation, including dispute-driven 'box work' against cash machines.",
|
|
16432
|
+
// Source rows: 9, 47, 57, 70
|
|
16433
|
+
industries: [
|
|
16434
|
+
Industry.BANKING,
|
|
16435
|
+
Industry.FINANCIAL_SERVICES,
|
|
16436
|
+
Industry.FINTECH,
|
|
16437
|
+
Industry.PAYMENTS
|
|
16438
|
+
],
|
|
16439
|
+
query: or(
|
|
16440
|
+
bn(2, "atm"),
|
|
16441
|
+
bn(2, "withdrawal"),
|
|
16442
|
+
and(phrase(BRAND), phrase(lit("box work"))),
|
|
16443
|
+
and(
|
|
16444
|
+
phrase(BRAND),
|
|
16445
|
+
or(
|
|
16446
|
+
phrase(lit("atm deposit")),
|
|
16447
|
+
phrase(lit("atm withdrawal")),
|
|
16448
|
+
phrase(lit("atm withdraw")),
|
|
16449
|
+
phrase(lit("atm limit")),
|
|
16450
|
+
phrase(lit("atm card")),
|
|
16451
|
+
phrase(lit("cash withdrawal fee"))
|
|
16452
|
+
)
|
|
16453
|
+
)
|
|
16454
|
+
)
|
|
16455
|
+
},
|
|
16456
|
+
{
|
|
16457
|
+
id: "retail-cashout-network",
|
|
16458
|
+
category: "deposit-fraud",
|
|
16459
|
+
title: "Retail cash-out network",
|
|
16460
|
+
description: "Cash-out through retail and ATM partner networks, where funds are pulled at a storefront rather than a branch.",
|
|
16461
|
+
// Source rows: 30
|
|
16462
|
+
industries: [
|
|
16463
|
+
Industry.BANKING,
|
|
16464
|
+
Industry.FINANCIAL_SERVICES,
|
|
16465
|
+
Industry.FINTECH,
|
|
16466
|
+
Industry.PAYMENTS
|
|
16467
|
+
],
|
|
16468
|
+
query: or(
|
|
16469
|
+
bn(5, "allpoint"),
|
|
16470
|
+
bn(5, "walgreens"),
|
|
16471
|
+
bn(5, "cvs"),
|
|
16472
|
+
bn(5, "7-eleven"),
|
|
16473
|
+
bn(5, "7eleven"),
|
|
16474
|
+
bn(5, "711"),
|
|
16475
|
+
bn(5, "circle k"),
|
|
16476
|
+
bn(5, "target"),
|
|
16477
|
+
bn(5, "visa plus alliance"),
|
|
16478
|
+
bn(3, "moneypass"),
|
|
16479
|
+
bn(3, "vanilladirect"),
|
|
16480
|
+
bn(3, "vanilla"),
|
|
16481
|
+
bn(3, "dollar general"),
|
|
16482
|
+
bn(3, "dollar tree"),
|
|
16483
|
+
bn(3, "safeway"),
|
|
16484
|
+
bn(3, "walmart"),
|
|
16485
|
+
bn(3, "speedway")
|
|
16486
|
+
)
|
|
16487
|
+
},
|
|
16488
|
+
{
|
|
16489
|
+
id: "otp-bots",
|
|
16490
|
+
category: "account-takeover",
|
|
16491
|
+
title: "OTP bots and 2FA bypass",
|
|
16492
|
+
description: "Automated one-time-passcode interception services targeting the brand's login and step-up flows.",
|
|
16493
|
+
// Source rows: 34
|
|
16494
|
+
query: or(
|
|
16495
|
+
bn(2, "otp"),
|
|
16496
|
+
nb(1, "otp"),
|
|
16497
|
+
phrase(BRAND, lit("otp bot")),
|
|
16498
|
+
bn(2, "2fa"),
|
|
16499
|
+
bn(2, "code"),
|
|
16500
|
+
bn(2, "bypass"),
|
|
16501
|
+
bn(2, "bot"),
|
|
16502
|
+
bn(2, "bots")
|
|
16503
|
+
)
|
|
16504
|
+
},
|
|
16505
|
+
{
|
|
16506
|
+
id: "remote-access-tooling",
|
|
16507
|
+
category: "account-takeover",
|
|
16508
|
+
title: "Remote-access tooling",
|
|
16509
|
+
description: "Legitimate remote-management tools named alongside the brand, the standard toolkit for support-impersonation account takeover.",
|
|
16510
|
+
// Source rows: 29, 64. Truncated by the export; recoverable portion only.
|
|
16511
|
+
query: and(
|
|
16512
|
+
phrase(BRAND),
|
|
16513
|
+
or(
|
|
16514
|
+
word("action1"),
|
|
16515
|
+
phrase(lit("ammy admin")),
|
|
16516
|
+
word("ammyadmin"),
|
|
16517
|
+
word("anydesk"),
|
|
16518
|
+
phrase(lit("any desk")),
|
|
16519
|
+
word("atera"),
|
|
16520
|
+
word("beanywhere"),
|
|
16521
|
+
phrase(lit("chrome remote desktop")),
|
|
16522
|
+
word("connectwise"),
|
|
16523
|
+
word("screenconnect"),
|
|
16524
|
+
word("dameware"),
|
|
16525
|
+
word("domotz"),
|
|
16526
|
+
word("dwservice"),
|
|
16527
|
+
word("fleetdeck"),
|
|
16528
|
+
word("intelliadmin"),
|
|
16529
|
+
phrase(lit("itarian endpoint manager")),
|
|
16530
|
+
phrase(lit("level.io")),
|
|
16531
|
+
word("meshcentral"),
|
|
16532
|
+
word("mremoteng"),
|
|
16533
|
+
phrase(lit("n-able")),
|
|
16534
|
+
word("ngrok"),
|
|
16535
|
+
phrase(lit("pdq deploy")),
|
|
16536
|
+
word("pulseway"),
|
|
16537
|
+
word("realvnc"),
|
|
16538
|
+
phrase(lit("remote utilities")),
|
|
16539
|
+
word("rport")
|
|
16540
|
+
)
|
|
16541
|
+
)
|
|
16542
|
+
},
|
|
16543
|
+
{
|
|
16544
|
+
id: "antidetect-kyc-evasion",
|
|
16545
|
+
category: "account-takeover",
|
|
16546
|
+
title: "Anti-detect and KYC evasion tooling",
|
|
16547
|
+
description: "Fingerprint spoofing, residential proxies and emulators used to defeat the brand's device and identity checks.",
|
|
16548
|
+
// Source row: 40. The original filtered to Telegram OR Dread; DarkOwl's
|
|
16549
|
+
// `source` takes one value, so precision comes from the tooling terms.
|
|
16550
|
+
query: and(
|
|
16551
|
+
phrase(BRAND),
|
|
16552
|
+
or(
|
|
16553
|
+
word("tlo"),
|
|
16554
|
+
word("scamalytics"),
|
|
16555
|
+
word("burner"),
|
|
16556
|
+
prefix("prox"),
|
|
16557
|
+
word("vpn"),
|
|
16558
|
+
word("vps"),
|
|
16559
|
+
word("antidetect"),
|
|
16560
|
+
phrase(lit("anti-detect")),
|
|
16561
|
+
prefix("emulat")
|
|
16562
|
+
)
|
|
16563
|
+
)
|
|
16564
|
+
},
|
|
16565
|
+
{
|
|
16566
|
+
id: "brand-domains-sso",
|
|
16567
|
+
category: "account-takeover",
|
|
16568
|
+
title: "Brand domains and SSO endpoints",
|
|
16569
|
+
description: "The brand's own domains and identity-provider endpoints appearing in credential and access chatter.",
|
|
16570
|
+
// Source row: 31, as proximity not literal hostnames — the index tokenizes
|
|
16571
|
+
// `chime.okta.com`, so a glued literal would never match. Row 23's
|
|
16572
|
+
// "[brand] pass*"~1 is omitted: no wildcards inside a phrase.
|
|
16573
|
+
query: and(
|
|
16574
|
+
or(bn(2, "okta"), bn(2, "login"), bn(2, "portal"), bn(1, "bank")),
|
|
16575
|
+
notOneOf(word("zendesk"))
|
|
16576
|
+
)
|
|
16577
|
+
},
|
|
16578
|
+
{
|
|
16579
|
+
id: "account-opening-abuse",
|
|
16580
|
+
category: "onboarding-abuse",
|
|
16581
|
+
title: "Account opening and self-registration",
|
|
16582
|
+
description: "Bulk or fraudulent account creation against the brand, including 'self-reg' and 'drop' accounts opened on stolen identities.",
|
|
16583
|
+
// Source rows: 5, 17, 54
|
|
16584
|
+
query: or(
|
|
16585
|
+
bn(5, "enroll"),
|
|
16586
|
+
nb(5, "enroll"),
|
|
16587
|
+
bn(5, "open"),
|
|
16588
|
+
nb(5, "open"),
|
|
16589
|
+
bn(5, "drop"),
|
|
16590
|
+
nb(5, "drop"),
|
|
16591
|
+
nb(5, "make"),
|
|
16592
|
+
nb(5, "create"),
|
|
16593
|
+
nb(5, "fresh"),
|
|
16594
|
+
nb(5, "register"),
|
|
16595
|
+
bn(5, "self-reg"),
|
|
16596
|
+
bn(5, "selfreg"),
|
|
16597
|
+
bn(5, "self-registered"),
|
|
16598
|
+
bn(5, "self register"),
|
|
16599
|
+
bn(1, "fullz")
|
|
16600
|
+
)
|
|
16601
|
+
},
|
|
16602
|
+
{
|
|
16603
|
+
id: "identity-documents",
|
|
16604
|
+
category: "onboarding-abuse",
|
|
16605
|
+
title: "Identity documents and fullz",
|
|
16606
|
+
description: "Trade in identity packages and lookup services used to pass onboarding checks. Anchored to the brand at the root, since the source query was brand-independent.",
|
|
16607
|
+
// Source row: 15. Lexicon-only, so the renderer AND-s the anchor on.
|
|
16608
|
+
query: or(
|
|
16609
|
+
word("fullz"),
|
|
16610
|
+
phrase(lit("get pros")),
|
|
16611
|
+
phrase(lit("driver's license")),
|
|
16612
|
+
phrase(lit("tlo bot")),
|
|
16613
|
+
phrase(lit("tlo plug")),
|
|
16614
|
+
phrase(lit("need dl")),
|
|
16615
|
+
phrase(lit("get id"))
|
|
16616
|
+
)
|
|
16617
|
+
},
|
|
16618
|
+
{
|
|
16619
|
+
id: "referral-bonus-abuse",
|
|
16620
|
+
category: "onboarding-abuse",
|
|
16621
|
+
title: "Referral and bonus abuse",
|
|
16622
|
+
description: "Methods for farming the brand's referral bonuses and promotional offers, often paired with fake direct deposits.",
|
|
16623
|
+
// Source rows: 48
|
|
16624
|
+
query: and(
|
|
16625
|
+
or(bn(3, "referral"), bn(3, "bonus"), bn(3, "promotion"), bn(3, "offer")),
|
|
16626
|
+
or(
|
|
16627
|
+
word("bypass"),
|
|
16628
|
+
word("dd"),
|
|
16629
|
+
phrase(lit("direct deposit")),
|
|
16630
|
+
phrase(lit("work around")),
|
|
16631
|
+
word("trick"),
|
|
16632
|
+
word("method"),
|
|
16633
|
+
word("glitch"),
|
|
16634
|
+
word("tutorial"),
|
|
16635
|
+
word("tut"),
|
|
16636
|
+
word("wave"),
|
|
16637
|
+
word("sauce")
|
|
16638
|
+
)
|
|
16639
|
+
)
|
|
16640
|
+
},
|
|
16641
|
+
{
|
|
16642
|
+
id: "insider-recruitment",
|
|
16643
|
+
category: "insider-threat",
|
|
16644
|
+
title: "Insider recruitment",
|
|
16645
|
+
description: "Actors seeking or advertising an employee on the inside ('inny'), the highest-severity signal in this catalog.",
|
|
16646
|
+
// Source rows: 7, 38
|
|
16647
|
+
query: and(
|
|
16648
|
+
or(
|
|
16649
|
+
bn(4, "inny"),
|
|
16650
|
+
bn(4, "insider"),
|
|
16651
|
+
and(
|
|
16652
|
+
phrase(BRAND),
|
|
16653
|
+
or(
|
|
16654
|
+
word("insider"),
|
|
16655
|
+
word("inny"),
|
|
16656
|
+
phrase(lit("in office")),
|
|
16657
|
+
word("employee"),
|
|
16658
|
+
phrase(lit("i work at")),
|
|
16659
|
+
phrase(lit("i am an employee")),
|
|
16660
|
+
phrase(lit("i can get access")),
|
|
16661
|
+
phrase(lit("i have access to")),
|
|
16662
|
+
phrase(lit("employed at")),
|
|
16663
|
+
word("occupation")
|
|
16664
|
+
)
|
|
16665
|
+
)
|
|
16666
|
+
),
|
|
16667
|
+
notOneOf(phrase(lit("welcome to insider chat")))
|
|
16668
|
+
)
|
|
16669
|
+
},
|
|
16670
|
+
{
|
|
16671
|
+
id: "mule-crew-recruitment",
|
|
16672
|
+
category: "insider-threat",
|
|
16673
|
+
title: "Mule and cash-out crew recruitment",
|
|
16674
|
+
description: "Recruitment of account holders to receive and forward funds, priced as a revenue split ('50/50', '60/40').",
|
|
16675
|
+
// Source rows: 39
|
|
16676
|
+
query: or(
|
|
16677
|
+
bn(5, "cl"),
|
|
16678
|
+
bn(5, "mule"),
|
|
16679
|
+
bn(5, "tap in"),
|
|
16680
|
+
bn(5, "50/50"),
|
|
16681
|
+
bn(5, "60/40"),
|
|
16682
|
+
bn(5, "striker")
|
|
16683
|
+
)
|
|
16684
|
+
},
|
|
16685
|
+
{
|
|
16686
|
+
id: "methods-and-tutorials",
|
|
16687
|
+
category: "tradecraft",
|
|
16688
|
+
title: "Methods, 'sauce' and tutorials",
|
|
16689
|
+
description: "Fraud methods being taught or sold against the brand, under the usual slang: sauce, glitch, tut, wave, motion, tap in.",
|
|
16690
|
+
// Source rows: 4, 21, 59
|
|
16691
|
+
query: or(
|
|
16692
|
+
bn(3, "sauce"),
|
|
16693
|
+
bn(3, "method"),
|
|
16694
|
+
bn(3, "guide"),
|
|
16695
|
+
bn(3, "tut"),
|
|
16696
|
+
bn(3, "tutorial"),
|
|
16697
|
+
bn(4, "hack"),
|
|
16698
|
+
bn(4, "glitch"),
|
|
16699
|
+
bn(4, "wave"),
|
|
16700
|
+
bn(4, "motion"),
|
|
16701
|
+
bn(4, "walkthrough"),
|
|
16702
|
+
bn(4, "walk through"),
|
|
16703
|
+
bn(2, "tap in"),
|
|
16704
|
+
bn(2, "tapin"),
|
|
16705
|
+
nb(2, "tapn")
|
|
16706
|
+
)
|
|
16707
|
+
},
|
|
16708
|
+
{
|
|
16709
|
+
id: "hack-leak-chatter",
|
|
16710
|
+
category: "tradecraft",
|
|
16711
|
+
title: "Hack and leak chatter",
|
|
16712
|
+
description: "Claims of having hacked, breached or leaked the brand, whether credible or not.",
|
|
16713
|
+
// Source rows: 28
|
|
16714
|
+
query: or(
|
|
16715
|
+
bn(4, "hack"),
|
|
16716
|
+
bn(4, "glitch"),
|
|
16717
|
+
nb(4, "hacking"),
|
|
16718
|
+
bn(4, "leak"),
|
|
16719
|
+
bn(4, "leaked")
|
|
16720
|
+
)
|
|
16721
|
+
},
|
|
16722
|
+
{
|
|
16723
|
+
id: "support-impersonation",
|
|
16724
|
+
category: "brand-abuse",
|
|
16725
|
+
title: "Support impersonation",
|
|
16726
|
+
description: "Actors impersonating the brand's support or service staff to social-engineer customers.",
|
|
16727
|
+
// Source rows: 36
|
|
16728
|
+
query: or(
|
|
16729
|
+
bn(1, "agent"),
|
|
16730
|
+
bn(1, "support"),
|
|
16731
|
+
bn(1, "service"),
|
|
16732
|
+
bn(1, "customer"),
|
|
16733
|
+
nb(1, "impersonate"),
|
|
16734
|
+
bn(1, "impersonation"),
|
|
16735
|
+
bn(3, "scam"),
|
|
16736
|
+
nb(1, "scam")
|
|
16737
|
+
)
|
|
16738
|
+
},
|
|
16739
|
+
{
|
|
16740
|
+
id: "social-impersonation",
|
|
16741
|
+
category: "brand-abuse",
|
|
16742
|
+
title: "Social account impersonation",
|
|
16743
|
+
description: "The brand discussed alongside social platforms, where fake support and giveaway accounts are staged.",
|
|
16744
|
+
// Source rows: 25
|
|
16745
|
+
query: or(
|
|
16746
|
+
bn(5, "instagram"),
|
|
16747
|
+
bn(5, "insta"),
|
|
16748
|
+
bn(5, "facebook"),
|
|
16749
|
+
bn(5, "twitter"),
|
|
16750
|
+
bn(5, "tiktok")
|
|
16751
|
+
)
|
|
16752
|
+
},
|
|
16753
|
+
{
|
|
16754
|
+
id: "vendor-supply-chain",
|
|
16755
|
+
category: "data-exposure",
|
|
16756
|
+
title: "Vendor and BPO supply chain",
|
|
16757
|
+
description: "Outsourced support and processing vendors named alongside the brand, where a third-party breach exposes brand customer data.",
|
|
16758
|
+
// Source row: 60, truncated by the export. Generic BPO/CX providers; a
|
|
16759
|
+
// per-org vendor list would be materially better.
|
|
16760
|
+
query: and(
|
|
16761
|
+
phrase(BRAND),
|
|
16762
|
+
or(
|
|
16763
|
+
word("zendesk"),
|
|
16764
|
+
word("teleperformance"),
|
|
16765
|
+
word("concentrix"),
|
|
16766
|
+
word("taskus"),
|
|
16767
|
+
word("genpact"),
|
|
16768
|
+
word("ubiquity"),
|
|
16769
|
+
word("hioperator"),
|
|
16770
|
+
word("galileo"),
|
|
16771
|
+
word("fiserv"),
|
|
16772
|
+
phrase(lit("etech global"))
|
|
16773
|
+
)
|
|
16774
|
+
)
|
|
16775
|
+
}
|
|
16776
|
+
];
|
|
16777
|
+
new Map(
|
|
16778
|
+
SCAN_TEMPLATES.map((template) => [template.id, template])
|
|
16779
|
+
);
|
|
16780
|
+
|
|
16168
16781
|
// src/client.ts
|
|
16169
16782
|
function trimTrailingSlashes(url) {
|
|
16170
16783
|
return url.replace(/\/+$/, "");
|