calmlens 0.1.1 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/sig/calmlens.rbs CHANGED
@@ -22,17 +22,18 @@ module CalmLens
22
22
 
23
23
  class Error < StandardError
24
24
  attr_reader code: String
25
- # Extra details from the API error body (any JSON), plus `"network" => true` for API errors.
26
- attr_reader details: Hash[String, json_value]
25
+ # The API error's details (any JSON), such as validation `issues`, or nil when it has none.
26
+ attr_reader details: Hash[String, json_value]?
27
27
  attr_reader status: Integer?
28
28
  attr_reader request_id: String?
29
29
  attr_reader headers: Hash[String, String]
30
- def initialize: (String code, ?String? message, ?details: Hash[String, json_value], ?status: Integer?,
30
+ def initialize: (String code, ?String? message, ?details: Hash[String, json_value]?, ?status: Integer?,
31
31
  ?headers: Hash[String, String], ?request_id: String?) -> void
32
- def retry_after: () -> Float?
32
+ # Whole seconds from the `Retry-After` header.
33
+ def retry_after: () -> Integer?
33
34
  def not_found?: () -> bool
34
35
  def retryable?: () -> bool
35
- def self.build: (String code, ?String? message, ?status: Integer?, ?details: Hash[String, json_value],
36
+ def self.build: (String code, ?String? message, ?status: Integer?, ?details: Hash[String, json_value]?,
36
37
  ?headers: Hash[String, String], ?request_id: String?) -> Error
37
38
  end
38
39
  class APIError < Error end
@@ -101,8 +102,17 @@ module CalmLens
101
102
  class ServerClient
102
103
  DEFAULT_BASE_URL: String
103
104
  DEFAULT_CDN_BASE_URL: String
105
+ DEFAULT_TIMEOUT: Integer
106
+ DEFAULT_OPEN_TIMEOUT: Integer
107
+ DEFAULT_MAX_RETRIES: Integer
108
+ DEFAULT_RETRY_BASE_DELAY: Float
109
+ RETRY_MAX_DELAY: Integer
110
+ RETRY_AFTER_MAX: Integer
111
+ DEFAULT_MAX_RESPONSE_BYTES: Integer
112
+ ENSURE_LENSES_MAX_PER_REQUEST: Integer
104
113
  attr_reader assets: Assets
105
114
  attr_reader folders: Folders
115
+ attr_reader hash_lists: HashLists
106
116
  attr_reader text: Text
107
117
  attr_reader upload_tokens: UploadTokens
108
118
  attr_reader events: Events
@@ -111,8 +121,8 @@ module CalmLens
111
121
  attr_reader base_url: String
112
122
  attr_reader cdn_base_url: String
113
123
  def initialize: (api_key: String, project_id: String, ?base_url: String, ?cdn_base_url: String, ?timeout: number,
114
- ?open_timeout: number, ?max_retries: Integer, ?retry_base_delay: number,
115
- ?transport: Transport::_Transport?) -> void
124
+ ?open_timeout: number, ?upload_timeout: number?, ?max_retries: Integer, ?retry_base_delay: number,
125
+ ?max_response_bytes: Integer, ?transport: Transport::_Transport?) -> void
116
126
  def close: () -> nil
117
127
  def ensure_lenses: (ensure_lenses_options options) -> Array[lens]
118
128
  def ensure_lens: (ensure_lens_options options) -> lens
@@ -123,11 +133,29 @@ module CalmLens
123
133
  private def initialize: (untyped session) -> void
124
134
  end
125
135
 
136
+ # The earlier posts CalmLens uses from an upload's `context`.
137
+ module ModerationContext
138
+ # The most recent earlier posts CalmLens uses.
139
+ USED_ITEMS: Integer
140
+ # The most characters (Unicode code points) of earlier posts CalmLens uses.
141
+ USED_CHARACTERS: Integer
142
+ # The most recent posts within USED_ITEMS and USED_CHARACTERS, oldest first; the newest is always kept.
143
+ def self.select_items: (Array[moderation_context_item_input | Hash[String | Symbol, untyped]] items) -> Array[moderation_context_item]
144
+ end
145
+
126
146
  class Assets < Resource
127
- # Moderation statuses that carry a decision.
128
- DECIDED_MODERATION_STATUSES: Array[String]
147
+ # The moderation status before a decision.
148
+ PENDING_MODERATION_STATUS: String
129
149
  # Processing statuses after which no decision arrives without a retry.
130
150
  FINISHED_PROCESSING_STATUSES: Array[String]
151
+ DECISION_POLL_FIRST_DELAY: Float
152
+ DECISION_POLL_FACTOR: Float
153
+ DECISION_POLL_MAX_DELAY: Float
154
+ DEFAULT_DECISION_TIMEOUT: Integer
155
+ DEFAULT_SIGNED_URL_SECONDS: Integer
156
+ MAX_SIGNED_URL_SECONDS: Integer
157
+ BATCH_OPERATIONS: Array[asset_batch_operation]
158
+ MAX_BATCH_ASSETS: Integer
131
159
 
132
160
  def search: (asset_search_options options) -> asset_search_response
133
161
  def list: (?list_assets_options options) -> asset_page
@@ -140,17 +168,20 @@ module CalmLens
140
168
  def wait_for_decision: (wait_for_decision_options options) -> asset
141
169
  def update: (update_asset_options options) -> asset
142
170
  def retry: (asset_id_options options) -> asset
171
+ def decide: (decide_asset_options options) -> asset
172
+ def explain: (explain_asset_options options) -> asset
143
173
  def delete_content: (asset_id_options options) -> asset
144
174
  def delete: (asset_id_options options) -> nil
175
+ def batch: (batch_assets_options options) -> batch_assets_response
145
176
  def move: (move_asset_options options) -> asset
146
177
  def create_signed_url: (create_signed_url_options options) -> signed_url
147
178
  def create: (upload_options options) -> asset
148
- def moderate: (upload_options options) -> asset
179
+ def classify: (upload_options options) -> asset
149
180
  def upload_part: (upload_part_options options) -> asset
150
181
  end
151
182
 
152
183
  class Folders < Resource
153
- def list: (?list_folders_options options) -> Array[folder]
184
+ def list: (?list_folders_options options) -> folder_page
154
185
  def create: (create_folder_options options) -> folder
155
186
  def retrieve: (folder_id_options options) -> folder
156
187
  def update: (update_folder_options options) -> folder
@@ -158,6 +189,17 @@ module CalmLens
158
189
  def delete: (folder_id_options options) -> nil
159
190
  end
160
191
 
192
+ class HashLists < Resource
193
+ def list: (?list_hash_lists_options options) -> hash_list_page
194
+ def retrieve: (hash_list_id_options options) -> hash_list
195
+ def create: (create_hash_list_options options) -> hash_list
196
+ def update: (update_hash_list_options options) -> hash_list
197
+ def delete: (hash_list_id_options options) -> nil
198
+ def list_entries: (list_hash_list_entries_options options) -> hash_list_entry_page
199
+ def add_entry: (add_hash_list_entry_options options) -> hash_list_entry
200
+ def remove_entry: (hash_list_entry_id_options options) -> nil
201
+ end
202
+
161
203
  class UploadTokens < Resource
162
204
  TOKEN_PREFIX: String
163
205
  SIGNING_CONTEXT: String
@@ -169,7 +211,7 @@ module CalmLens
169
211
 
170
212
  class Text < Resource
171
213
  private def initialize: (untyped session, Assets assets) -> void
172
- def moderate: (moderate_text_options options) -> asset
214
+ def classify: (moderate_text_options options) -> asset
173
215
  end
174
216
 
175
217
  class Events < Resource
@@ -186,36 +228,65 @@ module CalmLens
186
228
  | [T] (serve_options options) { (Response) -> T } -> T
187
229
  end
188
230
 
231
+ # A verified webhook delivery, with the fields of an `events.list` item.
189
232
  class WebhookEvent < Struct[untyped]
190
233
  attr_accessor id: String
191
- attr_accessor type: event_type
234
+ attr_accessor project_id: String
235
+ # New types may appear: ignore unknown ones.
236
+ attr_accessor type: event_type | String
237
+ attr_accessor severity: event_severity?
238
+ attr_accessor title: String?
239
+ attr_accessor description: String?
240
+ attr_accessor asset_id: String?
241
+ attr_accessor asset: event_asset?
242
+ attr_accessor facts: Array[event_fact]
192
243
  # Milliseconds since the Unix epoch.
193
244
  attr_accessor created_at: Integer
194
- attr_accessor project_id: String
195
- attr_accessor data: webhook_event_data
196
- def initialize: (id: String, type: event_type, created_at: Integer, project_id: String, data: webhook_event_data) -> void
197
- def asset_id: () -> String?
198
- def facts: () -> Array[event_fact]
245
+ # The delivery body as received, with every field.
246
+ attr_accessor payload: Hash[String, json_value]
247
+ def initialize: (?id: String, ?project_id: String, ?type: event_type | String, ?severity: event_severity?, ?title: String?,
248
+ ?description: String?, ?asset_id: String?, ?asset: event_asset?, ?facts: Array[event_fact],
249
+ ?created_at: Integer, ?payload: Hash[String, json_value]) -> void
199
250
  def test?: () -> bool
251
+ # The delivery body as received, with every field.
252
+ def to_payload: () -> Hash[String, json_value]
253
+ end
254
+
255
+ # Request headers to read webhook headers from: names in any case, repeated values as an Array
256
+ # (`Net::HTTPHeader#to_hash`), or a Rack env.
257
+ type webhook_headers = Hash[String | Symbol, String | Array[String]] | _ToHash
258
+
259
+ interface _ToHash
260
+ def to_hash: () -> Hash[String, String | Array[String]]
200
261
  end
201
262
 
202
263
  module Webhooks
203
264
  def self.signature_header: (payload: String, timestamp: String | Integer, secret: String) -> String
204
- def self.verify: (payload: String, signature: String?, timestamp: String?, secret: String, ?tolerance_seconds: Integer,
205
- ?now: number) -> bool
206
- def self.parse_event: (payload: String, signature: String?, timestamp: String?, secret: String,
265
+ def self.headers: (payload: String, delivery_id: String, secret: String, ?timestamp: Integer) -> Hash[String, String]
266
+ def self.to_payload: (event event) -> event
267
+ def self.verify: (payload: String, secret: String, ?signature: String?, ?timestamp: String?, ?headers: webhook_headers?,
268
+ ?tolerance_seconds: Integer, ?now: number) -> bool
269
+ def self.verify_request: (payload: String, headers: webhook_headers, secret: String, ?tolerance_seconds: Integer,
270
+ ?now: number) -> bool
271
+ def self.parse_event: (payload: String, secret: String, ?signature: String?, ?timestamp: String?, ?headers: webhook_headers?,
207
272
  ?tolerance_seconds: Integer, ?now: number) -> WebhookEvent
273
+ def self.test_event?: (WebhookEvent | Hash[String, untyped] event) -> bool
208
274
  end
209
275
 
210
276
  def self.create_webhook_signature_header: (payload: String, timestamp: String | Integer, secret: String) -> String
211
- def self.verify_webhook_signature: (payload: String, signature: String?, timestamp: String?, secret: String,
212
- ?tolerance_seconds: Integer, ?now: number) -> bool
213
- def self.parse_webhook_event: (payload: String, signature: String?, timestamp: String?, secret: String,
214
- ?tolerance_seconds: Integer, ?now: number) -> WebhookEvent
277
+ def self.create_webhook_headers: (payload: String, delivery_id: String, secret: String, ?timestamp: Integer) -> Hash[String, String]
278
+ def self.to_webhook_event_payload: (event event) -> event
279
+ def self.verify_webhook_signature: (payload: String, secret: String, ?signature: String?, ?timestamp: String?,
280
+ ?headers: webhook_headers?, ?tolerance_seconds: Integer, ?now: number) -> bool
281
+ def self.verify_webhook_request: (payload: String, headers: webhook_headers, secret: String, ?tolerance_seconds: Integer,
282
+ ?now: number) -> bool
283
+ def self.parse_webhook_event: (payload: String, secret: String, ?signature: String?, ?timestamp: String?,
284
+ ?headers: webhook_headers?, ?tolerance_seconds: Integer, ?now: number) -> WebhookEvent
285
+ def self.test_webhook_event?: (WebhookEvent | Hash[String, untyped] event) -> bool
215
286
 
216
287
  # require 'calmlens/testing'
217
288
  module Testing
218
- # The mock's in-memory records. Change them to arrange a test, such as setting an asset's `moderation.status`.
289
+ # The mock's in-memory records. Change them to arrange a test, such as setting an asset's `classification.moderation.status`.
219
290
  class State < Struct[untyped]
220
291
  attr_accessor assets: Hash[String, asset]
221
292
  attr_accessor folders: Hash[String, folder]
@@ -223,6 +294,8 @@ module CalmLens
223
294
  attr_accessor content: Hash[String, { "type" => String, "parts" => Hash[Integer, String] }]
224
295
  attr_accessor events: Array[event]
225
296
  attr_accessor lenses: Hash[String, lens]
297
+ attr_accessor hash_lists: Hash[String, hash_list]
298
+ attr_accessor hash_list_entries: Hash[String, hash_list_entry]
226
299
  end
227
300
  end
228
301
 
@@ -234,6 +307,8 @@ module CalmLens
234
307
  attr_accessor query: Hash[String, String]
235
308
  attr_accessor headers: Hash[String, String]
236
309
  attr_accessor body: String?
310
+ # The HTTP status the mock answered with; nil when the request failed without a response.
311
+ attr_accessor status: Integer?
237
312
  def json: () -> json_value
238
313
  end
239
314
 
@@ -243,31 +318,85 @@ module CalmLens
243
318
  end
244
319
 
245
320
  interface _IdFactory
246
- def call: () -> String
321
+ def call: (String prefix) -> String
247
322
  end
248
323
 
249
- # Where a mock upload ends up: `pending` (still processing), `approved` or `rejected`
250
- # (processing done with that decision), or `failed` (processing failed, retryable).
251
- type outcome = "pending" | "approved" | "rejected" | "failed"
324
+ # Decides each asset the mock moderates: a status or a MockDecision.
325
+ interface _Moderate
326
+ def call: (MockModerationInput input) -> (MockDecision::status | MockDecision)
327
+ end
252
328
 
253
- # An outcome, fields to deep-merge into the asset, or a callable that receives a copy of the
254
- # asset and returns either.
255
- type analyzed_outcome = outcome | Hash[String, json_input] | _AnalyzedOutcome
329
+ API_KEY_PREFIX: String
256
330
 
257
- interface _AnalyzedOutcome
258
- def call: (asset asset) -> (String | Hash[String, json_input])
259
- end
331
+ # A mock API key carrying permission grants, such as `assets:download` for CDN reads.
332
+ def self.create_api_key: (?Array[Hash[Symbol | String, untyped]] grants) -> String
333
+ # Signs an upload token like UploadTokens#sign at `now` (epoch milliseconds) with `nonce`.
334
+ def self.sign_upload_token: (String api_key, sign_upload_token_options options, now: Integer, nonce: String) -> signed_upload_token
260
335
 
261
- def initialize: (?project_id: String, ?base_url: String, ?cdn_base_url: String, ?now: _Clock, ?create_id: _IdFactory,
262
- ?queued_outcome: outcome, ?analyzed_outcome: analyzed_outcome, ?timeout: number,
263
- ?open_timeout: number, ?max_retries: Integer, ?retry_base_delay: number) -> void
336
+ REQUEST_FAILURES: Array[String]
337
+
338
+ def initialize: (?project_id: String, ?api_key: String, ?base_url: String, ?cdn_base_url: String, ?now: _Clock, ?create_id: _IdFactory,
339
+ ?moderate: _Moderate?, ?timeout: number,
340
+ ?open_timeout: number, ?upload_timeout: number?, ?max_retries: Integer, ?retry_base_delay: number,
341
+ ?max_response_bytes: Integer) -> void
342
+ # Replaces the mock API key's grants for later requests; the key stays the same.
343
+ def api_key_grants=: (Array[Hash[Symbol | String, untyped]] grants) -> Array[Hash[Symbol | String, untyped]]
344
+ # Fails the next request (or the next one `operation` sends) with `transport-error`, `timeout`, an
345
+ # API error code (with optional `details` and `Retry-After` seconds) or an exception.
346
+ def fail_next_request: (?(String | Exception) failure, ?operation: String?, ?details: Hash[String | Symbol, untyped]?,
347
+ ?retry_after: Integer?) -> self
264
348
  def state: () -> Testing::State
265
349
  # `body` is any JSON value, encoded as the response body.
266
350
  def enqueue: (body: json_input, ?status: Integer, ?headers: Hash[String, String]) -> self
267
351
  def enqueue_raw: (body: String, ?status: Integer, ?headers: Hash[String, String]) -> self
268
352
  def enqueue_error: (Exception error) -> self
269
353
  def enqueue_event: (mock_event_input event) -> event
354
+ # Applies a reviewer's decision and adds the matching `asset.<decision>` event.
355
+ def decide: (String asset_id, asset_moderation_decision decision) -> asset
356
+ # Finishes processing an asset as the moderation pipeline would, with `decision` or else `moderate`'s answer.
357
+ def complete_processing: (String asset_id, ?(MockDecision::status | MockDecision)? decision) -> asset
270
358
  def requests: () -> Array[Request]
359
+ def clear_requests: () -> self
271
360
  def remaining_responses: () -> Integer
272
361
  end
362
+
363
+ # A moderation decision for MockServerClient's `moderate:` option or `complete_processing`.
364
+ class MockDecision
365
+ # `pending`, `failed` or a decided moderation status.
366
+ type status = "pending" | "failed" | asset_moderation_decision
367
+
368
+ STATUSES: Array[String]
369
+
370
+ def self.of: (status status) -> MockDecision
371
+ def initialize: (status status) -> void
372
+ def status: () -> status
373
+ # Flags `category` with a score from 0 to 1 and optional qualifier scores.
374
+ def flag: (String | Symbol category, Numeric score, ?Hash[String | Symbol, Numeric] qualifiers) -> self
375
+ def not_evaluated: (String | Symbol category) -> self
376
+ # The `categories`, `score` and `policy` a decided asset gets; nil for `pending` and `failed`.
377
+ def report: () -> Hash[String, json_value]?
378
+ end
379
+
380
+ # What MockServerClient's `moderate:` callback receives.
381
+ class MockModerationInput < Struct[untyped]
382
+ class Content < Struct[untyped]
383
+ # The uploaded bytes; nil without stored content.
384
+ attr_accessor bytes: String?
385
+ # The bytes as UTF-8 text, for a `plaintext-document`.
386
+ attr_accessor text: String?
387
+ end
388
+
389
+ # The stored asset, still processing.
390
+ attr_accessor asset: asset
391
+ attr_accessor content: Content
392
+ attr_accessor trigger: "upload" | "retry" | "rerun" | "complete"
393
+ attr_accessor queued: bool
394
+ def queued?: () -> bool
395
+ end
396
+
397
+ # The categories and qualifiers MockDecision accepts.
398
+ module MockClassification
399
+ CATEGORIES: Array[String]
400
+ QUALIFIERS: Hash[String, Array[String]]
401
+ end
273
402
  end
data/sig/error_codes.rbs CHANGED
@@ -2,20 +2,44 @@
2
2
  # packages/shared/src/PublicErrorCodes.ts. test/signature_test.rb fails when the two differ.
3
3
  module CalmLens
4
4
  module ErrorCodes
5
+ INVALID_VIEWER_CLAIMS: String
6
+ AGE_CONFIRMATION_REQUIRED: String
7
+ INVALID_VIEWER_REGION: String
8
+ VIEWER_REGION_REQUIRED: String
9
+ REGIONAL_EVIDENCE_REQUIRED: String
10
+ INVALID_TYPE: String
11
+ TOO_SMALL: String
12
+ TOO_BIG: String
13
+ INVALID_FORMAT: String
14
+ INVALID_VALUE: String
15
+ UNKNOWN_FIELD: String
16
+ UNSUPPORTED_CONTENT_TYPE: String
17
+ INVALID_FILTER: String
18
+ INVALID_ORDERING_FIELD: String
19
+ ROUTE_NOT_FOUND: String
20
+ INTERNAL_ERROR: String
21
+ UNAUTHENTICATED: String
22
+ TOKEN_EXPIRED: String
23
+ INVALID_TOKEN: String
24
+ SEARCH_UNAVAILABLE: String
25
+ INVALID_TRANSFORM: String
26
+ INVALID_TRANSFORM_OPTIONS: String
27
+ REMOTE_URL_REDIRECT_LIMIT: String
28
+ COPYRIGHT_CONTENT_HELD: String
29
+ DOWNLOAD_PERMISSION_REQUIRED: String
5
30
  INVALID_CURSOR: String
6
31
  MISSING_TOKEN: String
7
32
  INVALID_API_KEY: String
8
33
  API_KEY_PROJECT_MISMATCH: String
9
34
  API_KEY_NOT_ACCEPTED: String
35
+ PERMISSION_DENIED: String
10
36
  FILE_TOO_LARGE: String
11
- IMAGE_REQUIRES_MULTIPART_UPLOAD: String
12
37
  MULTIPART_IMAGE_TOO_SMALL: String
13
38
  MULTIPART_IMAGE_TOO_LARGE: String
14
39
  IMAGE_EXCEEDED_MAX_DIMENSIONS: String
15
40
  UPLOAD_LIMIT_EXCEEDED: String
16
41
  SPEND_LIMIT_REACHED: String
17
42
  INVALID_UPLOAD_MIME_TYPE: String
18
- INVALID_EVENT_CURSOR: String
19
43
  INVALID_UPLOAD_PAYLOAD: String
20
44
  USE_UPLOAD_PART: String
21
45
  UPLOAD_NOT_OPEN: String
@@ -27,10 +51,19 @@ module CalmLens
27
51
  IDEMPOTENT_REQUEST_IN_PROGRESS: String
28
52
  ASSET_NOT_FOUND: String
29
53
  PROJECT_NOT_FOUND: String
54
+ ASSET_REVIEW_CHANGED: String
55
+ ASSET_REVIEW_NOTE_REQUIRED: String
30
56
  ASSET_UPDATE_FAILED: String
31
57
  ASSET_SAFETY_HELD: String
58
+ ASSET_PROCESSING: String
59
+ ASSET_DECISION_NOT_ALLOWED: String
60
+ ASSET_DECISION_UNCHANGED: String
32
61
  ASSET_NOT_RETRYABLE: String
33
62
  ASSET_CONTENT_UNAVAILABLE: String
63
+ ASSET_CONTENT_PURGED: String
64
+ ASSET_NOT_DECIDED: String
65
+ ASSET_POLICY_CHANGED: String
66
+ ASSET_REVIEWED: String
34
67
  SUPPORT_TICKET_NOT_FOUND: String
35
68
  DUPLICATE_EXTERNAL_ID: String
36
69
  FOLDER_NOT_FOUND: String
@@ -38,6 +71,12 @@ module CalmLens
38
71
  FOLDER_NOT_EMPTY: String
39
72
  FOLDER_PARENT_CYCLE: String
40
73
  LENS_VERSION_CONFLICT: String
74
+ LENS_IDENTIFIER_RESERVED: String
75
+ HASH_LIST_NOT_FOUND: String
76
+ HASH_LIST_ENTRY_NOT_FOUND: String
77
+ HASH_LIST_LIMIT_REACHED: String
78
+ HASH_LIST_ENTRY_LIMIT_REACHED: String
79
+ HASH_LIST_ASSET_NOT_HASHED: String
41
80
  UPLOAD_PRESET_NOT_FOUND: String
42
81
  UPLOAD_PRESET_DISABLED: String
43
82
  UPLOAD_PRESET_TOKEN_REQUIRED: String
@@ -0,0 +1,141 @@
1
+ # Generated by packages/sdk-contract/generate.ts from packages/shared/src/ModerationPolicyDimensions.ts; do not edit.
2
+ module CalmLens
3
+ # The keys of a category's qualifiers.
4
+ type qualifier_results = {
5
+ ?"sexual-pornographic-media" => qualifier_result,
6
+ ?"hate-nazi-symbols-public-display" => qualifier_result,
7
+ ?"hate-nazi-insignia-public-display" => qualifier_result,
8
+ ?"hate-nazi-genocide-public-peace" => qualifier_result,
9
+ ?"hate-nazi-genocide-denial-or-approval" => qualifier_result,
10
+ ?"hate-adjudicated-nazi-crimes-denial" => qualifier_result,
11
+ ?"violence-high-impact" => qualifier_result,
12
+ ?"self-harm-age-restricted" => qualifier_result,
13
+ ?"personal-information-contact" => qualifier_result,
14
+ ?"personal-information-email" => qualifier_result,
15
+ ?"personal-information-phone" => qualifier_result,
16
+ ?"personal-information-government-id" => qualifier_result,
17
+ ?"personal-information-financial" => qualifier_result,
18
+ ?"personal-information-location" => qualifier_result,
19
+ ?"personal-information-identifiers" => qualifier_result,
20
+ ?"personal-information-credentials" => qualifier_result,
21
+ ?"personal-information-request" => qualifier_result,
22
+ ?"personal-information-self-disclosure" => qualifier_result,
23
+ ?"personal-information-third-party" => qualifier_result,
24
+ ?"personal-information-historical" => qualifier_result,
25
+ ?"personal-information-documentary" => qualifier_result,
26
+ ?"personal-information-educational" => qualifier_result,
27
+ ?"personal-information-fictional" => qualifier_result,
28
+ ?"personal-information-support-prevention" => qualifier_result,
29
+ ?"profanity-mild" => qualifier_result,
30
+ ?"profanity-strong" => qualifier_result,
31
+ ?"profanity-slurs" => qualifier_result,
32
+ ?"profanity-obfuscated" => qualifier_result,
33
+ ?"profanity-historical" => qualifier_result,
34
+ ?"profanity-documentary" => qualifier_result,
35
+ ?"profanity-educational" => qualifier_result,
36
+ ?"profanity-fictional" => qualifier_result,
37
+ ?"profanity-support-prevention" => qualifier_result,
38
+ ?"sexual-nudity" => qualifier_result,
39
+ ?"sexual-activity" => qualifier_result,
40
+ ?"sexual-explicit-language" => qualifier_result,
41
+ ?"sexual-assault-media" => qualifier_result,
42
+ ?"sexual-non-consensual" => qualifier_result,
43
+ ?"sexual-intimate-image-abuse" => qualifier_result,
44
+ ?"sexual-extreme" => qualifier_result,
45
+ ?"sexual-minors" => qualifier_result,
46
+ ?"sexual-solicitation" => qualifier_result,
47
+ ?"sexual-paid" => qualifier_result,
48
+ ?"sexual-adult-promotion" => qualifier_result,
49
+ ?"sexual-revealing-clothing" => qualifier_result,
50
+ ?"sexual-suggestive" => qualifier_result,
51
+ ?"sexual-non-erotic-nudity" => qualifier_result,
52
+ ?"sexual-text" => qualifier_result,
53
+ ?"sexual-historical" => qualifier_result,
54
+ ?"sexual-documentary" => qualifier_result,
55
+ ?"sexual-educational" => qualifier_result,
56
+ ?"sexual-discussion" => qualifier_result,
57
+ ?"sexual-fictional" => qualifier_result,
58
+ ?"sexual-support-prevention" => qualifier_result,
59
+ ?"violence-attack" => qualifier_result,
60
+ ?"violence-threat" => qualifier_result,
61
+ ?"violence-preparation" => qualifier_result,
62
+ ?"violence-encouragement" => qualifier_result,
63
+ ?"violence-wish" => qualifier_result,
64
+ ?"violence-coded-incitement" => qualifier_result,
65
+ ?"violence-extremism" => qualifier_result,
66
+ ?"violence-injury" => qualifier_result,
67
+ ?"violence-violent-death" => qualifier_result,
68
+ ?"violence-natural-death" => qualifier_result,
69
+ ?"violence-graphic" => qualifier_result,
70
+ ?"violence-decapitation-act" => qualifier_result,
71
+ ?"violence-gore" => qualifier_result,
72
+ ?"violence-weapon" => qualifier_result,
73
+ ?"violence-sport" => qualifier_result,
74
+ ?"violence-text" => qualifier_result,
75
+ ?"violence-historical" => qualifier_result,
76
+ ?"violence-documentary" => qualifier_result,
77
+ ?"violence-educational" => qualifier_result,
78
+ ?"violence-discussion" => qualifier_result,
79
+ ?"violence-fictional" => qualifier_result,
80
+ ?"violence-fantasy" => qualifier_result,
81
+ ?"violence-support-prevention" => qualifier_result,
82
+ ?"self-harm-thoughts" => qualifier_result,
83
+ ?"self-harm-preparation" => qualifier_result,
84
+ ?"self-harm-act" => qualifier_result,
85
+ ?"self-harm-methods" => qualifier_result,
86
+ ?"self-harm-encouragement" => qualifier_result,
87
+ ?"self-harm-historical" => qualifier_result,
88
+ ?"self-harm-documentary" => qualifier_result,
89
+ ?"self-harm-educational" => qualifier_result,
90
+ ?"self-harm-fictional" => qualifier_result,
91
+ ?"self-harm-support-prevention" => qualifier_result,
92
+ ?"harassment-abuse" => qualifier_result,
93
+ ?"harassment-mild" => qualifier_result,
94
+ ?"harassment-bullying" => qualifier_result,
95
+ ?"harassment-public-target" => qualifier_result,
96
+ ?"harassment-threat" => qualifier_result,
97
+ ?"harassment-sexual" => qualifier_result,
98
+ ?"harassment-encouragement" => qualifier_result,
99
+ ?"harassment-historical" => qualifier_result,
100
+ ?"harassment-documentary" => qualifier_result,
101
+ ?"harassment-educational" => qualifier_result,
102
+ ?"harassment-fictional" => qualifier_result,
103
+ ?"harassment-support-prevention" => qualifier_result,
104
+ ?"hate-abuse" => qualifier_result,
105
+ ?"hate-slurs" => qualifier_result,
106
+ ?"hate-dehumanization" => qualifier_result,
107
+ ?"hate-inferiority" => qualifier_result,
108
+ ?"hate-exclusion" => qualifier_result,
109
+ ?"hate-symbol" => qualifier_result,
110
+ ?"hate-hostility" => qualifier_result,
111
+ ?"hate-threat" => qualifier_result,
112
+ ?"hate-personal" => qualifier_result,
113
+ ?"hate-historical" => qualifier_result,
114
+ ?"hate-documentary" => qualifier_result,
115
+ ?"hate-educational" => qualifier_result,
116
+ ?"hate-fictional" => qualifier_result,
117
+ ?"hate-counterspeech" => qualifier_result,
118
+ ?"hate-support-prevention" => qualifier_result,
119
+ ?"criminal-activity-demonstration" => qualifier_result,
120
+ ?"criminal-activity-preparation" => qualifier_result,
121
+ ?"criminal-activity-request" => qualifier_result,
122
+ ?"criminal-activity-instructions" => qualifier_result,
123
+ ?"criminal-activity-promotion" => qualifier_result,
124
+ ?"criminal-activity-coded-incitement" => qualifier_result,
125
+ ?"criminal-activity-substances" => qualifier_result,
126
+ ?"criminal-activity-grooming" => qualifier_result,
127
+ ?"criminal-activity-csam" => qualifier_result,
128
+ ?"criminal-activity-alcohol" => qualifier_result,
129
+ ?"criminal-activity-tobacco" => qualifier_result,
130
+ ?"criminal-activity-gambling" => qualifier_result,
131
+ ?"criminal-activity-fraud" => qualifier_result,
132
+ ?"criminal-activity-sexual-solicitation" => qualifier_result,
133
+ ?"criminal-activity-graffiti" => qualifier_result,
134
+ ?"criminal-activity-historical" => qualifier_result,
135
+ ?"criminal-activity-documentary" => qualifier_result,
136
+ ?"criminal-activity-educational" => qualifier_result,
137
+ ?"criminal-activity-discussion" => qualifier_result,
138
+ ?"criminal-activity-fictional" => qualifier_result,
139
+ ?"criminal-activity-support-prevention" => qualifier_result
140
+ }
141
+ end