@chainpatrol/sdk 1.9.0 → 1.11.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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { __spreadValues, __export, __spreadProps, __async, __objRest, __pow } from './chunk-4U7ZT42S.mjs';
1
+ import { __spreadValues, __export, __async, __spreadProps, __objRest, __pow } from './chunk-4U7ZT42S.mjs';
2
2
  import { getDomain, getSubdomain, parse as parse$1 } from 'tldts';
3
3
  import { z } from 'zod';
4
4
 
@@ -543,45 +543,6 @@ z.object({
543
543
  name: z.string().optional().describe("Asset name"),
544
544
  description: z.string().nullish().optional().describe("Asset description")
545
545
  });
546
- z.object({
547
- slug: z.string(),
548
- assetId: z.number(),
549
- name: z.string().optional(),
550
- description: z.string().optional(),
551
- assetGroupId: z.number().nullable().optional(),
552
- updatedByOrganizationId: z.number().optional()
553
- });
554
- z.object({
555
- content: z.string().min(1, { message: "Content must be at least 3 character" }).max(1e3, { message: "Content must be less than 1000 characters" }),
556
- email: z.string().email(),
557
- description: z.string().optional().default("")
558
- });
559
- z.object({
560
- /** Canonicalization algorithm version the client computed its prefixes with. */
561
- algoVersion: z.number().int().positive(),
562
- /** 4-byte (8-hex-char) prefixes that hit the client's local index. */
563
- prefixes: z.array(z.string().regex(/^[0-9a-f]{8}$/)).min(1).max(200)
564
- }).describe("Blocklist confirm request");
565
- z.object({
566
- /** Full 64-char SHA-256 hashes of blocked expressions, grouped by prefix. */
567
- fullHashes: z.record(z.string(), z.array(z.string()))
568
- }).describe("Blocklist confirm response");
569
- z.void().describe("Blocklist version request");
570
- z.object({
571
- /** Canonicalization algorithm version the artifacts + confirm are built with. */
572
- algoVersion: z.number().int().positive(),
573
- snapshot: z.object({
574
- token: z.string(),
575
- url: z.string().url(),
576
- prefixBytes: z.number().int().positive(),
577
- count: z.number().int().nonnegative()
578
- }),
579
- recent: z.object({
580
- token: z.string(),
581
- url: z.string().url(),
582
- windowSeconds: z.number().int().positive()
583
- })
584
- }).describe("Blocklist version response");
585
546
 
586
547
  // ../../node_modules/luxon/src/errors.js
587
548
  var LuxonError = class extends Error {
@@ -1255,17 +1216,17 @@ var PolyDateFormatter = class {
1255
1216
  constructor(dt, intl, opts) {
1256
1217
  this.opts = opts;
1257
1218
  this.originalZone = void 0;
1258
- let z56 = void 0;
1219
+ let z64 = void 0;
1259
1220
  if (this.opts.timeZone) {
1260
1221
  this.dt = dt;
1261
1222
  } else if (dt.zone.type === "fixed") {
1262
1223
  const gmtOffset = -1 * (dt.offset / 60);
1263
1224
  const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
1264
1225
  if (dt.offset !== 0 && IANAZone.create(offsetZ).valid) {
1265
- z56 = offsetZ;
1226
+ z64 = offsetZ;
1266
1227
  this.dt = dt;
1267
1228
  } else {
1268
- z56 = "UTC";
1229
+ z64 = "UTC";
1269
1230
  this.dt = dt.offset === 0 ? dt : dt.setZone("UTC").plus({ minutes: dt.offset });
1270
1231
  this.originalZone = dt.zone;
1271
1232
  }
@@ -1273,14 +1234,14 @@ var PolyDateFormatter = class {
1273
1234
  this.dt = dt;
1274
1235
  } else if (dt.zone.type === "iana") {
1275
1236
  this.dt = dt;
1276
- z56 = dt.zone.name;
1237
+ z64 = dt.zone.name;
1277
1238
  } else {
1278
- z56 = "UTC";
1239
+ z64 = "UTC";
1279
1240
  this.dt = dt.setZone("UTC").plus({ minutes: dt.offset });
1280
1241
  this.originalZone = dt.zone;
1281
1242
  }
1282
1243
  const intlOpts = __spreadValues({}, this.opts);
1283
- intlOpts.timeZone = intlOpts.timeZone || z56;
1244
+ intlOpts.timeZone = intlOpts.timeZone || z64;
1284
1245
  this.dtf = getCachedDTF(intl, intlOpts);
1285
1246
  }
1286
1247
  format() {
@@ -6996,6 +6957,79 @@ function friendlyDateTime(dateTimeish) {
6996
6957
  );
6997
6958
  }
6998
6959
  }
6960
+ var MAX_ASSET_NOTE_LENGTH = 5e3;
6961
+ var assetNoteBodySchema = z.string().trim().min(1, "Note is required").max(MAX_ASSET_NOTE_LENGTH, `Note must be at most ${MAX_ASSET_NOTE_LENGTH} characters`);
6962
+ var assetNoteTimelineAtSchema = z.coerce.date().refine((value) => value.getTime() <= DateTime.now().toUTC().toMillis(), {
6963
+ message: "Timeline date cannot be in the future"
6964
+ });
6965
+ z.object({
6966
+ assetId: z.number().int().positive(),
6967
+ note: assetNoteBodySchema,
6968
+ timelineAt: assetNoteTimelineAtSchema.optional()
6969
+ });
6970
+ z.object({
6971
+ noteId: z.number().int().positive(),
6972
+ note: assetNoteBodySchema,
6973
+ timelineAt: assetNoteTimelineAtSchema.nullish()
6974
+ });
6975
+ z.object({
6976
+ noteId: z.number().int().positive()
6977
+ });
6978
+ var ASSET_TAGS = {
6979
+ ENFORCEMENT_EXHAUSTED: {
6980
+ label: "Enforcement Exhausted",
6981
+ description: "All available enforcement options have been pursued with the relevant providers. The asset remains active due to provider inaction.",
6982
+ colorScheme: "orange"
6983
+ }
6984
+ };
6985
+ var ASSET_TAG_KEYS = Object.keys(ASSET_TAGS);
6986
+ var assetTagKeySchema = z.enum(ASSET_TAG_KEYS);
6987
+ z.object({
6988
+ assetId: z.number().int().positive()
6989
+ });
6990
+ z.object({
6991
+ assetId: z.number().int().positive(),
6992
+ tag: assetTagKeySchema
6993
+ });
6994
+ z.object({
6995
+ slug: z.string(),
6996
+ assetId: z.number(),
6997
+ name: z.string().optional(),
6998
+ description: z.string().optional(),
6999
+ assetGroupId: z.number().nullable().optional(),
7000
+ updatedByOrganizationId: z.number().optional()
7001
+ });
7002
+ z.object({
7003
+ content: z.string().min(1, { message: "Content must be at least 3 character" }).max(1e3, { message: "Content must be less than 1000 characters" }),
7004
+ email: z.string().email(),
7005
+ description: z.string().optional().default("")
7006
+ });
7007
+ z.object({
7008
+ /** Canonicalization algorithm version the client computed its prefixes with. */
7009
+ algoVersion: z.number().int().positive(),
7010
+ /** 4-byte (8-hex-char) prefixes that hit the client's local index. */
7011
+ prefixes: z.array(z.string().regex(/^[0-9a-f]{8}$/)).min(1).max(200)
7012
+ }).describe("Blocklist confirm request");
7013
+ z.object({
7014
+ /** Full 64-char SHA-256 hashes of blocked expressions, grouped by prefix. */
7015
+ fullHashes: z.record(z.string(), z.array(z.string()))
7016
+ }).describe("Blocklist confirm response");
7017
+ z.void().describe("Blocklist version request");
7018
+ z.object({
7019
+ /** Canonicalization algorithm version the artifacts + confirm are built with. */
7020
+ algoVersion: z.number().int().positive(),
7021
+ snapshot: z.object({
7022
+ token: z.string(),
7023
+ url: z.string().url(),
7024
+ prefixBytes: z.number().int().positive(),
7025
+ count: z.number().int().nonnegative()
7026
+ }),
7027
+ recent: z.object({
7028
+ token: z.string(),
7029
+ url: z.string().url(),
7030
+ windowSeconds: z.number().int().positive()
7031
+ })
7032
+ }).describe("Blocklist version response");
6999
7033
 
7000
7034
  // ../../internal/database/src/generated/prisma/enums.ts
7001
7035
  var BrandType = {
@@ -7116,7 +7150,9 @@ var AssetType = {
7116
7150
  FIVE_HUNDRED_PX: "FIVE_HUNDRED_PX",
7117
7151
  LUMA: "LUMA",
7118
7152
  SMARTMONEYMATCH: "SMARTMONEYMATCH",
7119
- APK_GOLD: "APK_GOLD"
7153
+ APK_GOLD: "APK_GOLD",
7154
+ GLASSDOOR: "GLASSDOOR",
7155
+ PUMP_FUN: "PUMP_FUN"
7120
7156
  };
7121
7157
  var LivenessStatus = {
7122
7158
  UNKNOWN: "UNKNOWN",
@@ -7277,8 +7313,23 @@ z.object({
7277
7313
  watchStatus: z.nativeEnum(WatchStatus).optional().describe("The watch status of the asset.")
7278
7314
  }).describe("Check asset response body");
7279
7315
  var assetListInputSchema = z.object({
7280
- /** The type of asset to retrieve. */
7281
- type: z.nativeEnum(AssetType).describe("Asset type"),
7316
+ /**
7317
+ * The type of asset to retrieve. Omitting the key means every asset type,
7318
+ * which lets a bulk consumer sweep the whole blocklist with one cursor
7319
+ * instead of looping all 94 members of `AssetType`.
7320
+ *
7321
+ * An explicit `null` is rejected with a 400 rather than treated as "all
7322
+ * types". Only omission opts into the full sweep, so a client that sends
7323
+ * `type: null` from an uninitialised variable gets a clear error instead of
7324
+ * silently pulling every blocked asset.
7325
+ *
7326
+ * Not `.nullable()`: besides accepting that null, it renders in the
7327
+ * generated MCP tool manifest as a nested `anyOf` containing `{"not": {}}`,
7328
+ * which buries the enum hint telling a model which values are legal.
7329
+ */
7330
+ type: z.nativeEnum(AssetType).optional().describe(
7331
+ "Asset type to retrieve. Omit the field entirely to retrieve assets of every type in a single paginated sweep; an explicit null is rejected."
7332
+ ),
7282
7333
  /** Optional status filter for the assets; defaults to `BLOCKED`. */
7283
7334
  status: z.nativeEnum(AssetStatus).optional().default(AssetStatus.BLOCKED).describe("Status of the assets to retrieve"),
7284
7335
  /**
@@ -7306,7 +7357,8 @@ var assetListInputSchema = z.object({
7306
7357
  }).describe(
7307
7358
  `List asset request body
7308
7359
 
7309
- Defaults to getting all the updates in the last 1 day.
7360
+ With no \`startDate\`, this returns every matching asset regardless of age \u2014 there
7361
+ is no implicit one-day window. Pass \`startDate\` to get a delta instead.
7310
7362
 
7311
7363
  You can also choose a \`startDate\` and \`endDate\` for the range of asset updates, most
7312
7364
  timestamp formats should work, we use [Luxon](https://moment.github.io/luxon/#/parsing)
@@ -7415,6 +7467,8 @@ var ThreatDetectionSourceKey = /* @__PURE__ */ ((ThreatDetectionSourceKey2) => {
7415
7467
  ThreatDetectionSourceKey2["TELEGRAM_CHANNELS_SEARCH_VETRIC"] = "telegram_channels_search_vetric";
7416
7468
  ThreatDetectionSourceKey2["TELEGRAM_USER_SEARCH_VETRIC"] = "telegram_user_search_vetric";
7417
7469
  ThreatDetectionSourceKey2["FACEBOOK_PAGE_SEARCH_VETRIC"] = "facebook_page_search_vetric";
7470
+ ThreatDetectionSourceKey2["FACEBOOK_USER_SEARCH_VETRIC"] = "facebook_user_search_vetric";
7471
+ ThreatDetectionSourceKey2["FACEBOOK_POST_SEARCH_VETRIC"] = "facebook_post_search_vetric";
7418
7472
  ThreatDetectionSourceKey2["INSTAGRAM_ACCOUNT_SEARCH_VETRIC"] = "instagram_account_search_vetric";
7419
7473
  ThreatDetectionSourceKey2["TWITTER_SEARCH_VETRIC"] = "twitter_search_vetric";
7420
7474
  ThreatDetectionSourceKey2["LINKEDIN_PEOPLE_SEARCH_VETRIC"] = "linkedin_people_search_vetric";
@@ -7454,14 +7508,17 @@ var ThreatDetectionSourceKey = /* @__PURE__ */ ((ThreatDetectionSourceKey2) => {
7454
7508
  ThreatDetectionSourceKey2["GROK_USER_SEARCH"] = "grok_user_search";
7455
7509
  ThreatDetectionSourceKey2["GOOGLE_LENS_IMAGE_SEARCH"] = "google_lens_image_search";
7456
7510
  ThreatDetectionSourceKey2["YANDEX_SEARCH"] = "yandex_search";
7511
+ ThreatDetectionSourceKey2["YANDEX_IMAGE_SEARCH"] = "yandex_image_search";
7457
7512
  ThreatDetectionSourceKey2["LINKEDIN_EMPLOYEE_DETECTION"] = "linkedin_employee_detection";
7458
7513
  ThreatDetectionSourceKey2["LINKEDIN_POST_SEARCH"] = "linkedin_post_search";
7459
7514
  ThreatDetectionSourceKey2["LINKEDIN_COMPANY_SEARCH"] = "linkedin_company_search";
7460
7515
  ThreatDetectionSourceKey2["BING_ADS_SEARCH"] = "bing_ads_search";
7461
7516
  ThreatDetectionSourceKey2["TIK_TOK_ADS_SEARCH"] = "tik_tok_ads_search";
7517
+ ThreatDetectionSourceKey2["ADLIBRARY_ADS_SEARCH"] = "adlibrary_ads_search";
7462
7518
  ThreatDetectionSourceKey2["DNSDB"] = "dnsdb";
7463
7519
  ThreatDetectionSourceKey2["DAILY_MOTION_SEARCH"] = "daily_motion_search";
7464
7520
  ThreatDetectionSourceKey2["WATCHLIST"] = "watchlist";
7521
+ ThreatDetectionSourceKey2["GITHUB_SEARCH"] = "github_search";
7465
7522
  return ThreatDetectionSourceKey2;
7466
7523
  })(ThreatDetectionSourceKey || {});
7467
7524
  var ThreatDetectionScope = /* @__PURE__ */ ((ThreatDetectionScope2) => {
@@ -7487,6 +7544,7 @@ var AssetScanEnrichmentType = /* @__PURE__ */ ((AssetScanEnrichmentType2) => {
7487
7544
  AssetScanEnrichmentType2["DNS"] = "dns";
7488
7545
  AssetScanEnrichmentType2["TLS"] = "tls";
7489
7546
  AssetScanEnrichmentType2["TCP"] = "tcp";
7547
+ AssetScanEnrichmentType2["HOSTNAME_FIRST_SEEN"] = "hostname_first_seen";
7490
7548
  AssetScanEnrichmentType2["TWITTER_POST"] = "post";
7491
7549
  AssetScanEnrichmentType2["TWITTER_PROFILE"] = "profile";
7492
7550
  AssetScanEnrichmentType2["TWITTER_FOLLOWERS"] = "twitter_followers";
@@ -7512,12 +7570,17 @@ var AssetScanEnrichmentType = /* @__PURE__ */ ((AssetScanEnrichmentType2) => {
7512
7570
  AssetScanEnrichmentType2["VIMEO_PROFILE"] = "vimeo_profile";
7513
7571
  AssetScanEnrichmentType2["STACKBLITZ_PAGE"] = "stackblitz_page";
7514
7572
  AssetScanEnrichmentType2["LEETCODE_PAGE"] = "leetcode_page";
7573
+ AssetScanEnrichmentType2["TUMBLR_BLOG"] = "tumblr_blog";
7574
+ AssetScanEnrichmentType2["TUMBLR_POST"] = "tumblr_post";
7575
+ AssetScanEnrichmentType2["TUMBLR_COMMUNITY"] = "tumblr_community";
7515
7576
  AssetScanEnrichmentType2["NPM_PACKAGE"] = "npm_package";
7516
7577
  AssetScanEnrichmentType2["PYPI_PACKAGE"] = "pypi_package";
7517
7578
  AssetScanEnrichmentType2["RUST_PACKAGE"] = "rust_package";
7518
7579
  AssetScanEnrichmentType2["LINKEDIN_PROFILE"] = "linkedin_profile";
7580
+ AssetScanEnrichmentType2["PUMP_FUN_TOKEN"] = "pump_fun_token";
7519
7581
  AssetScanEnrichmentType2["META_AD"] = "meta_ad";
7520
7582
  AssetScanEnrichmentType2["GOOGLE_AD"] = "google_ad";
7583
+ AssetScanEnrichmentType2["ADLIBRARY_AD"] = "adlibrary_ad";
7521
7584
  AssetScanEnrichmentType2["CONTRACT_DEPLOYER"] = "contract_deployer";
7522
7585
  return AssetScanEnrichmentType2;
7523
7586
  })(AssetScanEnrichmentType || {});
@@ -7529,6 +7592,8 @@ var AssetScanEnrichmentSource = /* @__PURE__ */ ((AssetScanEnrichmentSource2) =>
7529
7592
  AssetScanEnrichmentSource2["NETWORK"] = "node_js_network";
7530
7593
  AssetScanEnrichmentSource2["EXTENSION"] = "extension";
7531
7594
  AssetScanEnrichmentSource2["PLAYWRIGHT"] = "playwright";
7595
+ AssetScanEnrichmentSource2["CHAINPATROL_BROWSER"] = "chainpatrol_browser";
7596
+ AssetScanEnrichmentSource2["STEEL_BROWSER"] = "steel_browser";
7532
7597
  AssetScanEnrichmentSource2["X_API"] = "x_api";
7533
7598
  AssetScanEnrichmentSource2["SOCIALDATA_API"] = "socialdata_api";
7534
7599
  AssetScanEnrichmentSource2["NEYNAR_API"] = "neynar_api";
@@ -7547,12 +7612,16 @@ var AssetScanEnrichmentSource = /* @__PURE__ */ ((AssetScanEnrichmentSource2) =>
7547
7612
  AssetScanEnrichmentSource2["VIMEO_API"] = "vimeo_api";
7548
7613
  AssetScanEnrichmentSource2["STACKBLITZ_API"] = "stackblitz_api";
7549
7614
  AssetScanEnrichmentSource2["LEETCODE_API"] = "leetcode_api";
7615
+ AssetScanEnrichmentSource2["TUMBLR_API"] = "tumblr_api";
7550
7616
  AssetScanEnrichmentSource2["NPM_REGISTRY_API"] = "npm_registry_api";
7551
7617
  AssetScanEnrichmentSource2["PYPI_REGISTRY_API"] = "pypi_registry_api";
7552
7618
  AssetScanEnrichmentSource2["CRATES_IO_API"] = "crates_io_api";
7553
7619
  AssetScanEnrichmentSource2["APIFY_LINKEDIN_API"] = "apify_linkedin_api";
7620
+ AssetScanEnrichmentSource2["PUMP_FUN_API"] = "pump_fun_api";
7554
7621
  AssetScanEnrichmentSource2["META_ADS_LIBRARY"] = "meta_ads_library";
7622
+ AssetScanEnrichmentSource2["STEEL_META_ADS_LIBRARY"] = "steel_meta_ads_library";
7555
7623
  AssetScanEnrichmentSource2["GOOGLE_ADS_TRANSPARENCY_CENTER"] = "google_ads_transparency_center";
7624
+ AssetScanEnrichmentSource2["ADLIBRARY"] = "adlibrary";
7556
7625
  AssetScanEnrichmentSource2["ETHERSCAN_API"] = "etherscan_api";
7557
7626
  return AssetScanEnrichmentSource2;
7558
7627
  })(AssetScanEnrichmentSource || {});
@@ -7567,6 +7636,7 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7567
7636
  ["dns" /* DNS */]: "DNS Lookup",
7568
7637
  ["tls" /* TLS */]: "TLS Connection Info",
7569
7638
  ["tcp" /* TCP */]: "TCP Connection Info",
7639
+ ["hostname_first_seen" /* HOSTNAME_FIRST_SEEN */]: "Hostname First Seen",
7570
7640
  // Farcaster
7571
7641
  ["cast" /* FARCASTER_CAST */]: "Farcaster Cast",
7572
7642
  ["farcaster_profile" /* FARCASTER_PROFILE */]: "Farcaster Profile",
@@ -7605,6 +7675,10 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7605
7675
  ["stackblitz_page" /* STACKBLITZ_PAGE */]: "Stackblitz Page",
7606
7676
  // Leetcode
7607
7677
  ["leetcode_page" /* LEETCODE_PAGE */]: "Leetcode Page",
7678
+ // Tumblr
7679
+ ["tumblr_blog" /* TUMBLR_BLOG */]: "Tumblr Blog",
7680
+ ["tumblr_post" /* TUMBLR_POST */]: "Tumblr Post",
7681
+ ["tumblr_community" /* TUMBLR_COMMUNITY */]: "Tumblr Community",
7608
7682
  // NPM
7609
7683
  ["npm_package" /* NPM_PACKAGE */]: "NPM Package",
7610
7684
  // PyPI
@@ -7613,10 +7687,14 @@ var ASSET_SCAN_ENRICHMENT_TYPE_LABELS = {
7613
7687
  ["rust_package" /* RUST_PACKAGE */]: "Rust Package",
7614
7688
  // LinkedIn
7615
7689
  ["linkedin_profile" /* LINKEDIN_PROFILE */]: "LinkedIn Profile",
7690
+ // Pump.fun
7691
+ ["pump_fun_token" /* PUMP_FUN_TOKEN */]: "Pump.fun Token",
7616
7692
  // Meta Ads
7617
7693
  ["meta_ad" /* META_AD */]: "Meta Ad",
7618
7694
  // Google Ads
7619
7695
  ["google_ad" /* GOOGLE_AD */]: "Google Ad",
7696
+ // Cross-platform ad intelligence
7697
+ ["adlibrary_ad" /* ADLIBRARY_AD */]: "AdLibrary Ad",
7620
7698
  // Crypto / Onchain
7621
7699
  ["contract_deployer" /* CONTRACT_DEPLOYER */]: "Contract Deployer"
7622
7700
  };
@@ -7629,6 +7707,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7629
7707
  ["node_js_network" /* NETWORK */]: "Network",
7630
7708
  ["extension" /* EXTENSION */]: "Browser Extension",
7631
7709
  ["playwright" /* PLAYWRIGHT */]: "Playwright",
7710
+ ["chainpatrol_browser" /* CHAINPATROL_BROWSER */]: "ChainPatrol Browser",
7711
+ ["steel_browser" /* STEEL_BROWSER */]: "Steel Browser",
7632
7712
  // Twitter
7633
7713
  ["x_api" /* X_API */]: "X API",
7634
7714
  ["socialdata_api" /* SOCIALDATA_API */]: "SocialData API",
@@ -7663,6 +7743,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7663
7743
  ["stackblitz_api" /* STACKBLITZ_API */]: "Stackblitz API",
7664
7744
  // Leetcode
7665
7745
  ["leetcode_api" /* LEETCODE_API */]: "Leetcode API",
7746
+ // Tumblr
7747
+ ["tumblr_api" /* TUMBLR_API */]: "Tumblr API",
7666
7748
  // NPM
7667
7749
  ["npm_registry_api" /* NPM_REGISTRY_API */]: "NPM Registry API",
7668
7750
  // PyPI
@@ -7671,10 +7753,15 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_LABELS = {
7671
7753
  ["crates_io_api" /* CRATES_IO_API */]: "Crates.io API",
7672
7754
  // LinkedIn
7673
7755
  ["apify_linkedin_api" /* APIFY_LINKEDIN_API */]: "Apify LinkedIn API",
7756
+ // Pump.fun
7757
+ ["pump_fun_api" /* PUMP_FUN_API */]: "Pump.fun API",
7674
7758
  // Meta Ads
7675
7759
  ["meta_ads_library" /* META_ADS_LIBRARY */]: "Meta Ads Library",
7760
+ ["steel_meta_ads_library" /* STEEL_META_ADS_LIBRARY */]: "Steel Meta Ads Library",
7676
7761
  // Google Ads
7677
7762
  ["google_ads_transparency_center" /* GOOGLE_ADS_TRANSPARENCY_CENTER */]: "Google Ads Transparency Center",
7763
+ // Cross-platform ad intelligence
7764
+ ["adlibrary" /* ADLIBRARY */]: "AdLibrary",
7678
7765
  // Crypto / Onchain
7679
7766
  ["etherscan_api" /* ETHERSCAN_API */]: "Etherscan"
7680
7767
  };
@@ -7682,7 +7769,8 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7682
7769
  // URL-related sources
7683
7770
  ["urlscan" /* URLSCAN */]: [
7684
7771
  "browser_capture" /* BROWSER_CAPTURE */,
7685
- "geolocation_and_ip" /* GEOLOCATION_AND_IP */
7772
+ "geolocation_and_ip" /* GEOLOCATION_AND_IP */,
7773
+ "hostname_first_seen" /* HOSTNAME_FIRST_SEEN */
7686
7774
  ],
7687
7775
  ["whois" /* WHOIS */]: ["ownership_and_registration" /* OWNERSHIP_AND_REGISTRATION */],
7688
7776
  ["rdap" /* RDAP */]: ["ownership_and_registration" /* OWNERSHIP_AND_REGISTRATION */],
@@ -7707,6 +7795,12 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7707
7795
  "bilibili_profile" /* BILIBILI_PROFILE */,
7708
7796
  "telegram_profile" /* TELEGRAM_PROFILE */
7709
7797
  ],
7798
+ // Only the generic page capture: the in-house browser does not (yet) run the
7799
+ // platform-specific scrapes PLAYWRIGHT does above.
7800
+ ["chainpatrol_browser" /* CHAINPATROL_BROWSER */]: [
7801
+ "browser_capture" /* BROWSER_CAPTURE */
7802
+ ],
7803
+ ["steel_browser" /* STEEL_BROWSER */]: ["browser_capture" /* BROWSER_CAPTURE */],
7710
7804
  // Twitter-related sources
7711
7805
  ["x_api" /* X_API */]: [
7712
7806
  "post" /* TWITTER_POST */,
@@ -7766,6 +7860,12 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7766
7860
  ["stackblitz_api" /* STACKBLITZ_API */]: ["stackblitz_page" /* STACKBLITZ_PAGE */],
7767
7861
  // Leetcode-related sources
7768
7862
  ["leetcode_api" /* LEETCODE_API */]: ["leetcode_page" /* LEETCODE_PAGE */],
7863
+ // Tumblr-related sources
7864
+ ["tumblr_api" /* TUMBLR_API */]: [
7865
+ "tumblr_blog" /* TUMBLR_BLOG */,
7866
+ "tumblr_post" /* TUMBLR_POST */,
7867
+ "tumblr_community" /* TUMBLR_COMMUNITY */
7868
+ ],
7769
7869
  // NPM-related sources
7770
7870
  ["npm_registry_api" /* NPM_REGISTRY_API */]: ["npm_package" /* NPM_PACKAGE */],
7771
7871
  // PyPI-related sources
@@ -7776,12 +7876,17 @@ var ASSET_SCAN_ENRICHMENT_SOURCE_TO_TYPES = {
7776
7876
  ["apify_linkedin_api" /* APIFY_LINKEDIN_API */]: [
7777
7877
  "linkedin_profile" /* LINKEDIN_PROFILE */
7778
7878
  ],
7879
+ // Pump.fun
7880
+ ["pump_fun_api" /* PUMP_FUN_API */]: ["pump_fun_token" /* PUMP_FUN_TOKEN */],
7779
7881
  // Meta Ads-related sources
7780
7882
  ["meta_ads_library" /* META_ADS_LIBRARY */]: ["meta_ad" /* META_AD */],
7883
+ ["steel_meta_ads_library" /* STEEL_META_ADS_LIBRARY */]: ["meta_ad" /* META_AD */],
7781
7884
  // Google Ads-related sources
7782
7885
  ["google_ads_transparency_center" /* GOOGLE_ADS_TRANSPARENCY_CENTER */]: [
7783
7886
  "google_ad" /* GOOGLE_AD */
7784
7887
  ],
7888
+ // Cross-platform ad intelligence sources
7889
+ ["adlibrary" /* ADLIBRARY */]: ["adlibrary_ad" /* ADLIBRARY_AD */],
7785
7890
  // Crypto / Onchain sources
7786
7891
  ["etherscan_api" /* ETHERSCAN_API */]: ["contract_deployer" /* CONTRACT_DEPLOYER */]
7787
7892
  };
@@ -7982,6 +8087,7 @@ function isDefinedAndNotNull(value) {
7982
8087
  // ../../internal/utils/src/promise.ts
7983
8088
  var promise_exports = {};
7984
8089
  __export(promise_exports, {
8090
+ allSettledWithConcurrency: () => allSettledWithConcurrency,
7985
8091
  isPromiseSettledResultFulfilled: () => isPromiseSettledResultFulfilled,
7986
8092
  isPromiseSettledResultRejected: () => isPromiseSettledResultRejected
7987
8093
  });
@@ -7991,6 +8097,27 @@ function isPromiseSettledResultFulfilled(result) {
7991
8097
  function isPromiseSettledResultRejected(result) {
7992
8098
  return result.status === "rejected";
7993
8099
  }
8100
+ function allSettledWithConcurrency(items, limit, fn5) {
8101
+ return __async(this, null, function* () {
8102
+ const results = new Array(items.length);
8103
+ let next = 0;
8104
+ const worker = () => __async(null, null, function* () {
8105
+ for (; ; ) {
8106
+ const index = next;
8107
+ next += 1;
8108
+ if (index >= items.length) return;
8109
+ try {
8110
+ results[index] = { status: "fulfilled", value: yield fn5(items[index], index) };
8111
+ } catch (reason) {
8112
+ results[index] = { status: "rejected", reason };
8113
+ }
8114
+ }
8115
+ });
8116
+ const workers = Math.max(1, Math.min(Math.floor(limit) || 1, items.length));
8117
+ yield Promise.all(Array.from({ length: workers }, worker));
8118
+ return results;
8119
+ });
8120
+ }
7994
8121
 
7995
8122
  // ../../internal/utils/src/url.ts
7996
8123
  var url_exports = {};
@@ -10745,6 +10872,7 @@ function buildSafePreviewUrl({
10745
10872
  var parse_exports = {};
10746
10873
  __export(parse_exports, {
10747
10874
  parseTerms: () => parseTerms,
10875
+ repairTermsString: () => repairTermsString,
10748
10876
  stringifyTerms: () => stringifyTerms
10749
10877
  });
10750
10878
  function parseTerms(terms, {
@@ -10771,6 +10899,31 @@ function parseTerms(terms, {
10771
10899
  function stringifyTerms(parsedTerms) {
10772
10900
  return parsedTerms.map((term) => term.type === "exact" ? `*${term.value}*` : term.value).join(", ");
10773
10901
  }
10902
+ function repairTermsString(terms) {
10903
+ if (!terms) return terms;
10904
+ const entries = terms.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0);
10905
+ if (entries.length === 0) return terms;
10906
+ const first = entries[0];
10907
+ const last = entries[entries.length - 1];
10908
+ const isWholeListWrap = entries.length > 1 && first.startsWith("*") && !first.endsWith("*") && last.endsWith("*") && !last.startsWith("*");
10909
+ const hasOneSidedAsterisk = entries.some(
10910
+ (entry) => entry.startsWith("*") !== entry.endsWith("*")
10911
+ );
10912
+ if (!isWholeListWrap && !hasOneSidedAsterisk) return terms;
10913
+ const seen = /* @__PURE__ */ new Set();
10914
+ const repaired = [];
10915
+ for (const entry of entries) {
10916
+ const inner = entry.replace(/^\*+|\*+$/g, "").trim();
10917
+ if (inner.length === 0) continue;
10918
+ const isExact = isWholeListWrap || entry.startsWith("*") && entry.endsWith("*") && entry.length > 2;
10919
+ const formatted = isExact ? `*${inner}*` : inner;
10920
+ const key = formatted.toLowerCase();
10921
+ if (seen.has(key)) continue;
10922
+ seen.add(key);
10923
+ repaired.push(formatted);
10924
+ }
10925
+ return repaired.join(", ");
10926
+ }
10774
10927
 
10775
10928
  // ../../internal/utils/src/brand-pattern.ts
10776
10929
  var brand_pattern_exports = {};
@@ -11416,6 +11569,44 @@ z.object({
11416
11569
  })
11417
11570
  )
11418
11571
  });
11572
+ var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
11573
+ var utcDateSchema = (endOfDay) => z.preprocess((value) => {
11574
+ if (typeof value !== "string") {
11575
+ return value;
11576
+ }
11577
+ const parsed = DateTime.fromISO(value, { zone: "utc" });
11578
+ if (!parsed.isValid) {
11579
+ return new Date(Number.NaN);
11580
+ }
11581
+ return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11582
+ }, z.coerce.date());
11583
+
11584
+ // ../../internal/validation/src/public/metrics/false-positive-rate.ts
11585
+ z.object({
11586
+ slug: z.string().min(1).describe("Organization slug"),
11587
+ startDate: utcDateSchema(false).optional().describe(
11588
+ "Only include assets blocked on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11589
+ ),
11590
+ endDate: utcDateSchema(true).optional().describe(
11591
+ "Only include assets blocked 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"
11592
+ ),
11593
+ brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands"),
11594
+ countryCodes: z.array(z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries")
11595
+ });
11596
+ z.object({
11597
+ byAssetType: z.array(
11598
+ z.object({
11599
+ assetType: z.nativeEnum(AssetType).describe("Asset type that was blocked"),
11600
+ blocked: z.number().describe("Assets of this type blocked within the date range"),
11601
+ falsePositives: z.number().describe("Of those, how many are no longer blocked today"),
11602
+ falsePositiveRate: z.number().nullable().describe(
11603
+ "falsePositives / blocked, 0-1. Null only when nothing was blocked, which cannot happen for a returned row"
11604
+ )
11605
+ })
11606
+ ).describe(
11607
+ "False positive rate, one entry per asset type blocked in the range, descending by number blocked. Asset types with no false positives are included with a rate of 0; asset types with no blocks at all in the range are omitted, since they have no rate to report. The denominator counts block events, not distinct assets, so an asset blocked twice in the range counts twice. Whether a block still stands is read as of now while the range bounds the block itself, so a recent range reads low. An asset's blocked status is global, so a block another organization's report caused to be reversed is counted here too"
11608
+ )
11609
+ });
11419
11610
  z.object({
11420
11611
  slug: z.string().min(1),
11421
11612
  startDate: z.date(),
@@ -11430,8 +11621,8 @@ z.object({
11430
11621
  endDate: z.date()
11431
11622
  })
11432
11623
  });
11433
- var DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/;
11434
- var utcDateSchema = (endOfDay) => z.preprocess((value) => {
11624
+ var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
11625
+ var utcDateSchema2 = (endOfDay) => z.preprocess((value) => {
11435
11626
  if (typeof value !== "string") {
11436
11627
  return value;
11437
11628
  }
@@ -11439,7 +11630,7 @@ var utcDateSchema = (endOfDay) => z.preprocess((value) => {
11439
11630
  if (!parsed.isValid) {
11440
11631
  return new Date(Number.NaN);
11441
11632
  }
11442
- return endOfDay && DATE_ONLY_PATTERN.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11633
+ return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11443
11634
  }, z.coerce.date());
11444
11635
  var funnelCountsSchema = z.object({
11445
11636
  blocked: z.number().int().nonnegative().describe(
@@ -11448,10 +11639,10 @@ var funnelCountsSchema = z.object({
11448
11639
  });
11449
11640
  z.object({
11450
11641
  slug: z.string().min(1).describe("Organization slug"),
11451
- startDate: utcDateSchema(false).describe(
11642
+ startDate: utcDateSchema2(false).describe(
11452
11643
  "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
11644
  ),
11454
- endDate: utcDateSchema(true).describe(
11645
+ endDate: utcDateSchema2(true).describe(
11455
11646
  "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
11647
  ),
11457
11648
  brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
@@ -11505,23 +11696,43 @@ z.object({
11505
11696
  })
11506
11697
  )
11507
11698
  });
11508
- var DATE_ONLY_PATTERN2 = /^\d{4}-\d{2}-\d{2}$/;
11509
- var utcDateSchema2 = (endOfDay) => z.preprocess((value) => {
11510
- if (typeof value !== "string") {
11511
- return value;
11512
- }
11513
- const parsed = DateTime.fromISO(value, { zone: "utc" });
11514
- if (!parsed.isValid) {
11515
- return new Date(Number.NaN);
11516
- }
11517
- return endOfDay && DATE_ONLY_PATTERN2.test(value) ? parsed.endOf("day").toJSDate() : parsed.toJSDate();
11518
- }, z.coerce.date());
11519
11699
  z.object({
11520
11700
  slug: z.string().min(1).describe("Organization slug"),
11521
- startDate: utcDateSchema2(false).optional().describe(
11701
+ startDate: utcDateSchema(false).optional().describe(
11702
+ "Only include takedowns first submitted to a provider on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11703
+ ),
11704
+ endDate: utcDateSchema(true).optional().describe(
11705
+ "Only include takedowns first submitted to a provider 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"
11706
+ ),
11707
+ blockLabel: z.string().optional().describe(
11708
+ 'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
11709
+ ),
11710
+ brandType: z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
11711
+ countryCodes: z.array(z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
11712
+ brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
11713
+ });
11714
+ z.object({
11715
+ byAssetType: z.array(
11716
+ z.object({
11717
+ assetType: z.nativeEnum(AssetType).describe("Asset type the takedowns were filed against"),
11718
+ submitted: z.number().describe("Takedowns whose first submission to a provider fell in the range"),
11719
+ completed: z.number().describe("Of those, how many ended in a takedown"),
11720
+ stillOpen: z.number().describe("Of those, how many have not yet reached an outcome"),
11721
+ successRate: z.number().describe("completed / submitted, 0-1. Still-open takedowns count against it"),
11722
+ resolvedSuccessRate: z.number().nullable().describe(
11723
+ "completed / (submitted - stillOpen), 0-1, or null when nothing has resolved yet. Higher than successRate whenever work is still outstanding"
11724
+ )
11725
+ })
11726
+ ).describe(
11727
+ "Takedown success rate, one entry per asset type, descending by number submitted"
11728
+ )
11729
+ });
11730
+ z.object({
11731
+ slug: z.string().min(1).describe("Organization slug"),
11732
+ startDate: utcDateSchema(false).optional().describe(
11522
11733
  "Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11523
11734
  ),
11524
- endDate: utcDateSchema2(true).optional().describe(
11735
+ endDate: utcDateSchema(true).optional().describe(
11525
11736
  "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"
11526
11737
  ),
11527
11738
  blockLabel: z.string().optional().describe(
@@ -11544,6 +11755,46 @@ z.object({
11544
11755
  "Median time from takedown start to completion, one entry per asset type, ascending by median"
11545
11756
  )
11546
11757
  });
11758
+ var TakedownProviderRoleSchema = z.enum([
11759
+ "HOSTING_PROVIDER",
11760
+ "DOMAIN_REGISTRAR",
11761
+ "TLD_REGISTRAR"
11762
+ ]);
11763
+ z.object({
11764
+ slug: z.string().min(1).describe("Organization slug"),
11765
+ startDate: utcDateSchema(false).optional().describe(
11766
+ "Only include takedowns completed on or after this date. A date-only value (YYYY-MM-DD) starts at midnight UTC"
11767
+ ),
11768
+ endDate: utcDateSchema(true).optional().describe(
11769
+ "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"
11770
+ ),
11771
+ roles: z.array(TakedownProviderRoleSchema).optional().describe(
11772
+ "Only break down these provider roles. Omit for every role. A takedown filed against both a host and a registrar is counted once under each"
11773
+ ),
11774
+ blockLabel: z.string().optional().describe(
11775
+ 'Only include assets blocked with this review label, e.g. "Brand Impersonation", "Employee Impersonation" or "Targeting Org Users"'
11776
+ ),
11777
+ brandType: z.nativeEnum(BrandType).optional().describe("Only include assets belonging to brands of this type"),
11778
+ countryCodes: z.array(z.string().length(2)).optional().describe("Only include assets scanned from these ISO 3166-1 alpha-2 countries"),
11779
+ brandIds: z.array(z.number().int().positive()).optional().describe("Only include assets belonging to these brands")
11780
+ });
11781
+ z.object({
11782
+ byProvider: z.array(
11783
+ z.object({
11784
+ providerId: z.number().describe("Takedown provider id"),
11785
+ providerName: z.string().describe("Takedown provider name"),
11786
+ role: TakedownProviderRoleSchema.describe(
11787
+ "Which provider slot of the takedown this median is computed over"
11788
+ ),
11789
+ medianTakedownMinutes: z.number(),
11790
+ medianTakedownHours: z.number(),
11791
+ medianTakedownDays: z.number(),
11792
+ count: z.number().describe("Number of completed takedowns behind the median")
11793
+ })
11794
+ ).describe(
11795
+ "Median time from takedown start to completion, one entry per provider and role, ascending by median"
11796
+ )
11797
+ });
11547
11798
  z.object({
11548
11799
  slug: z.string().min(1).describe("Organization slug"),
11549
11800
  months: z.number().int().min(2).max(36).default(12).describe("Size of the trailing window in whole months, including the current month"),
@@ -11799,6 +12050,13 @@ z.object({
11799
12050
  brands: z.array(brandItemSchema).describe("List of brands")
11800
12051
  }).describe("Successful operation");
11801
12052
  var FILTERABLE_SUBSCRIPTION_STATUSES = [
12053
+ SubscriptionStatus.PROSPECT,
12054
+ SubscriptionStatus.POC,
12055
+ SubscriptionStatus.ACTIVE,
12056
+ SubscriptionStatus.INTEGRATION,
12057
+ SubscriptionStatus.INACTIVE
12058
+ ];
12059
+ [
11802
12060
  SubscriptionStatus.PROSPECT,
11803
12061
  SubscriptionStatus.POC,
11804
12062
  SubscriptionStatus.ACTIVE,
@@ -11833,7 +12091,9 @@ var userOrgsPendingServiceApprovalFilterSchema = z.object({
11833
12091
  }).optional();
11834
12092
  z.object({
11835
12093
  query: z.string().default(""),
11836
- subscriptionStatus: z.array(UserOrgsSubscriptionStatusSchema).min(1).optional(),
12094
+ subscriptionStatus: z.array(UserOrgsSubscriptionStatusSchema).min(1).optional().describe(
12095
+ "Statuses to include. Defaults to the live set (PROSPECT/POC/ACTIVE/INTEGRATION); pass INACTIVE explicitly to see churned organizations."
12096
+ ),
11837
12097
  services: userOrgsServicesFilterObjectSchema.optional(),
11838
12098
  obligatoryAdminApproval: userOrgsObligatoryAdminApprovalFilterSchema,
11839
12099
  pendingServiceApproval: userOrgsPendingServiceApprovalFilterSchema
@@ -12014,7 +12274,7 @@ z.object({
12014
12274
  "Shortcut for 'every org the caller is authorized to read'. Reuses the same filter logic as `/user/orgs`: org-scoped API keys are rejected (they're pinned to one org \u2014 use the default form); user API keys / Bearer sessions resolve to the user's memberships (or every active org for staff). Combine with `subscriptionStatus` and `services` to narrow (e.g. only paying customers with takedowns enabled). The resolved org set is still capped at " + String(ORGANIZATION_METRICS_MAX_SLUGS) + " and a 413 is returned if exceeded. Mutually exclusive with `organizationSlug`, `slugs`, and `brandSlug`."
12015
12275
  ),
12016
12276
  subscriptionStatus: z.array(UserOrgsSubscriptionStatusSchema).min(1).optional().describe(
12017
- "Only meaningful with `allMyOrgs: true`. Defaults to the same set `/user/orgs` uses (ACTIVE/POC/PROSPECT/INTEGRATION \u2014 INACTIVE is always excluded)."
12277
+ "Only meaningful with `allMyOrgs: true`. Defaults to the same set `/user/orgs` uses (ACTIVE/POC/PROSPECT/INTEGRATION); pass INACTIVE explicitly to include churned organizations."
12018
12278
  ),
12019
12279
  services: organizationMetricsServicesFilterSchema.describe(
12020
12280
  "Only meaningful with `allMyOrgs: true`. Same shape as `/user/orgs`'s `services` filter \u2014 every service accepts `{ active }`, and **only `takedowns` additionally accepts `automated`** (the one service where manual-vs-automated changes real platform behavior). E.g. `{ takedowns: { active: true, automated: false } }` for 'orgs with takedowns enabled but automation off'."
@@ -12141,8 +12401,10 @@ var reportCreateInputSchema = z.object({
12141
12401
  ).optional().refine((value) => !value || !isPhoneNumberMissingCountryCode(value), {
12142
12402
  message: PHONE_COUNTRY_CODE_ERROR_MESSAGE
12143
12403
  }),
12144
- /** Optional list of URLs for images to be attached to the report. */
12145
- attachmentUrls: z.array(z.string().url()).optional().describe("URLs of images to attach to the report"),
12404
+ /** Optional list of URLs for files to be attached to the report as evidence. */
12405
+ attachmentUrls: z.array(z.string().url()).optional().describe(
12406
+ "URLs of files to attach to the report as evidence. Any file type, not only images: .eml/.msg messages, PDFs, and documents are all supported. Upload a file to POST /attachment/upload to get a URL, or pass a publicly reachable URL you host yourself."
12407
+ ),
12146
12408
  /** Optional link to the external submission (e.g. Telegram message link) */
12147
12409
  externalSubmissionLink: z.string().url().optional().describe("Link to the external submission (e.g. Telegram message link)"),
12148
12410
  /** Optional user agent string from the reporter's browser */
@@ -12310,6 +12572,38 @@ for parsing the dates.`
12310
12572
  path: ["startDate"]
12311
12573
  }
12312
12574
  );
12575
+ var TakedownProofType = {
12576
+ ProviderEmail: "provider-email"
12577
+ };
12578
+ var takedownProofEmailSchema = z.object({
12579
+ text: z.string().describe(
12580
+ "The provider's reply, verbatim. Plain-text body where the provider sent one, otherwise the raw HTML body \u2014 treat it as untrusted content and escape it before rendering."
12581
+ ),
12582
+ subject: z.string().nullable().describe("Subject line of the provider's reply.")
12583
+ }).nullable().describe(
12584
+ "Present when `type` is `provider-email`, `null` for every other proof type."
12585
+ );
12586
+ var takedownProofSchema = z.object({
12587
+ type: z.nativeEnum(TakedownProofType).describe(
12588
+ "Which kind of evidence this is. Currently only `provider-email`. New types may be added over time \u2014 read `type` before reading any of the type-specific objects below, and treat an unrecognised value as an opaque proof rather than an error."
12589
+ ),
12590
+ source: z.string().nullable().describe(
12591
+ "Who confirmed the takedown, in whatever form that provider identifies itself \u2014 an address such as `abuse@example.com` for `provider-email`."
12592
+ ),
12593
+ confirmedAt: z.date().describe("When the provider confirmed the takedown."),
12594
+ email: takedownProofEmailSchema
12595
+ });
12596
+ var takedownProofsSchema = z.array(takedownProofSchema).describe(
12597
+ `Evidence that this takedown is ours: providers confirming they removed the asset, newest first.
12598
+
12599
+ A takedown filed at several providers can be confirmed by more than one of them, so this is a list. At most 5 are returned per takedown.
12600
+
12601
+ \`type\`, \`source\` and \`confirmedAt\` are present on every entry, so a caller that only needs to show "confirmed by X on date Y" never has to branch on the type. The type-specific object (\`email\`, and others as they are added) carries the underlying evidence.
12602
+
12603
+ Empty unless the takedown is COMPLETED and we hold a confirmation \u2014 which is the common case, because most providers either never reply or reply without confirming they acted. An empty list is not evidence that the asset is still up.
12604
+
12605
+ Requires the \`takedown-proof-api\` feature flag; without it this is always empty.`
12606
+ );
12313
12607
  var takedownItemSchema = z.object({
12314
12608
  id: z.number().describe("Takedown ID"),
12315
12609
  status: z.nativeEnum(TakedownStatus).describe("Takedown status"),
@@ -12359,7 +12653,8 @@ var takedownItemSchema = z.object({
12359
12653
  name: z.string().describe("TLD registrar name (e.g. `Verisign`, `Public Interest Registry`)")
12360
12654
  }).nullable().describe(
12361
12655
  "Top-level-domain registrar assigned to this takedown. `null` when unresolved."
12362
- )
12656
+ ),
12657
+ proofs: takedownProofsSchema
12363
12658
  });
12364
12659
  z.object({
12365
12660
  takedowns: z.array(takedownItemSchema).describe("List of takedowns"),
@@ -12671,6 +12966,141 @@ z.object({
12671
12966
  hiddenMetrics: z.record(z.string(), z.boolean()).default({}),
12672
12967
  overriddenMetrics: z.record(z.string(), z.boolean()).default({})
12673
12968
  });
12969
+ var ONE_PAGER_BUDGETS = {
12970
+ headline: 60,
12971
+ badge: 28,
12972
+ frontLabel: 44,
12973
+ paragraphsMax: 2,
12974
+ heroPhrase: 80,
12975
+ landscapeCaption: 180,
12976
+ xp01Line: 220,
12977
+ screenshotCaption: 48,
12978
+ divergenceLine: 220
12979
+ };
12980
+ var ONE_PAGER_STORED_MAX = {
12981
+ paragraph: 480,
12982
+ paragraph2Lead: 60,
12983
+ heroNarrative: 300
12984
+ };
12985
+ var onePagerFactPayloadSchema = z.object({
12986
+ /** Raw (not defanged) asset contents the prose may reference. */
12987
+ assetContents: z.array(z.string()),
12988
+ /** Every numeric token (as string) the prose is allowed to contain. */
12989
+ numbers: z.array(z.string()),
12990
+ /** ISO dates the prose may reference. */
12991
+ dates: z.array(z.string()),
12992
+ platforms: z.array(z.string()),
12993
+ groupSize: z.number(),
12994
+ takedownCompletedAt: z.string().nullable(),
12995
+ activeSince: z.string().nullable(),
12996
+ // ---- v2 enrichment ----------------------------------------------------
12997
+ // Optional rather than defaulted so rows stored by v1 keep parsing AND the
12998
+ // inferred type stays assignable from a v1-shaped literal.
12999
+ /** How the attacker paid for the surface ("free_subdomain" | ...). */
13000
+ hostingPattern: z.string().nullable().optional(),
13001
+ /** Who surfaced it first ("client_reported" | "proactive"). */
13002
+ sourceKind: z.string().nullable().optional(),
13003
+ /** Prior blocked assets in the same relaunch family. */
13004
+ relaunchCount: z.number().nullable().optional(),
13005
+ /** Earliest sighting, ISO. */
13006
+ firstSeenAt: z.string().nullable().optional(),
13007
+ /**
13008
+ * Pre-computed hours from first sighting to confirmed removal, as a string
13009
+ * so it lands in the same allowlist as `numbers`. The model is forbidden
13010
+ * from doing arithmetic, so every duration it may cite is computed here.
13011
+ */
13012
+ timeToRemovalHrs: z.string().nullable().optional()
13013
+ });
13014
+ var onePagerStorySchema = z.object({
13015
+ archetypeId: z.string(),
13016
+ archetypeCategory: z.string(),
13017
+ /** 1-5 = placed on the page; null = alternate available for swap. */
13018
+ slot: z.number().int().min(1).max(5).nullable(),
13019
+ /** Column layout the story occupies; slot 1 is full-width by convention. */
13020
+ layout: z.enum(["full", "half"]).default("half"),
13021
+ frontLabel: z.string().max(ONE_PAGER_BUDGETS.frontLabel),
13022
+ headline: z.string().max(ONE_PAGER_BUDGETS.headline),
13023
+ /** Compound "10 of 10 removed · 3 hrs". */
13024
+ badge: z.string().max(ONE_PAGER_BUDGETS.badge),
13025
+ paragraphs: z.array(z.string().max(ONE_PAGER_STORED_MAX.paragraph)).min(1).max(ONE_PAGER_BUDGETS.paragraphsMax),
13026
+ /** Bold lead-in shown ahead of the second paragraph. */
13027
+ paragraph2Lead: z.string().max(ONE_PAGER_STORED_MAX.paragraph2Lead).nullable().default(null),
13028
+ /** Defanged, display-ready asset identifiers. */
13029
+ assetList: z.array(z.string()).max(12),
13030
+ /** Story-bank identity for the referenced assets. */
13031
+ assetIds: z.array(z.number()).default([]),
13032
+ screenshotUrls: z.array(z.string()),
13033
+ selectedScreenshotUrls: z.array(z.string()).max(2),
13034
+ /** Parallel to selectedScreenshotUrls. */
13035
+ screenshotCaptions: z.array(z.string().max(ONE_PAGER_BUDGETS.screenshotCaption)).max(2).default([]),
13036
+ /** Manual redact toggle, parallel to selectedScreenshotUrls. */
13037
+ screenshotBlur: z.array(z.boolean()).max(2).default([]),
13038
+ xp01Line: z.string().max(ONE_PAGER_BUDGETS.xp01Line).nullable(),
13039
+ factPayload: onePagerFactPayloadSchema,
13040
+ proseSource: z.enum(["llm", "template"]),
13041
+ /** Cross-period continuation framing. */
13042
+ continuation: z.boolean().default(false),
13043
+ /** Shown in the editor when this story overlaps with a prior period. */
13044
+ priorHeadline: z.string().nullable().default(null)
13045
+ });
13046
+ var onePagerLandscapeRowSchema = z.object({
13047
+ platform: z.string(),
13048
+ count: z.number(),
13049
+ sharePct: z.number()
13050
+ });
13051
+ var onePagerFormDataObjectSchema = z.object({
13052
+ orgName: z.string(),
13053
+ orgSlug: z.string(),
13054
+ periodLabel: z.string(),
13055
+ partnershipLabel: z.string().max(40).default("AN ONGOING PARTNERSHIP"),
13056
+ coverageWindow: z.object({ start: z.string(), end: z.string(), label: z.string(), short: z.boolean() }).nullable().default(null),
13057
+ heroStat: z.object({
13058
+ value: z.string(),
13059
+ phrase: z.string().max(ONE_PAGER_BUDGETS.heroPhrase)
13060
+ }),
13061
+ heroNarrative: z.string().max(ONE_PAGER_STORED_MAX.heroNarrative),
13062
+ /**
13063
+ * Up to 4 rows, but the metric library legitimately returns fewer on a thin
13064
+ * month (a zero-valued metric is excluded outright rather than rendered as
13065
+ * a "0" row), so this is a range, not a fixed length. Below 2 the block
13066
+ * reads as broken rather than short.
13067
+ */
13068
+ metricsRows: z.array(
13069
+ z.object({
13070
+ key: z.string().default("legacy"),
13071
+ label: z.string(),
13072
+ value: z.string()
13073
+ })
13074
+ ).min(2).max(4),
13075
+ landscape: z.object({
13076
+ rows: z.array(onePagerLandscapeRowSchema).max(8),
13077
+ otherCount: z.number().nullable(),
13078
+ otherPlatformsLabel: z.string().nullable(),
13079
+ /** Kept for legacy row parse; caption is preferred going forward. */
13080
+ divergenceLine: z.string().max(ONE_PAGER_BUDGETS.divergenceLine).nullable(),
13081
+ caption: z.string().max(ONE_PAGER_BUDGETS.landscapeCaption).nullable().default(null)
13082
+ }),
13083
+ stories: z.array(onePagerStorySchema).min(1).max(6),
13084
+ footer: z.object({
13085
+ contactName: z.string(),
13086
+ contactLine: z.string(),
13087
+ contactEmail: z.string().default(""),
13088
+ bookingLink: z.string().default(""),
13089
+ ctaLine: z.string().default("Anything your community has flagged, send it over.")
13090
+ }),
13091
+ /** Engine v2 writes 2; absent/older rows default to 1. */
13092
+ schemaVersion: z.number().default(1)
13093
+ });
13094
+ onePagerFormDataObjectSchema.refine(
13095
+ (data) => data.stories.some((s2) => s2.slot !== null),
13096
+ { message: "at least one story must be placed", path: ["stories"] }
13097
+ );
13098
+ var INTERNAL_ORG_SLUGS = [
13099
+ "chainpatrol",
13100
+ "chainpatrol-automation",
13101
+ "mountaintop"
13102
+ ];
13103
+ new Set(INTERNAL_ORG_SLUGS);
12674
13104
  z.object({
12675
13105
  x: z.number().min(0).max(1),
12676
13106
  y: z.number().min(0).max(1),
@@ -13436,20 +13866,20 @@ var convertA98ToXyz65_default = convertA98ToXyz65;
13436
13866
 
13437
13867
  // ../../node_modules/culori/src/a98/convertXyz65ToA98.js
13438
13868
  var gamma = (v) => Math.pow(Math.abs(v), 256 / 563) * Math.sign(v);
13439
- var convertXyz65ToA98 = ({ x, y, z: z56, alpha }) => {
13869
+ var convertXyz65ToA98 = ({ x, y, z: z64, alpha }) => {
13440
13870
  if (x === void 0) x = 0;
13441
13871
  if (y === void 0) y = 0;
13442
- if (z56 === void 0) z56 = 0;
13872
+ if (z64 === void 0) z64 = 0;
13443
13873
  let res = {
13444
13874
  mode: "a98",
13445
13875
  r: gamma(
13446
- x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z56
13876
+ x * 2.0415879038107465 - y * 0.5650069742788597 - 0.3447313507783297 * z64
13447
13877
  ),
13448
13878
  g: gamma(
13449
- x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z56
13879
+ x * -0.9692436362808798 + y * 1.8759675015077206 + 0.0415550574071756 * z64
13450
13880
  ),
13451
13881
  b: gamma(
13452
- x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z56
13882
+ x * 0.0134442806320312 - y * 0.1183623922310184 + 1.0151749943912058 * z64
13453
13883
  )
13454
13884
  };
13455
13885
  if (alpha !== void 0) {
@@ -13516,14 +13946,14 @@ var convertLrgbToRgb = ({ r, g, b, alpha }, mode = "rgb") => {
13516
13946
  var convertLrgbToRgb_default = convertLrgbToRgb;
13517
13947
 
13518
13948
  // ../../node_modules/culori/src/xyz65/convertXyz65ToRgb.js
13519
- var convertXyz65ToRgb = ({ x, y, z: z56, alpha }) => {
13949
+ var convertXyz65ToRgb = ({ x, y, z: z64, alpha }) => {
13520
13950
  if (x === void 0) x = 0;
13521
13951
  if (y === void 0) y = 0;
13522
- if (z56 === void 0) z56 = 0;
13952
+ if (z64 === void 0) z64 = 0;
13523
13953
  let res = convertLrgbToRgb_default({
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
13954
+ r: x * 3.2409699419045226 - y * 1.537383177570094 - 0.4986107602930034 * z64,
13955
+ g: x * -0.9692436362808796 + y * 1.8759675015077204 + 0.0415550574071756 * z64,
13956
+ b: x * 0.0556300796969936 - y * 0.2039769588889765 + 1.0569715142428784 * z64
13527
13957
  });
13528
13958
  if (alpha !== void 0) {
13529
13959
  res.alpha = alpha;
@@ -13773,13 +14203,13 @@ var convertLab65ToRgb_default = convertLab65ToRgb;
13773
14203
 
13774
14204
  // ../../node_modules/culori/src/lab65/convertXyz65ToLab65.js
13775
14205
  var f = (value) => value > e ? Math.cbrt(value) : (k * value + 16) / 116;
13776
- var convertXyz65ToLab65 = ({ x, y, z: z56, alpha }) => {
14206
+ var convertXyz65ToLab65 = ({ x, y, z: z64, alpha }) => {
13777
14207
  if (x === void 0) x = 0;
13778
14208
  if (y === void 0) y = 0;
13779
- if (z56 === void 0) z56 = 0;
14209
+ if (z64 === void 0) z64 = 0;
13780
14210
  let f0 = f(x / D65.X);
13781
14211
  let f1 = f(y / D65.Y);
13782
- let f22 = f(z56 / D65.Z);
14212
+ let f22 = f(z64 / D65.Z);
13783
14213
  let res = {
13784
14214
  mode: "lab65",
13785
14215
  l: 116 * f1 - 16,
@@ -14436,10 +14866,10 @@ var convertItpToXyz65_default = convertItpToXyz65;
14436
14866
 
14437
14867
  // ../../node_modules/culori/src/itp/convertXyz65ToItp.js
14438
14868
  var toAbs = (c2 = 0) => Math.max(c2 * YW, 0);
14439
- var convertXyz65ToItp = ({ x, y, z: z56, alpha }) => {
14869
+ var convertXyz65ToItp = ({ x, y, z: z64, alpha }) => {
14440
14870
  const absX = toAbs(x);
14441
14871
  const absY = toAbs(y);
14442
- const absZ = toAbs(z56);
14872
+ const absZ = toAbs(z64);
14443
14873
  const l2 = transferPqEncode(
14444
14874
  0.3592832590121217 * absX + 0.6976051147779502 * absY - 0.0358915932320289 * absZ
14445
14875
  );
@@ -14497,15 +14927,15 @@ var jabPqEncode = (v) => {
14497
14927
  return Math.pow((C1 + C2 * vn3) / (1 + C3 * vn3), p);
14498
14928
  };
14499
14929
  var abs = (v = 0) => Math.max(v * 203, 0);
14500
- var convertXyz65ToJab = ({ x, y, z: z56, alpha }) => {
14930
+ var convertXyz65ToJab = ({ x, y, z: z64, alpha }) => {
14501
14931
  x = abs(x);
14502
14932
  y = abs(y);
14503
- z56 = abs(z56);
14504
- let xp = 1.15 * x - 0.15 * z56;
14933
+ z64 = abs(z64);
14934
+ let xp = 1.15 * x - 0.15 * z64;
14505
14935
  let yp = 0.66 * y + 0.34 * x;
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);
14936
+ let l2 = jabPqEncode(0.41478972 * xp + 0.579999 * yp + 0.014648 * z64);
14937
+ let m = jabPqEncode(-0.20151 * xp + 1.120649 * yp + 0.0531008 * z64);
14938
+ let s2 = jabPqEncode(-0.0166008 * xp + 0.2648 * yp + 0.6684799 * z64);
14509
14939
  let i = (l2 + m) / 2;
14510
14940
  let res = {
14511
14941
  mode: "jab",
@@ -14691,14 +15121,14 @@ var convertLabToXyz50 = ({ l: l2, a, b, alpha }) => {
14691
15121
  var convertLabToXyz50_default = convertLabToXyz50;
14692
15122
 
14693
15123
  // ../../node_modules/culori/src/xyz50/convertXyz50ToRgb.js
14694
- var convertXyz50ToRgb = ({ x, y, z: z56, alpha }) => {
15124
+ var convertXyz50ToRgb = ({ x, y, z: z64, alpha }) => {
14695
15125
  if (x === void 0) x = 0;
14696
15126
  if (y === void 0) y = 0;
14697
- if (z56 === void 0) z56 = 0;
15127
+ if (z64 === void 0) z64 = 0;
14698
15128
  let res = convertLrgbToRgb_default({
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
15129
+ r: x * 3.1341359569958707 - y * 1.6173863321612538 - 0.4906619460083532 * z64,
15130
+ g: x * -0.978795502912089 + y * 1.916254567259524 + 0.03344273116131949 * z64,
15131
+ b: x * 0.07195537988411677 - y * 0.2289768264158322 + 1.405386058324125 * z64
14702
15132
  });
14703
15133
  if (alpha !== void 0) {
14704
15134
  res.alpha = alpha;
@@ -14729,13 +15159,13 @@ var convertRgbToXyz50_default = convertRgbToXyz50;
14729
15159
 
14730
15160
  // ../../node_modules/culori/src/lab/convertXyz50ToLab.js
14731
15161
  var f2 = (value) => value > e3 ? Math.cbrt(value) : (k3 * value + 16) / 116;
14732
- var convertXyz50ToLab = ({ x, y, z: z56, alpha }) => {
15162
+ var convertXyz50ToLab = ({ x, y, z: z64, alpha }) => {
14733
15163
  if (x === void 0) x = 0;
14734
15164
  if (y === void 0) y = 0;
14735
- if (z56 === void 0) z56 = 0;
15165
+ if (z64 === void 0) z64 = 0;
14736
15166
  let f0 = f2(x / D50.X);
14737
15167
  let f1 = f2(y / D50.Y);
14738
- let f22 = f2(z56 / D50.Z);
15168
+ let f22 = f2(z64 / D50.Z);
14739
15169
  let res = {
14740
15170
  mode: "lab",
14741
15171
  l: 116 * f1 - 16,
@@ -14970,18 +15400,18 @@ var convertLchuvToLuv = ({ l: l2, c: c2, h, alpha }) => {
14970
15400
  var convertLchuvToLuv_default = convertLchuvToLuv;
14971
15401
 
14972
15402
  // ../../node_modules/culori/src/luv/convertXyz50ToLuv.js
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);
15403
+ var u_fn = (x, y, z64) => 4 * x / (x + 15 * y + 3 * z64);
15404
+ var v_fn = (x, y, z64) => 9 * y / (x + 15 * y + 3 * z64);
14975
15405
  var un = u_fn(D50.X, D50.Y, D50.Z);
14976
15406
  var vn = v_fn(D50.X, D50.Y, D50.Z);
14977
15407
  var l_fn = (value) => value <= e3 ? k3 * value : 116 * Math.cbrt(value) - 16;
14978
- var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
15408
+ var convertXyz50ToLuv = ({ x, y, z: z64, alpha }) => {
14979
15409
  if (x === void 0) x = 0;
14980
15410
  if (y === void 0) y = 0;
14981
- if (z56 === void 0) z56 = 0;
15411
+ if (z64 === void 0) z64 = 0;
14982
15412
  let l2 = l_fn(y / D50.Y);
14983
- let u = u_fn(x, y, z56);
14984
- let v = v_fn(x, y, z56);
15413
+ let u = u_fn(x, y, z64);
15414
+ let v = v_fn(x, y, z64);
14985
15415
  if (!isFinite(u) || !isFinite(v)) {
14986
15416
  l2 = u = v = 0;
14987
15417
  } else {
@@ -15002,8 +15432,8 @@ var convertXyz50ToLuv = ({ x, y, z: z56, alpha }) => {
15002
15432
  var convertXyz50ToLuv_default = convertXyz50ToLuv;
15003
15433
 
15004
15434
  // ../../node_modules/culori/src/luv/convertLuvToXyz50.js
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);
15435
+ var u_fn2 = (x, y, z64) => 4 * x / (x + 15 * y + 3 * z64);
15436
+ var v_fn2 = (x, y, z64) => 9 * y / (x + 15 * y + 3 * z64);
15007
15437
  var un2 = u_fn2(D50.X, D50.Y, D50.Z);
15008
15438
  var vn2 = v_fn2(D50.X, D50.Y, D50.Z);
15009
15439
  var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
@@ -15017,8 +15447,8 @@ var convertLuvToXyz50 = ({ l: l2, u, v, alpha }) => {
15017
15447
  let vp = v / (13 * l2) + vn2;
15018
15448
  let y = D50.Y * (l2 <= 8 ? l2 / k3 : Math.pow((l2 + 16) / 116, 3));
15019
15449
  let x = y * (9 * up) / (4 * vp);
15020
- let z56 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
15021
- let res = { mode: "xyz50", x, y, z: z56 };
15450
+ let z64 = y * (12 - 3 * up - 20 * vp) / (4 * vp);
15451
+ let res = { mode: "xyz50", x, y, z: z64 };
15022
15452
  if (alpha !== void 0) {
15023
15453
  res.alpha = alpha;
15024
15454
  }
@@ -15635,15 +16065,15 @@ var convertP3ToXyz65 = (rgb2) => {
15635
16065
  var convertP3ToXyz65_default = convertP3ToXyz65;
15636
16066
 
15637
16067
  // ../../node_modules/culori/src/p3/convertXyz65ToP3.js
15638
- var convertXyz65ToP3 = ({ x, y, z: z56, alpha }) => {
16068
+ var convertXyz65ToP3 = ({ x, y, z: z64, alpha }) => {
15639
16069
  if (x === void 0) x = 0;
15640
16070
  if (y === void 0) y = 0;
15641
- if (z56 === void 0) z56 = 0;
16071
+ if (z64 === void 0) z64 = 0;
15642
16072
  let res = convertLrgbToRgb_default(
15643
16073
  {
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
16074
+ r: x * 2.4934969119414263 - y * 0.9313836179191242 - 0.402710784450717 * z64,
16075
+ g: x * -0.8294889695615749 + y * 1.7626640603183465 + 0.0236246858419436 * z64,
16076
+ b: x * 0.0358458302437845 - y * 0.0761723892680418 + 0.9568845240076871 * z64
15647
16077
  },
15648
16078
  "p3"
15649
16079
  );
@@ -15678,19 +16108,19 @@ var gamma2 = (v) => {
15678
16108
  }
15679
16109
  return 16 * v;
15680
16110
  };
15681
- var convertXyz50ToProphoto = ({ x, y, z: z56, alpha }) => {
16111
+ var convertXyz50ToProphoto = ({ x, y, z: z64, alpha }) => {
15682
16112
  if (x === void 0) x = 0;
15683
16113
  if (y === void 0) y = 0;
15684
- if (z56 === void 0) z56 = 0;
16114
+ if (z64 === void 0) z64 = 0;
15685
16115
  let res = {
15686
16116
  mode: "prophoto",
15687
16117
  r: gamma2(
15688
- x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z56
16118
+ x * 1.3457868816471585 - y * 0.2555720873797946 - 0.0511018649755453 * z64
15689
16119
  ),
15690
16120
  g: gamma2(
15691
- x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z56
16121
+ x * -0.5446307051249019 + y * 1.5082477428451466 + 0.0205274474364214 * z64
15692
16122
  ),
15693
- b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z56)
16123
+ b: gamma2(x * 0 + y * 0 + 1.2119675456389452 * z64)
15694
16124
  };
15695
16125
  if (alpha !== void 0) {
15696
16126
  res.alpha = alpha;
@@ -15750,20 +16180,20 @@ var gamma3 = (v) => {
15750
16180
  }
15751
16181
  return 4.5 * v;
15752
16182
  };
15753
- var convertXyz65ToRec2020 = ({ x, y, z: z56, alpha }) => {
16183
+ var convertXyz65ToRec2020 = ({ x, y, z: z64, alpha }) => {
15754
16184
  if (x === void 0) x = 0;
15755
16185
  if (y === void 0) y = 0;
15756
- if (z56 === void 0) z56 = 0;
16186
+ if (z64 === void 0) z64 = 0;
15757
16187
  let res = {
15758
16188
  mode: "rec2020",
15759
16189
  r: gamma3(
15760
- x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z56
16190
+ x * 1.7166511879712683 - y * 0.3556707837763925 - 0.2533662813736599 * z64
15761
16191
  ),
15762
16192
  g: gamma3(
15763
- x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z56
16193
+ x * -0.6666843518324893 + y * 1.6164812366349395 + 0.0157685458139111 * z64
15764
16194
  ),
15765
16195
  b: gamma3(
15766
- x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z56
16196
+ x * 0.0176398574453108 - y * 0.0427706132578085 + 0.9421031212354739 * z64
15767
16197
  )
15768
16198
  };
15769
16199
  if (alpha !== void 0) {
@@ -15916,15 +16346,15 @@ var definition_default26 = definition26;
15916
16346
 
15917
16347
  // ../../node_modules/culori/src/xyz65/convertXyz65ToXyz50.js
15918
16348
  var convertXyz65ToXyz50 = (xyz652) => {
15919
- let { x, y, z: z56, alpha } = xyz652;
16349
+ let { x, y, z: z64, alpha } = xyz652;
15920
16350
  if (x === void 0) x = 0;
15921
16351
  if (y === void 0) y = 0;
15922
- if (z56 === void 0) z56 = 0;
16352
+ if (z64 === void 0) z64 = 0;
15923
16353
  let res = {
15924
16354
  mode: "xyz50",
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
16355
+ x: 1.0479298208405488 * x + 0.0229467933410191 * y - 0.0501922295431356 * z64,
16356
+ y: 0.0296278156881593 * x + 0.990434484573249 * y - 0.0170738250293851 * z64,
16357
+ z: -0.0092430581525912 * x + 0.0150551448965779 * y + 0.7518742899580008 * z64
15928
16358
  };
15929
16359
  if (alpha !== void 0) {
15930
16360
  res.alpha = alpha;
@@ -15935,15 +16365,15 @@ var convertXyz65ToXyz50_default = convertXyz65ToXyz50;
15935
16365
 
15936
16366
  // ../../node_modules/culori/src/xyz65/convertXyz50ToXyz65.js
15937
16367
  var convertXyz50ToXyz65 = (xyz502) => {
15938
- let { x, y, z: z56, alpha } = xyz502;
16368
+ let { x, y, z: z64, alpha } = xyz502;
15939
16369
  if (x === void 0) x = 0;
15940
16370
  if (y === void 0) y = 0;
15941
- if (z56 === void 0) z56 = 0;
16371
+ if (z64 === void 0) z64 = 0;
15942
16372
  let res = {
15943
16373
  mode: "xyz65",
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
16374
+ x: 0.9554734527042182 * x - 0.0230985368742614 * y + 0.0632593086610217 * z64,
16375
+ y: -0.0283697069632081 * x + 1.0099954580058226 * y + 0.021041398966943 * z64,
16376
+ z: 0.0123140016883199 * x - 0.0205076964334779 * y + 1.3303659366080753 * z64
15947
16377
  };
15948
16378
  if (alpha !== void 0) {
15949
16379
  res.alpha = alpha;
@@ -16180,6 +16610,13 @@ function validateTermsString(termsString) {
16180
16610
  };
16181
16611
  }
16182
16612
  } else {
16613
+ if (term.startsWith("*") || term.endsWith("*")) {
16614
+ const inner = term.replace(/^\*+|\*+$/g, "");
16615
+ return {
16616
+ valid: false,
16617
+ error: `Term "${term}" has an unmatched asterisk. Use *${inner}* for exact matching, or ${inner} for loose matching.`
16618
+ };
16619
+ }
16183
16620
  normalizedTerm = term.replace(/\s+/g, "");
16184
16621
  if (normalizedTerm.length < 6) {
16185
16622
  return {
@@ -16777,6 +17214,8 @@ var SCAN_TEMPLATES = [
16777
17214
  new Map(
16778
17215
  SCAN_TEMPLATES.map((template) => [template.id, template])
16779
17216
  );
17217
+ var DARK_WEB_ENTITY_SEARCH_KINDS = ["domain", "email", "crypto"];
17218
+ z.enum(DARK_WEB_ENTITY_SEARCH_KINDS);
16780
17219
 
16781
17220
  // src/client.ts
16782
17221
  function trimTrailingSlashes(url) {